Skip to content

Commit 30afb80

Browse files
committed
yikes
1 parent 51efd8f commit 30afb80

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+592
-381
lines changed

compiler/rustc_infer/src/infer/canonical/query_response.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ use rustc_index::{Idx, IndexVec};
1515
use rustc_middle::arena::ArenaAllocatable;
1616
use rustc_middle::mir::ConstraintCategory;
1717
use rustc_middle::ty::fold::TypeFoldable;
18+
use rustc_middle::ty::traverse::AlwaysTraversable;
1819
use rustc_middle::ty::{self, BoundVar, GenericArg, GenericArgKind, Ty, TyCtxt};
1920
use rustc_middle::{bug, span_bug};
21+
use rustc_type_ir::traverse::OptTryFoldWith;
2022
use tracing::{debug, instrument};
2123

2224
use crate::infer::canonical::instantiate::{CanonicalExt, instantiate_value};
@@ -60,7 +62,7 @@ impl<'tcx> InferCtxt<'tcx> {
6062
fulfill_cx: &mut dyn TraitEngine<'tcx, ScrubbedTraitError<'tcx>>,
6163
) -> Result<CanonicalQueryResponse<'tcx, T>, NoSolution>
6264
where
63-
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
65+
T: OptTryFoldWith<TyCtxt<'tcx>>,
6466
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
6567
{
6668
let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
@@ -107,7 +109,7 @@ impl<'tcx> InferCtxt<'tcx> {
107109
fulfill_cx: &mut dyn TraitEngine<'tcx, ScrubbedTraitError<'tcx>>,
108110
) -> Result<QueryResponse<'tcx, T>, NoSolution>
109111
where
110-
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
112+
T: OptTryFoldWith<TyCtxt<'tcx>>,
111113
{
112114
let tcx = self.tcx;
113115

@@ -243,7 +245,7 @@ impl<'tcx> InferCtxt<'tcx> {
243245
output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
244246
) -> InferResult<'tcx, R>
245247
where
246-
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
248+
R: OptTryFoldWith<TyCtxt<'tcx>>,
247249
{
248250
let InferOk { value: result_args, mut obligations } = self
249251
.query_response_instantiation_guess(
@@ -326,8 +328,11 @@ impl<'tcx> InferCtxt<'tcx> {
326328
.map(|p_c| instantiate_value(self.tcx, &result_args, p_c.clone())),
327329
);
328330

329-
let user_result: R =
330-
query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone());
331+
let user_result: R = query_response
332+
.instantiate_projected(self.tcx, &result_args, |q_r| {
333+
AlwaysTraversable(q_r.value.clone())
334+
})
335+
.0;
331336

332337
Ok(InferOk { value: user_result, obligations })
333338
}
@@ -396,7 +401,7 @@ impl<'tcx> InferCtxt<'tcx> {
396401
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
397402
) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
398403
where
399-
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
404+
R: OptTryFoldWith<TyCtxt<'tcx>>,
400405
{
401406
// For each new universe created in the query result that did
402407
// not appear in the original query, create a local

compiler/rustc_infer/src/traits/structural_impls.rs

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_ast_ir::try_visit;
44
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable};
55
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor};
66
use rustc_middle::ty::{self, TyCtxt};
7+
use rustc_type_ir::traverse::{ImportantTypeTraversal, TypeTraversable};
78

89
use crate::traits;
910
use crate::traits::project::Normalized;
@@ -55,6 +56,11 @@ impl<'tcx, O: TypeFoldable<TyCtxt<'tcx>>> TypeFoldable<TyCtxt<'tcx>>
5556
}
5657
}
5758

59+
impl<'tcx, O: TypeVisitable<TyCtxt<'tcx>>> TypeTraversable<TyCtxt<'tcx>>
60+
for traits::Obligation<'tcx, O>
61+
{
62+
type Kind = ImportantTypeTraversal;
63+
}
5864
impl<'tcx, O: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>>
5965
for traits::Obligation<'tcx, O>
6066
{

compiler/rustc_macros/src/lib.rs

+4-21
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mod diagnostics;
1717
mod extension;
1818
mod hash_stable;
1919
mod lift;
20+
mod noop_type_traversable;
2021
mod query;
2122
mod serialize;
2223
mod symbols;
@@ -81,27 +82,9 @@ decl_derive!([TyDecodable] => serialize::type_decodable_derive);
8182
decl_derive!([TyEncodable] => serialize::type_encodable_derive);
8283
decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive);
8384
decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive);
84-
decl_derive!(
85-
[TypeFoldable, attributes(type_foldable)] =>
86-
/// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported).
87-
///
88-
/// The fold will produce a value of the same struct or enum variant as the input, with
89-
/// each field respectively folded using the `TypeFoldable` implementation for its type.
90-
/// However, if a field of a struct or an enum variant is annotated with
91-
/// `#[type_foldable(identity)]` then that field will retain its incumbent value (and its
92-
/// type is not required to implement `TypeFoldable`).
93-
type_foldable::type_foldable_derive
94-
);
95-
decl_derive!(
96-
[TypeVisitable, attributes(type_visitable)] =>
97-
/// Derives `TypeVisitable` for the annotated `struct` or `enum` (`union` is not supported).
98-
///
99-
/// Each field of the struct or enum variant will be visited in definition order, using the
100-
/// `TypeVisitable` implementation for its type. However, if a field of a struct or an enum
101-
/// variant is annotated with `#[type_visitable(ignore)]` then that field will not be
102-
/// visited (and its type is not required to implement `TypeVisitable`).
103-
type_visitable::type_visitable_derive
104-
);
85+
decl_derive!([NoopTypeTraversable] => noop_type_traversable::noop_type_traversable_derive);
86+
decl_derive!([TypeVisitable] => type_visitable::type_visitable_derive);
87+
decl_derive!([TypeFoldable] => type_foldable::type_foldable_derive);
10588
decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
10689
decl_derive!(
10790
[Diagnostic, attributes(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use quote::quote;
2+
use syn::parse_quote;
3+
4+
pub(super) fn noop_type_traversable_derive(
5+
mut s: synstructure::Structure<'_>,
6+
) -> proc_macro2::TokenStream {
7+
if let syn::Data::Union(_) = s.ast().data {
8+
panic!("cannot derive on union")
9+
}
10+
11+
s.underscore_const(true);
12+
13+
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
14+
s.add_impl_generic(parse_quote! { 'tcx });
15+
}
16+
17+
s.add_bounds(synstructure::AddBounds::None);
18+
let mut where_clauses = None;
19+
s.add_trait_bounds(
20+
&parse_quote!(
21+
::rustc_middle::ty::traverse::TypeTraversable<
22+
::rustc_middle::ty::TyCtxt<'tcx>,
23+
Kind = ::rustc_middle::ty::traverse::NoopTypeTraversal,
24+
>
25+
),
26+
&mut where_clauses,
27+
synstructure::AddBounds::Fields,
28+
);
29+
for pred in where_clauses.into_iter().flat_map(|c| c.predicates) {
30+
s.add_where_predicate(pred);
31+
}
32+
33+
s.bound_impl(
34+
quote!(::rustc_middle::ty::traverse::TypeTraversable<::rustc_middle::ty::TyCtxt<'tcx>>),
35+
quote! {
36+
type Kind = ::rustc_middle::ty::traverse::NoopTypeTraversal;
37+
},
38+
)
39+
}

compiler/rustc_macros/src/type_foldable.rs

+15-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use quote::{ToTokens, quote};
1+
use quote::quote;
22
use syn::parse_quote;
33

44
pub(super) fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
@@ -12,34 +12,25 @@ pub(super) fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_m
1212
s.add_impl_generic(parse_quote! { 'tcx });
1313
}
1414

15-
s.add_bounds(synstructure::AddBounds::Generics);
15+
s.add_bounds(synstructure::AddBounds::None);
16+
let mut where_clauses = None;
17+
s.add_trait_bounds(
18+
&parse_quote!(::rustc_type_ir::traverse::OptTryFoldWith<::rustc_middle::ty::TyCtxt<'tcx>>),
19+
&mut where_clauses,
20+
synstructure::AddBounds::Fields,
21+
);
22+
s.add_where_predicate(parse_quote! { Self: std::fmt::Debug + Clone });
23+
for pred in where_clauses.into_iter().flat_map(|c| c.predicates) {
24+
s.add_where_predicate(pred);
25+
}
26+
1627
s.bind_with(|_| synstructure::BindStyle::Move);
1728
let body_fold = s.each_variant(|vi| {
1829
let bindings = vi.bindings();
1930
vi.construct(|_, index| {
2031
let bind = &bindings[index];
21-
22-
let mut fixed = false;
23-
24-
// retain value of fields with #[type_foldable(identity)]
25-
bind.ast().attrs.iter().for_each(|x| {
26-
if !x.path().is_ident("type_foldable") {
27-
return;
28-
}
29-
let _ = x.parse_nested_meta(|nested| {
30-
if nested.path.is_ident("identity") {
31-
fixed = true;
32-
}
33-
Ok(())
34-
});
35-
});
36-
37-
if fixed {
38-
bind.to_token_stream()
39-
} else {
40-
quote! {
41-
::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)?
42-
}
32+
quote! {
33+
::rustc_middle::ty::traverse::OptTryFoldWith::mk_try_fold_with()(#bind, __folder)?
4334
}
4435
})
4536
});

compiler/rustc_macros/src/type_visitable.rs

+31-23
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,30 @@ pub(super) fn type_visitable_derive(
1010

1111
s.underscore_const(true);
1212

13-
// ignore fields with #[type_visitable(ignore)]
14-
s.filter(|bi| {
15-
let mut ignored = false;
16-
17-
bi.ast().attrs.iter().for_each(|attr| {
18-
if !attr.path().is_ident("type_visitable") {
19-
return;
20-
}
21-
let _ = attr.parse_nested_meta(|nested| {
22-
if nested.path.is_ident("ignore") {
23-
ignored = true;
24-
}
25-
Ok(())
26-
});
27-
});
28-
29-
!ignored
30-
});
31-
3213
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
3314
s.add_impl_generic(parse_quote! { 'tcx });
3415
}
3516

36-
s.add_bounds(synstructure::AddBounds::Generics);
17+
s.add_bounds(synstructure::AddBounds::None);
18+
let mut where_clauses = None;
19+
s.add_trait_bounds(
20+
&parse_quote!(
21+
::rustc_middle::ty::traverse::OptVisitWith::<::rustc_middle::ty::TyCtxt<'tcx>>
22+
),
23+
&mut where_clauses,
24+
synstructure::AddBounds::Fields,
25+
);
26+
s.add_where_predicate(parse_quote! { Self: std::fmt::Debug + Clone });
27+
for pred in where_clauses.into_iter().flat_map(|c| c.predicates) {
28+
s.add_where_predicate(pred);
29+
}
30+
31+
let impl_traversable_s = s.clone();
32+
3733
let body_visit = s.each(|bind| {
3834
quote! {
3935
match ::rustc_ast_ir::visit::VisitorResult::branch(
40-
::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor)
36+
::rustc_middle::ty::traverse::OptVisitWith::mk_visit_with()(#bind, __visitor)
4137
) {
4238
::core::ops::ControlFlow::Continue(()) => {},
4339
::core::ops::ControlFlow::Break(r) => {
@@ -48,7 +44,7 @@ pub(super) fn type_visitable_derive(
4844
});
4945
s.bind_with(|_| synstructure::BindStyle::Move);
5046

51-
s.bound_impl(
47+
let visitable_impl = s.bound_impl(
5248
quote!(::rustc_middle::ty::visit::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>),
5349
quote! {
5450
fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(
@@ -59,5 +55,17 @@ pub(super) fn type_visitable_derive(
5955
<__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
6056
}
6157
},
62-
)
58+
);
59+
60+
let traversable_impl = impl_traversable_s.bound_impl(
61+
quote!(::rustc_middle::ty::traverse::TypeTraversable<::rustc_middle::ty::TyCtxt<'tcx>>),
62+
quote! {
63+
type Kind = ::rustc_middle::ty::traverse::ImportantTypeTraversal;
64+
},
65+
);
66+
67+
quote! {
68+
#visitable_impl
69+
#traversable_impl
70+
}
6371
}

compiler/rustc_middle/src/hir/place.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use rustc_hir::HirId;
2-
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
2+
use rustc_macros::{
3+
HashStable, NoopTypeTraversable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
4+
};
35
use rustc_target::abi::{FieldIdx, VariantIdx};
46

57
use crate::ty;
68
use crate::ty::Ty;
79

810
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
9-
#[derive(TypeFoldable, TypeVisitable)]
11+
#[derive(NoopTypeTraversable)]
1012
pub enum PlaceBase {
1113
/// A temporary variable.
1214
Rvalue,
@@ -19,7 +21,7 @@ pub enum PlaceBase {
1921
}
2022

2123
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
22-
#[derive(TypeFoldable, TypeVisitable)]
24+
#[derive(NoopTypeTraversable)]
2325
pub enum ProjectionKind {
2426
/// A dereference of a pointer, reference or `Box<T>` of the given type.
2527
Deref,

compiler/rustc_middle/src/macros.rs

+2-26
Original file line numberDiff line numberDiff line change
@@ -73,32 +73,8 @@ macro_rules! TrivialLiftImpls {
7373
macro_rules! TrivialTypeTraversalImpls {
7474
($($ty:ty),+ $(,)?) => {
7575
$(
76-
impl<'tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<'tcx>> for $ty {
77-
fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<'tcx>>>(
78-
self,
79-
_: &mut F,
80-
) -> ::std::result::Result<Self, F::Error> {
81-
Ok(self)
82-
}
83-
84-
#[inline]
85-
fn fold_with<F: $crate::ty::fold::TypeFolder<$crate::ty::TyCtxt<'tcx>>>(
86-
self,
87-
_: &mut F,
88-
) -> Self {
89-
self
90-
}
91-
}
92-
93-
impl<'tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<'tcx>> for $ty {
94-
#[inline]
95-
fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<'tcx>>>(
96-
&self,
97-
_: &mut F)
98-
-> F::Result
99-
{
100-
<F::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
101-
}
76+
impl<'tcx> $crate::ty::traverse::TypeTraversable<$crate::ty::TyCtxt<'tcx>> for $ty {
77+
type Kind = $crate::ty::traverse::NoopTypeTraversal;
10278
}
10379
)+
10480
};

0 commit comments

Comments
 (0)