From 196fdf144f638e2ce901c5f44c9d404bba8d1ed3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 22 Oct 2024 23:07:51 +0200 Subject: [PATCH 1/7] do not relate `Abi` and `Safety` and update some macros while we're at it --- compiler/rustc_middle/src/ty/relate.rs | 22 ---- .../rustc_middle/src/ty/structural_impls.rs | 7 +- compiler/rustc_type_ir/src/error.rs | 4 +- compiler/rustc_type_ir/src/inherent.rs | 4 +- compiler/rustc_type_ir/src/relate.rs | 15 ++- compiler/rustc_type_ir/src/ty_kind.rs | 4 + compiler/rustc_type_ir/src/ty_kind/closure.rs | 4 + compiler/rustc_type_ir_macros/src/lib.rs | 114 +++++++++++------- 8 files changed, 99 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 4c7bcb1bf2e88..504a3c8a6d832 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -1,7 +1,5 @@ use std::iter; -use rustc_hir as hir; -use rustc_target::spec::abi; pub use rustc_type_ir::relate::*; use crate::ty::error::{ExpectedFound, TypeError}; @@ -121,26 +119,6 @@ impl<'tcx> Relate> for &'tcx ty::List Relate> for hir::Safety { - fn relate>>( - _relation: &mut R, - a: hir::Safety, - b: hir::Safety, - ) -> RelateResult<'tcx, hir::Safety> { - if a != b { Err(TypeError::SafetyMismatch(ExpectedFound::new(true, a, b))) } else { Ok(a) } - } -} - -impl<'tcx> Relate> for abi::Abi { - fn relate>>( - _relation: &mut R, - a: abi::Abi, - b: abi::Abi, - ) -> RelateResult<'tcx, abi::Abi> { - if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(ExpectedFound::new(true, a, b))) } - } -} - impl<'tcx> Relate> for ty::GenericArgsRef<'tcx> { fn relate>>( relation: &mut R, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index cd9ff9b60d859..4872d8c89eb84 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -264,8 +264,6 @@ TrivialTypeTraversalImpls! { // interners). TrivialTypeTraversalAndLiftImpls! { ::rustc_hir::def_id::DefId, - ::rustc_hir::Safety, - ::rustc_target::spec::abi::Abi, crate::ty::ClosureKind, crate::ty::ParamConst, crate::ty::ParamTy, @@ -276,6 +274,11 @@ TrivialTypeTraversalAndLiftImpls! { rustc_target::abi::Size, } +TrivialLiftImpls! { + ::rustc_hir::Safety, + ::rustc_target::spec::abi::Abi, +} + /////////////////////////////////////////////////////////////////////////// // Lift implementations diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index 8a6d37b7d23f6..7250194572109 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -29,8 +29,8 @@ pub enum TypeError { Mismatch, ConstnessMismatch(ExpectedFound), PolarityMismatch(ExpectedFound), - SafetyMismatch(ExpectedFound), - AbiMismatch(ExpectedFound), + SafetyMismatch(#[type_visitable(ignore)] ExpectedFound), + AbiMismatch(#[type_visitable(ignore)] ExpectedFound), Mutability, ArgumentMutability(usize), TupleSize(ExpectedFound), diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index f7875bb515270..02ec29a7f3d52 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -208,14 +208,14 @@ pub trait Tys>: fn output(self) -> I::Ty; } -pub trait Abi>: Copy + Debug + Hash + Eq + Relate { +pub trait Abi>: Copy + Debug + Hash + Eq { fn rust() -> Self; /// Whether this ABI is `extern "Rust"`. fn is_rust(self) -> bool; } -pub trait Safety>: Copy + Debug + Hash + Eq + Relate { +pub trait Safety>: Copy + Debug + Hash + Eq { fn safe() -> Self; fn is_safe(self) -> bool; diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index a0b93064694e3..ccb8e9fcf7ce3 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -174,12 +174,17 @@ impl Relate for ty::FnSig { ExpectedFound::new(true, a, b) })); } - let safety = relation.relate(a.safety, b.safety)?; - let abi = relation.relate(a.abi, b.abi)?; + + if a.safety != b.safety { + return Err(TypeError::SafetyMismatch(ExpectedFound::new(true, a.safety, b.safety))); + } + + if a.abi != b.abi { + return Err(TypeError::AbiMismatch(ExpectedFound::new(true, a.abi, b.abi))); + }; let a_inputs = a.inputs(); let b_inputs = b.inputs(); - if a_inputs.len() != b_inputs.len() { return Err(TypeError::ArgCount); } @@ -212,8 +217,8 @@ impl Relate for ty::FnSig { Ok(ty::FnSig { inputs_and_output: cx.mk_type_list_from_iter(inputs_and_output)?, c_variadic: a.c_variadic, - safety, - abi, + safety: a.safety, + abi: a.abi, }) } } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index b7f6ef4ffbb9a..499e6d3dd37d1 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -861,7 +861,11 @@ pub struct TypeAndMut { pub struct FnSig { pub inputs_and_output: I::Tys, pub c_variadic: bool, + #[type_visitable(ignore)] + #[type_foldable(identity)] pub safety: I::Safety, + #[type_visitable(ignore)] + #[type_foldable(identity)] pub abi: I::Abi, } diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 09a43b1795516..10b164eae027b 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -372,8 +372,12 @@ pub struct CoroutineClosureSignature { /// Always false pub c_variadic: bool, /// Always `Normal` (safe) + #[type_visitable(ignore)] + #[type_foldable(identity)] pub safety: I::Safety, /// Always `RustCall` + #[type_visitable(ignore)] + #[type_foldable(identity)] pub abi: I::Abi, } diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index 1a0a2479f6f07..aaf69e2648d5c 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -1,18 +1,73 @@ -use quote::quote; -use syn::parse_quote; +use quote::{ToTokens, quote}; use syn::visit_mut::VisitMut; +use syn::{Attribute, parse_quote}; use synstructure::decl_derive; decl_derive!( - [TypeFoldable_Generic] => type_foldable_derive + [TypeVisitable_Generic, attributes(type_visitable)] => type_visitable_derive ); decl_derive!( - [TypeVisitable_Generic] => type_visitable_derive + [TypeFoldable_Generic, attributes(type_foldable)] => type_foldable_derive ); decl_derive!( [Lift_Generic] => lift_derive ); +fn has_ignore_attr(attrs: &[Attribute], name: &'static str, meta: &'static str) -> bool { + let mut ignored = false; + attrs.iter().for_each(|attr| { + if !attr.path().is_ident(name) { + return; + } + let _ = attr.parse_nested_meta(|nested| { + if nested.path.is_ident(meta) { + ignored = true; + } + Ok(()) + }); + }); + + ignored +} + +fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { + s.add_impl_generic(parse_quote! { I }); + } + + s.filter(|bi| !has_ignore_attr(&bi.ast().attrs, "type_visitable", "ignore")); + + s.add_where_predicate(parse_quote! { I: Interner }); + s.add_bounds(synstructure::AddBounds::Fields); + let body_visit = s.each(|bind| { + quote! { + match ::rustc_ast_ir::visit::VisitorResult::branch( + ::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor) + ) { + ::core::ops::ControlFlow::Continue(()) => {}, + ::core::ops::ControlFlow::Break(r) => { + return ::rustc_ast_ir::visit::VisitorResult::from_residual(r); + }, + } + } + }); + s.bind_with(|_| synstructure::BindStyle::Move); + + s.bound_impl(quote!(::rustc_type_ir::visit::TypeVisitable), quote! { + fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor>( + &self, + __visitor: &mut __V + ) -> __V::Result { + match *self { #body_visit } + <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() + } + }) +} + fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { if let syn::Data::Union(_) = s.ast().data { panic!("cannot derive on union") @@ -29,12 +84,23 @@ fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke let bindings = vi.bindings(); vi.construct(|_, index| { let bind = &bindings[index]; - quote! { - ::rustc_type_ir::fold::TypeFoldable::try_fold_with(#bind, __folder)? + + // retain value of fields with #[type_foldable(identity)] + if has_ignore_attr(&bind.ast().attrs, "type_foldable", "identity") { + bind.to_token_stream() + } else { + quote! { + ::rustc_type_ir::fold::TypeFoldable::try_fold_with(#bind, __folder)? + } } }) }); + // We filter fields which get ignored and don't require them to implement + // `TypeFoldable`. We do so after generating `body_fold` as we still need + // to generate code for them. + s.filter(|bi| !has_ignore_attr(&bi.ast().attrs, "type_foldable", "identity")); + s.add_bounds(synstructure::AddBounds::Fields); s.bound_impl(quote!(::rustc_type_ir::fold::TypeFoldable), quote! { fn try_fold_with<__F: ::rustc_type_ir::fold::FallibleTypeFolder>( self, @@ -113,39 +179,3 @@ fn lift(mut ty: syn::Type) -> syn::Type { ty } - -fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { - if let syn::Data::Union(_) = s.ast().data { - panic!("cannot derive on union") - } - - if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { - s.add_impl_generic(parse_quote! { I }); - } - - s.add_where_predicate(parse_quote! { I: Interner }); - s.add_bounds(synstructure::AddBounds::Fields); - let body_visit = s.each(|bind| { - quote! { - match ::rustc_ast_ir::visit::VisitorResult::branch( - ::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor) - ) { - ::core::ops::ControlFlow::Continue(()) => {}, - ::core::ops::ControlFlow::Break(r) => { - return ::rustc_ast_ir::visit::VisitorResult::from_residual(r); - }, - } - } - }); - s.bind_with(|_| synstructure::BindStyle::Move); - - s.bound_impl(quote!(::rustc_type_ir::visit::TypeVisitable), quote! { - fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor>( - &self, - __visitor: &mut __V - ) -> __V::Result { - match *self { #body_visit } - <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() - } - }) -} From 00266eeaa5957f0dde0b17f2823fd4b4ea6996c2 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 23 Oct 2024 00:52:37 +0200 Subject: [PATCH 2/7] remove `PredicatePolarity` and `BoundConstness` relate impls Also removes `TypeError::ConstnessMismatch`. It is unused. --- compiler/rustc_middle/src/ty/error.rs | 3 --- compiler/rustc_type_ir/src/error.rs | 9 +++---- compiler/rustc_type_ir/src/relate.rs | 39 +++++---------------------- 3 files changed, 11 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index b02eff3bfd6a3..c49824bb418cd 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -35,9 +35,6 @@ impl<'tcx> TypeError<'tcx> { TypeError::CyclicTy(_) => "cyclic type of infinite size".into(), TypeError::CyclicConst(_) => "encountered a self-referencing constant".into(), TypeError::Mismatch => "types differ".into(), - TypeError::ConstnessMismatch(values) => { - format!("expected {} bound, found {} bound", values.expected, values.found).into() - } TypeError::PolarityMismatch(values) => { format!("expected {} polarity, found {} polarity", values.expected, values.found) .into() diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index 7250194572109..cdff77f742d0a 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -27,8 +27,7 @@ impl ExpectedFound { #[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum TypeError { Mismatch, - ConstnessMismatch(ExpectedFound), - PolarityMismatch(ExpectedFound), + PolarityMismatch(#[type_visitable(ignore)] ExpectedFound), SafetyMismatch(#[type_visitable(ignore)] ExpectedFound), AbiMismatch(#[type_visitable(ignore)] ExpectedFound), Mutability, @@ -73,9 +72,9 @@ impl TypeError { pub fn must_include_note(self) -> bool { use self::TypeError::*; match self { - CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | ConstnessMismatch(_) - | PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_) - | ArgumentSorts(..) | Sorts(_) | VariadicMismatch(_) | TargetFeatureCast(_) => false, + CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | PolarityMismatch(_) | Mismatch + | AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_) + | VariadicMismatch(_) | TargetFeatureCast(_) => false, Mutability | ArgumentMutability(_) diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index ccb8e9fcf7ce3..ad17911830b3d 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -223,20 +223,6 @@ impl Relate for ty::FnSig { } } -impl Relate for ty::BoundConstness { - fn relate>( - _relation: &mut R, - a: ty::BoundConstness, - b: ty::BoundConstness, - ) -> RelateResult { - if a != b { - Err(TypeError::ConstnessMismatch(ExpectedFound::new(true, a, b))) - } else { - Ok(a) - } - } -} - impl Relate for ty::AliasTy { fn relate>( relation: &mut R, @@ -664,29 +650,18 @@ impl> Relate for ty::Binder { } } -impl Relate for ty::PredicatePolarity { - fn relate>( - _relation: &mut R, - a: ty::PredicatePolarity, - b: ty::PredicatePolarity, - ) -> RelateResult { - if a != b { - Err(TypeError::PolarityMismatch(ExpectedFound::new(true, a, b))) - } else { - Ok(a) - } - } -} - impl Relate for ty::TraitPredicate { fn relate>( relation: &mut R, a: ty::TraitPredicate, b: ty::TraitPredicate, ) -> RelateResult> { - Ok(ty::TraitPredicate { - trait_ref: relation.relate(a.trait_ref, b.trait_ref)?, - polarity: relation.relate(a.polarity, b.polarity)?, - }) + let trait_ref = relation.relate(a.trait_ref, b.trait_ref)?; + if a.polarity != b.polarity { + return Err(TypeError::PolarityMismatch(ExpectedFound::new( + true, a.polarity, b.polarity, + ))); + } + Ok(ty::TraitPredicate { trait_ref, polarity: a.polarity }) } } From e2dfdfd373e6dcaeb89feff90d304289bc2e2b34 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 22 Oct 2024 20:31:45 +0200 Subject: [PATCH 3/7] move type traversals into a shared module --- compiler/rustc_type_ir/src/lib.rs | 4 ++-- compiler/rustc_type_ir/src/{ => traverse}/fold.rs | 0 compiler/rustc_type_ir/src/traverse/mod.rs | 3 +++ compiler/rustc_type_ir/src/{ => traverse}/visit.rs | 0 4 files changed, 5 insertions(+), 2 deletions(-) rename compiler/rustc_type_ir/src/{ => traverse}/fold.rs (100%) create mode 100644 compiler/rustc_type_ir/src/traverse/mod.rs rename compiler/rustc_type_ir/src/{ => traverse}/visit.rs (100%) diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 9e6d1f424ba49..f589007670595 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -19,14 +19,13 @@ use rustc_macros::{Decodable, Encodable, HashStable_NoContext}; // These modules are `pub` since they are not glob-imported. #[macro_use] -pub mod visit; +pub mod traverse; #[cfg(feature = "nightly")] pub mod codec; pub mod data_structures; pub mod elaborate; pub mod error; pub mod fast_reject; -pub mod fold; #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_inherent")] pub mod inherent; pub mod ir_print; @@ -79,6 +78,7 @@ pub use region_kind::*; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; +pub use traverse::{visit, fold}; rustc_index::newtype_index! { /// A [De Bruijn index][dbi] is a standard means of representing diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/traverse/fold.rs similarity index 100% rename from compiler/rustc_type_ir/src/fold.rs rename to compiler/rustc_type_ir/src/traverse/fold.rs diff --git a/compiler/rustc_type_ir/src/traverse/mod.rs b/compiler/rustc_type_ir/src/traverse/mod.rs new file mode 100644 index 0000000000000..7f4a69c162d7d --- /dev/null +++ b/compiler/rustc_type_ir/src/traverse/mod.rs @@ -0,0 +1,3 @@ +#[macro_use] +pub mod visit; +pub mod fold; \ No newline at end of file diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/traverse/visit.rs similarity index 100% rename from compiler/rustc_type_ir/src/visit.rs rename to compiler/rustc_type_ir/src/traverse/visit.rs From ff3a616ae1553b8a9b99d1c59afcaba4653ee3c2 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 23 Oct 2024 00:05:47 +0200 Subject: [PATCH 4/7] yikes --- compiler/rustc_macros/src/lib.rs | 25 +--- .../rustc_macros/src/noop_type_traversable.rs | 39 +++++ compiler/rustc_macros/src/type_foldable.rs | 38 ++--- compiler/rustc_macros/src/type_visitable.rs | 35 ++--- compiler/rustc_middle/src/macros.rs | 28 +--- compiler/rustc_middle/src/mir/query.rs | 2 - .../rustc_middle/src/mir/type_foldable.rs | 32 +--- compiler/rustc_middle/src/thir.rs | 3 - .../rustc_middle/src/ty/consts/valtree.rs | 4 +- compiler/rustc_middle/src/ty/mod.rs | 5 +- .../rustc_middle/src/ty/structural_impls.rs | 15 +- compiler/rustc_type_ir/src/error.rs | 6 +- compiler/rustc_type_ir/src/inherent.rs | 17 ++- compiler/rustc_type_ir/src/interner.rs | 8 +- compiler/rustc_type_ir/src/lib.rs | 2 +- compiler/rustc_type_ir/src/solve/mod.rs | 6 +- compiler/rustc_type_ir/src/traverse/fold.rs | 34 +++-- compiler/rustc_type_ir/src/traverse/mod.rs | 141 +++++++++++++++++- compiler/rustc_type_ir/src/traverse/visit.rs | 66 ++++---- compiler/rustc_type_ir/src/ty_kind.rs | 4 - compiler/rustc_type_ir/src/ty_kind/closure.rs | 4 - compiler/rustc_type_ir_macros/src/lib.rs | 98 ++++++------ 22 files changed, 366 insertions(+), 246 deletions(-) create mode 100644 compiler/rustc_macros/src/noop_type_traversable.rs diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index f46c795b9565c..b3e491c651a93 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -17,6 +17,7 @@ mod diagnostics; mod extension; mod hash_stable; mod lift; +mod noop_type_traversable; mod query; mod serialize; mod symbols; @@ -81,27 +82,9 @@ decl_derive!([TyDecodable] => serialize::type_decodable_derive); decl_derive!([TyEncodable] => serialize::type_encodable_derive); decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive); decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive); -decl_derive!( - [TypeFoldable, attributes(type_foldable)] => - /// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported). - /// - /// The fold will produce a value of the same struct or enum variant as the input, with - /// each field respectively folded using the `TypeFoldable` implementation for its type. - /// However, if a field of a struct or an enum variant is annotated with - /// `#[type_foldable(identity)]` then that field will retain its incumbent value (and its - /// type is not required to implement `TypeFoldable`). - type_foldable::type_foldable_derive -); -decl_derive!( - [TypeVisitable, attributes(type_visitable)] => - /// Derives `TypeVisitable` for the annotated `struct` or `enum` (`union` is not supported). - /// - /// Each field of the struct or enum variant will be visited in definition order, using the - /// `TypeVisitable` implementation for its type. However, if a field of a struct or an enum - /// variant is annotated with `#[type_visitable(ignore)]` then that field will not be - /// visited (and its type is not required to implement `TypeVisitable`). - type_visitable::type_visitable_derive -); +decl_derive!([NoopTypeTraversable] => noop_type_traversable::noop_type_traversable_derive); +decl_derive!([TypeVisitable] => type_visitable::type_visitable_derive); +decl_derive!([TypeFoldable] => type_foldable::type_foldable_derive); decl_derive!([Lift, attributes(lift)] => lift::lift_derive); decl_derive!( [Diagnostic, attributes( diff --git a/compiler/rustc_macros/src/noop_type_traversable.rs b/compiler/rustc_macros/src/noop_type_traversable.rs new file mode 100644 index 0000000000000..eeb4bd2bc5863 --- /dev/null +++ b/compiler/rustc_macros/src/noop_type_traversable.rs @@ -0,0 +1,39 @@ +use quote::quote; +use syn::parse_quote; + +pub(super) fn noop_type_traversable_derive( + mut s: synstructure::Structure<'_>, +) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + s.underscore_const(true); + + if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { + s.add_impl_generic(parse_quote! { 'tcx }); + } + + s.add_bounds(synstructure::AddBounds::None); + let mut where_clauses = None; + s.add_trait_bounds( + &parse_quote!( + ::rustc_middle::ty::traverse::TypeTraversable< + ::rustc_middle::ty::TyCtxt<'tcx>, + Kind = ::rustc_middle::ty::traverse::NoopTypeTraversal, + > + ), + &mut where_clauses, + synstructure::AddBounds::Fields, + ); + for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { + s.add_where_predicate(pred); + } + + s.bound_impl( + quote!(::rustc_middle::ty::traverse::TypeTraversable<::rustc_middle::ty::TyCtxt<'tcx>>), + quote! { + type Kind = ::rustc_middle::ty::traverse::NoopTypeTraversal; + }, + ) +} diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index bc3b82c2893fa..e24dbf09d5872 100644 --- a/compiler/rustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs @@ -1,4 +1,4 @@ -use quote::{ToTokens, quote}; +use quote::quote; use syn::parse_quote; pub(super) fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { @@ -12,34 +12,24 @@ pub(super) fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_m s.add_impl_generic(parse_quote! { 'tcx }); } - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::None); + let mut where_clauses = None; + s.add_trait_bounds( + &parse_quote!(::rustc_type_ir::traverse::OptTryFoldWith<::rustc_middle::ty::TyCtxt<'tcx>>), + &mut where_clauses, + synstructure::AddBounds::Fields, + ); + for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { + s.add_where_predicate(pred); + } + s.bind_with(|_| synstructure::BindStyle::Move); let body_fold = s.each_variant(|vi| { let bindings = vi.bindings(); vi.construct(|_, index| { let bind = &bindings[index]; - - let mut fixed = false; - - // retain value of fields with #[type_foldable(identity)] - bind.ast().attrs.iter().for_each(|x| { - if !x.path().is_ident("type_foldable") { - return; - } - let _ = x.parse_nested_meta(|nested| { - if nested.path.is_ident("identity") { - fixed = true; - } - Ok(()) - }); - }); - - if fixed { - bind.to_token_stream() - } else { - quote! { - ::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)? - } + quote! { + ::rustc_middle::ty::traverse::OptTryFoldWith::mk_try_fold_with()(#bind, __folder)? } }) }); diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs index 527ca26c0eb10..750afbb2b6375 100644 --- a/compiler/rustc_macros/src/type_visitable.rs +++ b/compiler/rustc_macros/src/type_visitable.rs @@ -10,34 +10,27 @@ pub(super) fn type_visitable_derive( s.underscore_const(true); - // ignore fields with #[type_visitable(ignore)] - s.filter(|bi| { - let mut ignored = false; - - bi.ast().attrs.iter().for_each(|attr| { - if !attr.path().is_ident("type_visitable") { - return; - } - let _ = attr.parse_nested_meta(|nested| { - if nested.path.is_ident("ignore") { - ignored = true; - } - Ok(()) - }); - }); - - !ignored - }); - if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { s.add_impl_generic(parse_quote! { 'tcx }); } - s.add_bounds(synstructure::AddBounds::Generics); + s.add_bounds(synstructure::AddBounds::None); + let mut where_clauses = None; + s.add_trait_bounds( + &parse_quote!( + ::rustc_middle::ty::traverse::OptVisitWith::<::rustc_middle::ty::TyCtxt<'tcx>> + ), + &mut where_clauses, + synstructure::AddBounds::Fields, + ); + for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { + s.add_where_predicate(pred); + } + let body_visit = s.each(|bind| { quote! { match ::rustc_ast_ir::visit::VisitorResult::branch( - ::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor) + ::rustc_middle::ty::traverse::OptVisitWith::mk_visit_with()(#bind, __visitor) ) { ::core::ops::ControlFlow::Continue(()) => {}, ::core::ops::ControlFlow::Break(r) => { diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 39816c17b985f..8e3427e941dd1 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -73,32 +73,8 @@ macro_rules! TrivialLiftImpls { macro_rules! TrivialTypeTraversalImpls { ($($ty:ty),+ $(,)?) => { $( - impl<'tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<'tcx>> for $ty { - fn try_fold_with>>( - self, - _: &mut F, - ) -> ::std::result::Result { - Ok(self) - } - - #[inline] - fn fold_with>>( - self, - _: &mut F, - ) -> Self { - self - } - } - - impl<'tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<'tcx>> for $ty { - #[inline] - fn visit_with>>( - &self, - _: &mut F) - -> F::Result - { - ::output() - } + impl<'tcx> $crate::ty::traverse::TypeTraversable<$crate::ty::TyCtxt<'tcx>> for $ty { + type Kind = $crate::ty::traverse::NoopTypeTraversal; } )+ }; diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 70331214ac5a8..088c041c4b2be 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -57,8 +57,6 @@ pub struct CoroutineLayout<'tcx> { /// Which saved locals are storage-live at the same time. Locals that do not /// have conflicts with each other are allowed to overlap in the computed /// layout. - #[type_foldable(identity)] - #[type_visitable(ignore)] pub storage_conflicts: BitMatrix, } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index b798f0788007f..178b6767ce8ca 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -1,7 +1,5 @@ //! `TypeFoldable` implementations for MIR types - -use rustc_ast::InlineAsmTemplatePiece; -use rustc_hir::def_id::LocalDefId; +use rustc_index::bit_set::BitMatrix; use super::*; @@ -20,6 +18,7 @@ TrivialTypeTraversalImpls! { SwitchTargets, CoroutineKind, CoroutineSavedLocal, + BitMatrix, } TrivialTypeTraversalImpls! { @@ -27,33 +26,6 @@ TrivialTypeTraversalImpls! { NullOp<'tcx>, } -impl<'tcx> TypeFoldable> for &'tcx [InlineAsmTemplatePiece] { - fn try_fold_with>>( - self, - _folder: &mut F, - ) -> Result { - Ok(self) - } -} - -impl<'tcx> TypeFoldable> for &'tcx [Span] { - fn try_fold_with>>( - self, - _folder: &mut F, - ) -> Result { - Ok(self) - } -} - -impl<'tcx> TypeFoldable> for &'tcx ty::List { - fn try_fold_with>>( - self, - _folder: &mut F, - ) -> Result { - Ok(self) - } -} - impl<'tcx> TypeFoldable> for &'tcx ty::List> { fn try_fold_with>>( self, diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index fe865b8a51508..1202371eec96e 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -739,9 +739,7 @@ pub enum PatKind<'tcx> { /// `x`, `ref x`, `x @ P`, etc. Binding { name: Symbol, - #[type_visitable(ignore)] mode: BindingMode, - #[type_visitable(ignore)] var: LocalVarId, ty: Ty<'tcx>, subpattern: Option>>, @@ -844,7 +842,6 @@ pub struct PatRange<'tcx> { pub lo: PatRangeBoundary<'tcx>, /// Must not be `NegInfinity`. pub hi: PatRangeBoundary<'tcx>, - #[type_visitable(ignore)] pub end: RangeEnd, pub ty: Ty<'tcx>, } diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 9f9bf41c3355a..e3bad806d153f 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -1,11 +1,11 @@ -use rustc_macros::{HashStable, TyDecodable, TyEncodable}; +use rustc_macros::{HashStable, NoopTypeTraversable, TyDecodable, TyEncodable}; use super::ScalarInt; use crate::mir::interpret::Scalar; use crate::ty::{self, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq)] -#[derive(HashStable)] +#[derive(HashStable, NoopTypeTraversable)] /// This datastructure is used to represent the value of constants used in the type system. /// /// We explicitly choose a different datastructure from the way values are processed within diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ed24fcc7eb88a..2a0ae0f62439c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -55,6 +55,7 @@ pub use rustc_type_ir::ConstKind::{ Placeholder as PlaceholderCt, Unevaluated, Value, }; pub use rustc_type_ir::relate::VarianceDiagInfo; +use rustc_type_ir::traverse::TypeTraversable; pub use rustc_type_ir::*; use tracing::{debug, instrument}; pub use vtable::*; @@ -1031,7 +1032,7 @@ impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { ) -> Result { Ok(ParamEnv::new( self.caller_bounds().try_fold_with(folder)?, - self.reveal().try_fold_with(folder)?, + self.reveal().noop_try_fold_with(folder)?, )) } } @@ -1039,7 +1040,7 @@ impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { impl<'tcx> TypeVisitable> for ParamEnv<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { try_visit!(self.caller_bounds().visit_with(visitor)); - self.reveal().visit_with(visitor) + self.reveal().noop_visit_with(visitor) } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 4872d8c89eb84..c7f6a2cb881f5 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -11,6 +11,7 @@ use rustc_hir::def::Namespace; use rustc_span::source_map::Spanned; use rustc_target::abi::TyAndLayout; use rustc_type_ir::ConstKind; +use rustc_type_ir::traverse::TypeTraversable; use super::print::PrettyPrinter; use super::{GenericArg, GenericArgKind, Pattern, Region}; @@ -229,6 +230,7 @@ TrivialTypeTraversalImpls! { ::rustc_hir::def_id::LocalDefId, ::rustc_hir::ByRef, ::rustc_hir::HirId, + ::rustc_hir::RangeEnd, ::rustc_hir::MatchSource, ::rustc_target::asm::InlineAsmRegOrRegClass, crate::mir::coverage::BlockMarkerId, @@ -264,6 +266,8 @@ TrivialTypeTraversalImpls! { // interners). TrivialTypeTraversalAndLiftImpls! { ::rustc_hir::def_id::DefId, + ::rustc_hir::Safety, + ::rustc_target::spec::abi::Abi, crate::ty::ClosureKind, crate::ty::ParamConst, crate::ty::ParamTy, @@ -274,11 +278,6 @@ TrivialTypeTraversalAndLiftImpls! { rustc_target::abi::Size, } -TrivialLiftImpls! { - ::rustc_hir::Safety, - ::rustc_target::spec::abi::Abi, -} - /////////////////////////////////////////////////////////////////////////// // Lift implementations @@ -573,7 +572,7 @@ impl<'tcx> TypeSuperFoldable> for ty::Const<'tcx> { ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?), ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?), ConstKind::Value(t, v) => { - ConstKind::Value(t.try_fold_with(folder)?, v.try_fold_with(folder)?) + ConstKind::Value(t.try_fold_with(folder)?, v.noop_try_fold_with(folder)?) } ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?), ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?), @@ -644,7 +643,7 @@ impl<'tcx, T: TypeVisitable> + Debug + Clone> TypeVisitable>>(&self, visitor: &mut V) -> V::Result { try_visit!(self.node.visit_with(visitor)); - self.span.visit_with(visitor) + self.span.noop_visit_with(visitor) } } @@ -657,7 +656,7 @@ impl<'tcx, T: TypeFoldable> + Debug + Clone> TypeFoldable Result { Ok(Spanned { node: self.node.try_fold_with(folder)?, - span: self.span.try_fold_with(folder)?, + span: self.span.noop_try_fold_with(folder)?, }) } } diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index cdff77f742d0a..39672977c008f 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -27,9 +27,9 @@ impl ExpectedFound { #[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum TypeError { Mismatch, - PolarityMismatch(#[type_visitable(ignore)] ExpectedFound), - SafetyMismatch(#[type_visitable(ignore)] ExpectedFound), - AbiMismatch(#[type_visitable(ignore)] ExpectedFound), + PolarityMismatch(ExpectedFound), + SafetyMismatch(ExpectedFound), + AbiMismatch(ExpectedFound), Mutability, ArgumentMutability(usize), TupleSize(ExpectedFound), diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 02ec29a7f3d52..90f85e1f2f20c 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -12,6 +12,7 @@ use crate::elaborate::Elaboratable; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; use crate::solve::Reveal; +use crate::traverse::{NoopTypeTraversal, TypeTraversable}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{self as ty, CollectAndApply, Interner, UpcastFrom}; @@ -208,14 +209,18 @@ pub trait Tys>: fn output(self) -> I::Ty; } -pub trait Abi>: Copy + Debug + Hash + Eq { +pub trait Abi>: + Copy + Hash + Eq + TypeTraversable +{ fn rust() -> Self; /// Whether this ABI is `extern "Rust"`. fn is_rust(self) -> bool; } -pub trait Safety>: Copy + Debug + Hash + Eq { +pub trait Safety>: + Copy + Hash + Eq + TypeTraversable +{ fn safe() -> Self; fn is_safe(self) -> bool; @@ -545,7 +550,9 @@ pub trait Features: Copy { fn associated_const_equality(self) -> bool; } -pub trait DefId: Copy + Debug + Hash + Eq + TypeFoldable { +pub trait DefId: + Copy + Debug + Hash + Eq + TypeTraversable +{ fn is_local(self) -> bool; fn as_local(self) -> Option; @@ -565,7 +572,9 @@ pub trait BoundExistentialPredicates: ) -> impl IntoIterator>>; } -pub trait Span: Copy + Debug + Hash + Eq + TypeFoldable { +pub trait Span: + Copy + Debug + Hash + Eq + TypeTraversable +{ fn dummy() -> Self; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 4184e9e313ff7..6c43c237bf078 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -14,6 +14,7 @@ use crate::relate::Relate; use crate::solve::{ CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult, SolverMode, }; +use crate::traverse::{NoopTypeTraversal, TypeTraversable}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{self as ty, search_graph}; @@ -33,7 +34,12 @@ pub trait Interner: + IrPrint> { type DefId: DefId; - type LocalDefId: Copy + Debug + Hash + Eq + Into + TypeFoldable; + type LocalDefId: Copy + + Debug + + Hash + + Eq + + Into + + TypeTraversable; type Span: Span; type GenericArgs: GenericArgs; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index f589007670595..409f458cdeeba 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -75,10 +75,10 @@ pub use opaque_ty::*; pub use predicate::*; pub use predicate_kind::*; pub use region_kind::*; +pub use traverse::{fold, visit}; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; -pub use traverse::{visit, fold}; rustc_index::newtype_index! { /// A [De Bruijn index][dbi] is a standard means of representing diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index b3f8390bbf062..a8a4475a19e5c 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -6,13 +6,15 @@ use std::hash::Hash; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + Lift_Generic, NoopTypeTraversable_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; /// Depending on the stage of compilation, we want projection to be /// more or less conservative. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, NoopTypeTraversable_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub enum Reveal { /// At type-checking time, we refuse to project any associated diff --git a/compiler/rustc_type_ir/src/traverse/fold.rs b/compiler/rustc_type_ir/src/traverse/fold.rs index 8209d6f5fe3b1..7c50633ccab68 100644 --- a/compiler/rustc_type_ir/src/traverse/fold.rs +++ b/compiler/rustc_type_ir/src/traverse/fold.rs @@ -51,6 +51,7 @@ use rustc_index::{Idx, IndexVec}; use thin_vec::ThinVec; use tracing::instrument; +use super::OptTryFoldWith; use crate::data_structures::Lrc; use crate::inherent::*; use crate::visit::{TypeVisitable, TypeVisitableExt as _}; @@ -234,9 +235,12 @@ where /////////////////////////////////////////////////////////////////////////// // Traversal implementations. -impl, U: TypeFoldable> TypeFoldable for (T, U) { +impl, U: OptTryFoldWith> TypeFoldable for (T, U) { fn try_fold_with>(self, folder: &mut F) -> Result<(T, U), F::Error> { - Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?)) + Ok(( + OptTryFoldWith::mk_try_fold_with()(self.0, folder)?, + OptTryFoldWith::mk_try_fold_with()(self.1, folder)?, + )) } } @@ -248,17 +252,17 @@ impl, B: TypeFoldable, C: TypeFoldable> Ty folder: &mut F, ) -> Result<(A, B, C), F::Error> { Ok(( - self.0.try_fold_with(folder)?, - self.1.try_fold_with(folder)?, - self.2.try_fold_with(folder)?, + OptTryFoldWith::mk_try_fold_with()(self.0, folder)?, + OptTryFoldWith::mk_try_fold_with()(self.1, folder)?, + OptTryFoldWith::mk_try_fold_with()(self.2, folder)?, )) } } -impl> TypeFoldable for Option { +impl> TypeFoldable for Option { fn try_fold_with>(self, folder: &mut F) -> Result { Ok(match self { - Some(v) => Some(v.try_fold_with(folder)?), + Some(v) => Some(OptTryFoldWith::mk_try_fold_with()(v, folder)?), None => None, }) } @@ -310,32 +314,32 @@ impl> TypeFoldable for Lrc { } } -impl> TypeFoldable for Box { +impl> TypeFoldable for Box { fn try_fold_with>(mut self, folder: &mut F) -> Result { - *self = (*self).try_fold_with(folder)?; + *self = OptTryFoldWith::mk_try_fold_with()(*self, folder)?; Ok(self) } } -impl> TypeFoldable for Vec { +impl> TypeFoldable for Vec { fn try_fold_with>(self, folder: &mut F) -> Result { - self.into_iter().map(|t| t.try_fold_with(folder)).collect() + self.into_iter().map(|t| OptTryFoldWith::mk_try_fold_with()(t, folder)).collect() } } -impl> TypeFoldable for ThinVec { +impl> TypeFoldable for ThinVec { fn try_fold_with>(self, folder: &mut F) -> Result { - self.into_iter().map(|t| t.try_fold_with(folder)).collect() + self.into_iter().map(|t| OptTryFoldWith::mk_try_fold_with()(t, folder)).collect() } } -impl> TypeFoldable for Box<[T]> { +impl> TypeFoldable for Box<[T]> { fn try_fold_with>(self, folder: &mut F) -> Result { Vec::from(self).try_fold_with(folder).map(Vec::into_boxed_slice) } } -impl, Ix: Idx> TypeFoldable for IndexVec { +impl, Ix: Idx> TypeFoldable for IndexVec { fn try_fold_with>(self, folder: &mut F) -> Result { self.raw.try_fold_with(folder).map(IndexVec::from_raw) } diff --git a/compiler/rustc_type_ir/src/traverse/mod.rs b/compiler/rustc_type_ir/src/traverse/mod.rs index 7f4a69c162d7d..0cde01f61f286 100644 --- a/compiler/rustc_type_ir/src/traverse/mod.rs +++ b/compiler/rustc_type_ir/src/traverse/mod.rs @@ -1,3 +1,142 @@ +//! A visiting traversal mechanism for complex data structures that contain type +//! information. See the documentation of the [visit] and [fold] modules for more +//! details. + #[macro_use] pub mod visit; -pub mod fold; \ No newline at end of file +pub mod fold; + +use std::fmt; + +use fold::{FallibleTypeFolder, TypeFoldable}; +use rustc_ast_ir::visit::VisitorResult; +use visit::{TypeVisitable, TypeVisitor}; + +use crate::Interner; + +/// A trait which allows the compiler to reason about the disjointness +/// of `TypeVisitable` and `NoopTypeTraversable`. +/// +/// This trait has a blanket impls for everything that implements `TypeVisitable` +/// while requiring a manual impl for all types whose traversal is a noop. +pub trait TypeTraversable: fmt::Debug + Clone { + type Kind; + + #[inline(always)] + fn noop_visit>(&self, _: &mut V) -> V::Result + where + Self: TypeTraversable, + { + V::Result::output() + } + + #[inline(always)] + fn noop_try_fold_with>(self, _: &mut F) -> Result + where + Self: TypeTraversable, + { + Ok(self) + } +} +pub struct ImportantTypeTraversal; +pub struct NoopTypeTraversal; +#[inline(always)] +pub fn noop_visit() -> V::Result +where + I: Interner, + V: TypeVisitor, + T: TypeTraversable, +{ + V::Result::output() +} + +impl> TypeTraversable for T { + type Kind = ImportantTypeTraversal; +} + +pub trait OptVisitWith: TypeTraversable { + fn mk_visit_with>() -> fn(&Self, &mut V) -> V::Result; +} + +impl OptVisitWith for T +where + I: Interner, + T: TypeTraversable + Clone + OptVisitWithHelper, +{ + #[inline(always)] + fn mk_visit_with>() -> fn(&Self, &mut V) -> V::Result { + Self::mk_visit_with_helper() + } +} + +trait OptVisitWithHelper { + fn mk_visit_with_helper>() -> fn(&Self, &mut V) -> V::Result; +} + +impl OptVisitWithHelper for T +where + I: Interner, + T: TypeVisitable, +{ + #[inline(always)] + fn mk_visit_with_helper>() -> fn(&Self, &mut V) -> V::Result { + Self::visit_with + } +} + +/// While this is implemented for all `T`, it is only useable via `OptVisitWith` if +/// `T` implements `TypeTraversable`. +impl OptVisitWithHelper for T +where + I: Interner, +{ + #[inline(always)] + fn mk_visit_with_helper>() -> fn(&Self, &mut V) -> V::Result { + |_, _| V::Result::output() + } +} + +pub trait OptTryFoldWith: OptVisitWith + Sized { + fn mk_try_fold_with>() -> fn(Self, &mut F) -> Result; +} + +impl OptTryFoldWith for T +where + I: Interner, + T: OptVisitWith + OptTryFoldWithHelper, +{ + #[inline(always)] + fn mk_try_fold_with>() -> fn(Self, &mut F) -> Result { + Self::mk_try_fold_with_helper() + } +} + +pub trait OptTryFoldWithHelper: Sized { + fn mk_try_fold_with_helper>() + -> fn(Self, &mut F) -> Result; +} + +impl OptTryFoldWithHelper for T +where + I: Interner, + T: TypeFoldable, +{ + #[inline(always)] + fn mk_try_fold_with_helper>() + -> fn(Self, &mut F) -> Result { + Self::try_fold_with + } +} + +/// While this is implemented for all `T`, it is only useable via `OptTryFoldWith` if +/// `T` implements `TypeTraversable`. +impl OptTryFoldWithHelper for T +where + I: Interner, +{ + #[inline(always)] + fn mk_try_fold_with_helper>() + -> fn(Self, &mut F) -> Result { + |this, _| Ok(this) + } +} diff --git a/compiler/rustc_type_ir/src/traverse/visit.rs b/compiler/rustc_type_ir/src/traverse/visit.rs index 71c3646498b9f..bdf714bc21482 100644 --- a/compiler/rustc_type_ir/src/traverse/visit.rs +++ b/compiler/rustc_type_ir/src/traverse/visit.rs @@ -41,14 +41,14 @@ //! - u.visit_with(visitor) //! ``` -use std::fmt; use std::ops::ControlFlow; +use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; -use rustc_ast_ir::{try_visit, walk_visitable_list}; use rustc_index::{Idx, IndexVec}; use thin_vec::ThinVec; +use super::{ImportantTypeTraversal, OptVisitWith, TypeTraversable}; use crate::data_structures::Lrc; use crate::inherent::*; use crate::{self as ty, Interner, TypeFlags}; @@ -58,7 +58,7 @@ use crate::{self as ty, Interner, TypeFlags}; /// /// To implement this conveniently, use the derive macro located in /// `rustc_macros`. -pub trait TypeVisitable: fmt::Debug + Clone { +pub trait TypeVisitable: TypeTraversable { /// The entry point for visiting. To visit a value `t` with a visitor `v` /// call: `t.visit_with(v)`. /// @@ -131,27 +131,27 @@ pub trait TypeVisitor: Sized { /////////////////////////////////////////////////////////////////////////// // Traversal implementations. -impl, U: TypeVisitable> TypeVisitable for (T, U) { +impl, U: OptVisitWith> TypeVisitable for (T, U) { fn visit_with>(&self, visitor: &mut V) -> V::Result { - try_visit!(self.0.visit_with(visitor)); - self.1.visit_with(visitor) + try_visit!(OptVisitWith::mk_visit_with()(&self.0, visitor)); + OptVisitWith::mk_visit_with()(&self.1, visitor) } } -impl, B: TypeVisitable, C: TypeVisitable> TypeVisitable +impl, B: TypeVisitable, C: TypeVisitable> TypeVisitable for (A, B, C) { fn visit_with>(&self, visitor: &mut V) -> V::Result { - try_visit!(self.0.visit_with(visitor)); - try_visit!(self.1.visit_with(visitor)); - self.2.visit_with(visitor) + try_visit!(OptVisitWith::mk_visit_with()(&self.0, visitor)); + try_visit!(OptVisitWith::mk_visit_with()(&self.1, visitor)); + OptVisitWith::mk_visit_with()(&self.2, visitor) } } -impl> TypeVisitable for Option { +impl> TypeVisitable for Option { fn visit_with>(&self, visitor: &mut V) -> V::Result { match self { - Some(v) => v.visit_with(visitor), + Some(v) => OptVisitWith::mk_visit_with()(v, visitor), None => V::Result::output(), } } @@ -160,34 +160,38 @@ impl> TypeVisitable for Option { impl, E: TypeVisitable> TypeVisitable for Result { fn visit_with>(&self, visitor: &mut V) -> V::Result { match self { - Ok(v) => v.visit_with(visitor), - Err(e) => e.visit_with(visitor), + Ok(v) => OptVisitWith::mk_visit_with()(v, visitor), + Err(e) => OptVisitWith::mk_visit_with()(e, visitor), } } } -impl> TypeVisitable for Lrc { +impl> TypeVisitable for Lrc { fn visit_with>(&self, visitor: &mut V) -> V::Result { - (**self).visit_with(visitor) + OptVisitWith::mk_visit_with()(&**self, visitor) } } -impl> TypeVisitable for Box { +impl> TypeVisitable for Box { fn visit_with>(&self, visitor: &mut V) -> V::Result { - (**self).visit_with(visitor) + OptVisitWith::mk_visit_with()(&**self, visitor) } } -impl> TypeVisitable for Vec { +impl> TypeVisitable for Vec { fn visit_with>(&self, visitor: &mut V) -> V::Result { - walk_visitable_list!(visitor, self.iter()); + for elem in self.iter() { + try_visit!(OptVisitWith::mk_visit_with()(elem, visitor)); + } V::Result::output() } } -impl> TypeVisitable for ThinVec { +impl> TypeVisitable for ThinVec { fn visit_with>(&self, visitor: &mut V) -> V::Result { - walk_visitable_list!(visitor, self.iter()); + for elem in self.iter() { + try_visit!(OptVisitWith::mk_visit_with()(elem, visitor)); + } V::Result::output() } } @@ -195,23 +199,29 @@ impl> TypeVisitable for ThinVec { // `TypeFoldable` isn't impl'd for `&[T]`. It doesn't make sense in the general // case, because we can't return a new slice. But note that there are a couple // of trivial impls of `TypeFoldable` for specific slice types elsewhere. -impl> TypeVisitable for &[T] { +impl> TypeVisitable for &[T] { fn visit_with>(&self, visitor: &mut V) -> V::Result { - walk_visitable_list!(visitor, self.iter()); + for elem in self.iter() { + try_visit!(OptVisitWith::mk_visit_with()(elem, visitor)); + } V::Result::output() } } -impl> TypeVisitable for Box<[T]> { +impl> TypeVisitable for Box<[T]> { fn visit_with>(&self, visitor: &mut V) -> V::Result { - walk_visitable_list!(visitor, self.iter()); + for elem in self.iter() { + try_visit!(OptVisitWith::mk_visit_with()(elem, visitor)); + } V::Result::output() } } -impl, Ix: Idx> TypeVisitable for IndexVec { +impl, Ix: Idx> TypeVisitable for IndexVec { fn visit_with>(&self, visitor: &mut V) -> V::Result { - walk_visitable_list!(visitor, self.iter()); + for elem in self.iter() { + try_visit!(OptVisitWith::mk_visit_with()(elem, visitor)); + } V::Result::output() } } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 499e6d3dd37d1..b7f6ef4ffbb9a 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -861,11 +861,7 @@ pub struct TypeAndMut { pub struct FnSig { pub inputs_and_output: I::Tys, pub c_variadic: bool, - #[type_visitable(ignore)] - #[type_foldable(identity)] pub safety: I::Safety, - #[type_visitable(ignore)] - #[type_foldable(identity)] pub abi: I::Abi, } diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 10b164eae027b..09a43b1795516 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -372,12 +372,8 @@ pub struct CoroutineClosureSignature { /// Always false pub c_variadic: bool, /// Always `Normal` (safe) - #[type_visitable(ignore)] - #[type_foldable(identity)] pub safety: I::Safety, /// Always `RustCall` - #[type_visitable(ignore)] - #[type_foldable(identity)] pub abi: I::Abi, } diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index aaf69e2648d5c..e095fa921950c 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -1,33 +1,37 @@ -use quote::{ToTokens, quote}; +use quote::quote; +use syn::parse_quote; use syn::visit_mut::VisitMut; -use syn::{Attribute, parse_quote}; use synstructure::decl_derive; -decl_derive!( - [TypeVisitable_Generic, attributes(type_visitable)] => type_visitable_derive -); -decl_derive!( - [TypeFoldable_Generic, attributes(type_foldable)] => type_foldable_derive -); -decl_derive!( - [Lift_Generic] => lift_derive -); - -fn has_ignore_attr(attrs: &[Attribute], name: &'static str, meta: &'static str) -> bool { - let mut ignored = false; - attrs.iter().for_each(|attr| { - if !attr.path().is_ident(name) { - return; - } - let _ = attr.parse_nested_meta(|nested| { - if nested.path.is_ident(meta) { - ignored = true; - } - Ok(()) - }); - }); +decl_derive!([NoopTypeTraversable_Generic] => noop_type_traversable_derive); +decl_derive!([TypeFoldable_Generic] => type_foldable_derive); +decl_derive!([TypeVisitable_Generic] => type_visitable_derive); +decl_derive!([Lift_Generic] => lift_derive); + +fn noop_type_traversable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } - ignored + if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { + s.add_impl_generic(parse_quote! { I }); + } + + s.add_bounds(synstructure::AddBounds::None); + let mut where_clauses = None; + s.add_trait_bounds( + &parse_quote!(::rustc_type_ir::traverse::TypeTraversable), + &mut where_clauses, + synstructure::AddBounds::Fields, + ); + s.add_where_predicate(parse_quote! { I: Interner }); + for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { + s.add_where_predicate(pred); + } + + s.bound_impl(quote!(::rustc_type_ir::traverse::TypeTraversable), quote! { + type Kind = ::rustc_type_ir::traverse::NoopTypeTraversal; + }) } fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { @@ -39,14 +43,21 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok s.add_impl_generic(parse_quote! { I }); } - s.filter(|bi| !has_ignore_attr(&bi.ast().attrs, "type_visitable", "ignore")); - + s.add_bounds(synstructure::AddBounds::None); + let mut where_clauses = None; + s.add_trait_bounds( + &parse_quote!(::rustc_type_ir::traverse::OptVisitWith), + &mut where_clauses, + synstructure::AddBounds::Fields, + ); s.add_where_predicate(parse_quote! { I: Interner }); - s.add_bounds(synstructure::AddBounds::Fields); + for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { + s.add_where_predicate(pred); + } let body_visit = s.each(|bind| { quote! { match ::rustc_ast_ir::visit::VisitorResult::branch( - ::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor) + ::rustc_type_ir::traverse::OptVisitWith::mk_visit_with()(#bind, __visitor) ) { ::core::ops::ControlFlow::Continue(()) => {}, ::core::ops::ControlFlow::Break(r) => { @@ -77,30 +88,29 @@ fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Toke s.add_impl_generic(parse_quote! { I }); } + s.add_bounds(synstructure::AddBounds::None); + let mut where_clauses = None; + s.add_trait_bounds( + &parse_quote!(::rustc_type_ir::traverse::OptTryFoldWith), + &mut where_clauses, + synstructure::AddBounds::Fields, + ); s.add_where_predicate(parse_quote! { I: Interner }); - s.add_bounds(synstructure::AddBounds::Fields); + for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { + s.add_where_predicate(pred); + } + s.bind_with(|_| synstructure::BindStyle::Move); let body_fold = s.each_variant(|vi| { let bindings = vi.bindings(); vi.construct(|_, index| { let bind = &bindings[index]; - - // retain value of fields with #[type_foldable(identity)] - if has_ignore_attr(&bind.ast().attrs, "type_foldable", "identity") { - bind.to_token_stream() - } else { - quote! { - ::rustc_type_ir::fold::TypeFoldable::try_fold_with(#bind, __folder)? - } + quote! { + ::rustc_type_ir::traverse::OptTryFoldWith::mk_try_fold_with()(#bind, __folder)? } }) }); - // We filter fields which get ignored and don't require them to implement - // `TypeFoldable`. We do so after generating `body_fold` as we still need - // to generate code for them. - s.filter(|bi| !has_ignore_attr(&bi.ast().attrs, "type_foldable", "identity")); - s.add_bounds(synstructure::AddBounds::Fields); s.bound_impl(quote!(::rustc_type_ir::fold::TypeFoldable), quote! { fn try_fold_with<__F: ::rustc_type_ir::fold::FallibleTypeFolder>( self, From 046a949d8921093c12e77ff046d059eb92eef5a9 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 23 Oct 2024 00:43:17 +0200 Subject: [PATCH 5/7] stash --- compiler/rustc_type_ir/src/macros.rs | 28 ++-------------------- compiler/rustc_type_ir/src/traverse/mod.rs | 11 +-------- compiler/rustc_type_ir/src/ty_kind.rs | 6 +++-- 3 files changed, 7 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index aae5aeb5fb363..92cd9322a4252 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -3,32 +3,8 @@ macro_rules! TrivialTypeTraversalImpls { ($($ty:ty,)+) => { $( - impl $crate::fold::TypeFoldable for $ty { - fn try_fold_with>( - self, - _: &mut F, - ) -> ::std::result::Result { - Ok(self) - } - - #[inline] - fn fold_with>( - self, - _: &mut F, - ) -> Self { - self - } - } - - impl $crate::visit::TypeVisitable for $ty { - #[inline] - fn visit_with>( - &self, - _: &mut F) - -> F::Result - { - ::output() - } + impl $crate::traverse::TypeTraversable for $ty { + type Kind = $crate::traverse::NoopTypeTraversal; } )+ }; diff --git a/compiler/rustc_type_ir/src/traverse/mod.rs b/compiler/rustc_type_ir/src/traverse/mod.rs index 0cde01f61f286..419a6dc0a4663 100644 --- a/compiler/rustc_type_ir/src/traverse/mod.rs +++ b/compiler/rustc_type_ir/src/traverse/mod.rs @@ -40,17 +40,8 @@ pub trait TypeTraversable: fmt::Debug + Clone { } pub struct ImportantTypeTraversal; pub struct NoopTypeTraversal; -#[inline(always)] -pub fn noop_visit() -> V::Result -where - I: Interner, - V: TypeVisitor, - T: TypeTraversable, -{ - V::Result::output() -} -impl> TypeTraversable for T { +impl TypeTraversable for T { type Kind = ImportantTypeTraversal; } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index b7f6ef4ffbb9a..3f98417e4bb8e 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -8,7 +8,9 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + Lift_Generic, NoopTypeTraversable_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use self::TyKind::*; pub use self::closure::*; @@ -1012,7 +1014,7 @@ impl ty::Binder> { #[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(NoopTypeTraversable_Generic, Lift_Generic)] pub struct FnHeader { pub c_variadic: bool, pub safety: I::Safety, From ddf7917ce3c842711faa002179bf8f76c160c062 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 23 Oct 2024 01:30:00 +0200 Subject: [PATCH 6/7] uwu --- compiler/rustc_macros/src/type_foldable.rs | 1 + compiler/rustc_macros/src/type_visitable.rs | 19 ++++++- compiler/rustc_middle/src/hir/place.rs | 8 ++- compiler/rustc_middle/src/traits/solve.rs | 9 ++- compiler/rustc_middle/src/ty/generic_args.rs | 7 +++ compiler/rustc_middle/src/ty/mod.rs | 7 +++ .../rustc_middle/src/ty/structural_impls.rs | 56 +++++++++++-------- .../src/solve/eval_ctxt/canonical.rs | 3 +- compiler/rustc_type_ir/src/binder.rs | 4 ++ compiler/rustc_type_ir/src/interner.rs | 2 +- compiler/rustc_type_ir/src/traverse/mod.rs | 4 -- compiler/rustc_type_ir/src/traverse/visit.rs | 43 ++++++++++++-- compiler/rustc_type_ir_macros/src/lib.rs | 19 ++++++- 13 files changed, 139 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index e24dbf09d5872..afea1089a9401 100644 --- a/compiler/rustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs @@ -19,6 +19,7 @@ pub(super) fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_m &mut where_clauses, synstructure::AddBounds::Fields, ); + s.add_where_predicate(parse_quote! { Self: std::fmt::Debug + Clone }); for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { s.add_where_predicate(pred); } diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs index 750afbb2b6375..24850dbdb4071 100644 --- a/compiler/rustc_macros/src/type_visitable.rs +++ b/compiler/rustc_macros/src/type_visitable.rs @@ -23,10 +23,13 @@ pub(super) fn type_visitable_derive( &mut where_clauses, synstructure::AddBounds::Fields, ); + s.add_where_predicate(parse_quote! { Self: std::fmt::Debug + Clone }); for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { s.add_where_predicate(pred); } + let impl_traversable_s = s.clone(); + let body_visit = s.each(|bind| { quote! { match ::rustc_ast_ir::visit::VisitorResult::branch( @@ -41,7 +44,7 @@ pub(super) fn type_visitable_derive( }); s.bind_with(|_| synstructure::BindStyle::Move); - s.bound_impl( + let visitable_impl = s.bound_impl( quote!(::rustc_middle::ty::visit::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>), quote! { fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>( @@ -52,5 +55,17 @@ pub(super) fn type_visitable_derive( <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() } }, - ) + ); + + let traversable_impl = impl_traversable_s.bound_impl( + quote!(::rustc_middle::ty::traverse::TypeTraversable<::rustc_middle::ty::TyCtxt<'tcx>>), + quote! { + type Kind = ::rustc_middle::ty::traverse::ImportantTypeTraversal; + }, + ); + + quote! { + #visitable_impl + #traversable_impl + } } diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs index 4c7af0bc3726d..ceaa74156cd98 100644 --- a/compiler/rustc_middle/src/hir/place.rs +++ b/compiler/rustc_middle/src/hir/place.rs @@ -1,12 +1,14 @@ use rustc_hir::HirId; -use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; +use rustc_macros::{ + HashStable, NoopTypeTraversable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, +}; use rustc_target::abi::{FieldIdx, VariantIdx}; use crate::ty; use crate::ty::Ty; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] +#[derive(NoopTypeTraversable)] pub enum PlaceBase { /// A temporary variable. Rvalue, @@ -19,7 +21,7 @@ pub enum PlaceBase { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] +#[derive(NoopTypeTraversable)] pub enum ProjectionKind { /// A dereference of a pointer, reference or `Box` of the given type. Deref, diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index f659bf8125a0e..e538c3839320a 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -1,8 +1,9 @@ use rustc_ast_ir::try_visit; use rustc_data_structures::intern::Interned; use rustc_macros::HashStable; -use rustc_type_ir as ir; pub use rustc_type_ir::solve::*; +use rustc_type_ir::traverse::{ImportantTypeTraversal, TypeTraversable}; +use rustc_type_ir::{self as ir}; use crate::ty::{ self, FallibleTypeFolder, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, @@ -72,6 +73,9 @@ impl<'tcx> TypeFoldable> for ExternalConstraints<'tcx> { } } +impl<'tcx> TypeTraversable> for ExternalConstraints<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for ExternalConstraints<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { try_visit!(self.region_constraints.visit_with(visitor)); @@ -106,6 +110,9 @@ impl<'tcx> TypeFoldable> for PredefinedOpaques<'tcx> { } } +impl<'tcx> TypeTraversable> for PredefinedOpaques<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for PredefinedOpaques<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { self.opaque_types.visit_with(visitor) diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index daf1362e25c1f..702e46bce5de8 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -14,6 +14,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, extension}; use rustc_serialize::{Decodable, Encodable}; use rustc_type_ir::WithCachedTypeInfo; +use rustc_type_ir::traverse::{ImportantTypeTraversal, NoopTypeTraversal, TypeTraversable}; use smallvec::SmallVec; use crate::ty::codec::{TyDecoder, TyEncoder}; @@ -329,6 +330,9 @@ impl<'tcx> TypeFoldable> for GenericArg<'tcx> { } } +impl<'tcx> TypeTraversable> for GenericArg<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for GenericArg<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { match self.unpack() { @@ -642,6 +646,9 @@ impl<'tcx> TypeFoldable> for &'tcx ty::List> { } } +impl<'tcx, T: TypeVisitable>> TypeTraversable> for &'tcx ty::List { + type Kind = ImportantTypeTraversal; +} impl<'tcx, T: TypeVisitable>> TypeVisitable> for &'tcx ty::List { #[inline] fn visit_with>>(&self, visitor: &mut V) -> V::Result { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2a0ae0f62439c..9e653e0e20a42 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -58,6 +58,7 @@ pub use rustc_type_ir::relate::VarianceDiagInfo; use rustc_type_ir::traverse::TypeTraversable; pub use rustc_type_ir::*; use tracing::{debug, instrument}; +use traverse::ImportantTypeTraversal; pub use vtable::*; use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir}; @@ -548,6 +549,9 @@ impl<'tcx> TypeFoldable> for Term<'tcx> { } } +impl<'tcx> TypeTraversable> for Term<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for Term<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { match self.unpack() { @@ -1037,6 +1041,9 @@ impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { } } +impl<'tcx> TypeTraversable> for ParamEnv<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for ParamEnv<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { try_visit!(self.caller_bounds().visit_with(visitor)); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index c7f6a2cb881f5..8509d9dff0780 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -11,7 +11,7 @@ use rustc_hir::def::Namespace; use rustc_span::source_map::Spanned; use rustc_target::abi::TyAndLayout; use rustc_type_ir::ConstKind; -use rustc_type_ir::traverse::TypeTraversable; +use rustc_type_ir::traverse::{ImportantTypeTraversal, TypeTraversable}; use super::print::PrettyPrinter; use super::{GenericArg, GenericArgKind, Pattern, Region}; @@ -19,7 +19,7 @@ use crate::mir::interpret; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use crate::ty::print::{FmtPrinter, Printer, with_no_trimmed_paths}; use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; +use crate::ty::{self, Lift, Term, TermKind, Ty, TyCtxt}; impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -258,7 +258,6 @@ TrivialTypeTraversalImpls! { ::rustc_span::Span, ::rustc_span::symbol::Ident, ty::BoundVar, - ty::ValTree<'tcx>, } // For some things about which the type library does not know, or does not // provide any traversal implementations, we need to provide a traversal @@ -304,12 +303,6 @@ impl<'a, 'tcx> Lift> for Term<'a> { /////////////////////////////////////////////////////////////////////////// // Traversal implementations. -impl<'tcx> TypeVisitable> for ty::AdtDef<'tcx> { - fn visit_with>>(&self, _visitor: &mut V) -> V::Result { - V::Result::output() - } -} - impl<'tcx> TypeFoldable> for &'tcx ty::List> { fn try_fold_with>>( self, @@ -338,6 +331,9 @@ impl<'tcx> TypeFoldable> for Pattern<'tcx> { } } +impl<'tcx> TypeTraversable> for Pattern<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for Pattern<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { (**self).visit_with(visitor) @@ -353,6 +349,9 @@ impl<'tcx> TypeFoldable> for Ty<'tcx> { } } +impl<'tcx> TypeTraversable> for Ty<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for Ty<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_ty(*self) @@ -469,6 +468,9 @@ impl<'tcx> TypeFoldable> for ty::Region<'tcx> { } } +impl<'tcx> TypeTraversable> for ty::Region<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for ty::Region<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_region(*self) @@ -494,12 +496,18 @@ impl<'tcx> TypeFoldable> for ty::Clause<'tcx> { } } +impl<'tcx> TypeTraversable> for ty::Predicate<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for ty::Predicate<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_predicate(*self) } } +impl<'tcx> TypeTraversable> for ty::Clause<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for ty::Clause<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_predicate(self.as_predicate()) @@ -522,6 +530,9 @@ impl<'tcx> TypeSuperVisitable> for ty::Predicate<'tcx> { } } +impl<'tcx> TypeTraversable> for ty::Clauses<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for ty::Clauses<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_clauses(self) @@ -552,6 +563,9 @@ impl<'tcx> TypeFoldable> for ty::Const<'tcx> { } } +impl<'tcx> TypeTraversable> for ty::Const<'tcx> { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for ty::Const<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_const(*self) @@ -602,6 +616,9 @@ impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { } } +impl<'tcx> TypeTraversable> for rustc_span::ErrorGuaranteed { + type Kind = ImportantTypeTraversal; +} impl<'tcx> TypeVisitable> for rustc_span::ErrorGuaranteed { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_error(*self) @@ -617,27 +634,20 @@ impl<'tcx> TypeFoldable> for rustc_span::ErrorGuaranteed { } } -impl<'tcx> TypeFoldable> for InferConst { - fn try_fold_with>>( - self, - _folder: &mut F, - ) -> Result { - Ok(self) - } -} - -impl<'tcx> TypeVisitable> for InferConst { - fn visit_with>>(&self, _visitor: &mut V) -> V::Result { - V::Result::output() - } +impl<'tcx> TypeTraversable> for TyAndLayout<'tcx, Ty<'tcx>> { + type Kind = ImportantTypeTraversal; } - impl<'tcx> TypeVisitable> for TyAndLayout<'tcx, Ty<'tcx>> { fn visit_with>>(&self, visitor: &mut V) -> V::Result { visitor.visit_ty(self.ty) } } +impl<'tcx, T: TypeVisitable> + Debug + Clone> TypeTraversable> + for Spanned +{ + type Kind = ImportantTypeTraversal; +} impl<'tcx, T: TypeVisitable> + Debug + Clone> TypeVisitable> for Spanned { diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 71ce0cce77224..4d03d9affa3b8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -15,6 +15,7 @@ use rustc_index::IndexVec; use rustc_type_ir::fold::TypeFoldable; use rustc_type_ir::inherent::*; use rustc_type_ir::relate::solver_relating::RelateExt; +use rustc_type_ir::traverse::OptTryFoldWith; use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, InferCtxtLike, Interner}; use tracing::{debug, instrument, trace}; @@ -426,7 +427,7 @@ pub(in crate::solve) fn make_canonical_state( where D: SolverDelegate, I: Interner, - T: TypeFoldable, + T: OptTryFoldWith, { let var_values = CanonicalVarValues { var_values: delegate.cx().mk_args(var_values) }; let state = inspect::State { var_values, data }; diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index f20beb797500e..fb0637fcac7fa 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -14,6 +14,7 @@ use crate::data_structures::SsoHashSet; use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::inherent::*; use crate::lift::Lift; +use crate::traverse::{ImportantTypeTraversal, TypeTraversable}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use crate::{self as ty, Interner}; @@ -125,6 +126,9 @@ impl> TypeFoldable for Binder { } } +impl> TypeTraversable for Binder { + type Kind = ImportantTypeTraversal; +} impl> TypeVisitable for Binder { fn visit_with>(&self, visitor: &mut V) -> V::Result { visitor.visit_binder(self) diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 6c43c237bf078..ceb50e196d28f 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -66,7 +66,7 @@ pub trait Interner: + Hash + Default + Eq - + TypeVisitable + + TypeTraversable + SliceLike; type CanonicalVars: Copy diff --git a/compiler/rustc_type_ir/src/traverse/mod.rs b/compiler/rustc_type_ir/src/traverse/mod.rs index 419a6dc0a4663..c389c4fab2654 100644 --- a/compiler/rustc_type_ir/src/traverse/mod.rs +++ b/compiler/rustc_type_ir/src/traverse/mod.rs @@ -41,10 +41,6 @@ pub trait TypeTraversable: fmt::Debug + Clone { pub struct ImportantTypeTraversal; pub struct NoopTypeTraversal; -impl TypeTraversable for T { - type Kind = ImportantTypeTraversal; -} - pub trait OptVisitWith: TypeTraversable { fn mk_visit_with>() -> fn(&Self, &mut V) -> V::Result; } diff --git a/compiler/rustc_type_ir/src/traverse/visit.rs b/compiler/rustc_type_ir/src/traverse/visit.rs index bdf714bc21482..3f8bb32e1c826 100644 --- a/compiler/rustc_type_ir/src/traverse/visit.rs +++ b/compiler/rustc_type_ir/src/traverse/visit.rs @@ -131,6 +131,9 @@ pub trait TypeVisitor: Sized { /////////////////////////////////////////////////////////////////////////// // Traversal implementations. +impl, U: OptVisitWith> TypeTraversable for (T, U) { + type Kind = ImportantTypeTraversal; +} impl, U: OptVisitWith> TypeVisitable for (T, U) { fn visit_with>(&self, visitor: &mut V) -> V::Result { try_visit!(OptVisitWith::mk_visit_with()(&self.0, visitor)); @@ -138,7 +141,12 @@ impl, U: OptVisitWith> TypeVisitable for ( } } -impl, B: TypeVisitable, C: TypeVisitable> TypeVisitable +impl, B: OptVisitWith, C: OptVisitWith> TypeTraversable + for (A, B, C) +{ + type Kind = ImportantTypeTraversal; +} +impl, B: OptVisitWith, C: OptVisitWith> TypeVisitable for (A, B, C) { fn visit_with>(&self, visitor: &mut V) -> V::Result { @@ -148,6 +156,9 @@ impl, B: TypeVisitable, C: TypeVisitable> } } +impl> TypeTraversable for Option { + type Kind = ImportantTypeTraversal; +} impl> TypeVisitable for Option { fn visit_with>(&self, visitor: &mut V) -> V::Result { match self { @@ -157,7 +168,10 @@ impl> TypeVisitable for Option { } } -impl, E: TypeVisitable> TypeVisitable for Result { +impl, E: OptVisitWith> TypeTraversable for Result { + type Kind = ImportantTypeTraversal; +} +impl, E: OptVisitWith> TypeVisitable for Result { fn visit_with>(&self, visitor: &mut V) -> V::Result { match self { Ok(v) => OptVisitWith::mk_visit_with()(v, visitor), @@ -166,18 +180,26 @@ impl, E: TypeVisitable> TypeVisitable for } } +impl> TypeTraversable for Lrc { + type Kind = ImportantTypeTraversal; +} impl> TypeVisitable for Lrc { fn visit_with>(&self, visitor: &mut V) -> V::Result { OptVisitWith::mk_visit_with()(&**self, visitor) } } - +impl> TypeTraversable for Box { + type Kind = ImportantTypeTraversal; +} impl> TypeVisitable for Box { fn visit_with>(&self, visitor: &mut V) -> V::Result { OptVisitWith::mk_visit_with()(&**self, visitor) } } +impl> TypeTraversable for Vec { + type Kind = ImportantTypeTraversal; +} impl> TypeVisitable for Vec { fn visit_with>(&self, visitor: &mut V) -> V::Result { for elem in self.iter() { @@ -187,6 +209,9 @@ impl> TypeVisitable for Vec { } } +impl> TypeTraversable for ThinVec { + type Kind = ImportantTypeTraversal; +} impl> TypeVisitable for ThinVec { fn visit_with>(&self, visitor: &mut V) -> V::Result { for elem in self.iter() { @@ -196,9 +221,9 @@ impl> TypeVisitable for ThinVec { } } -// `TypeFoldable` isn't impl'd for `&[T]`. It doesn't make sense in the general -// case, because we can't return a new slice. But note that there are a couple -// of trivial impls of `TypeFoldable` for specific slice types elsewhere. +impl> TypeTraversable for &[T] { + type Kind = ImportantTypeTraversal; +} impl> TypeVisitable for &[T] { fn visit_with>(&self, visitor: &mut V) -> V::Result { for elem in self.iter() { @@ -208,6 +233,9 @@ impl> TypeVisitable for &[T] { } } +impl> TypeTraversable for Box<[T]> { + type Kind = ImportantTypeTraversal; +} impl> TypeVisitable for Box<[T]> { fn visit_with>(&self, visitor: &mut V) -> V::Result { for elem in self.iter() { @@ -217,6 +245,9 @@ impl> TypeVisitable for Box<[T]> { } } +impl, Ix: Idx> TypeTraversable for IndexVec { + type Kind = ImportantTypeTraversal; +} impl, Ix: Idx> TypeVisitable for IndexVec { fn visit_with>(&self, visitor: &mut V) -> V::Result { for elem in self.iter() { diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index e095fa921950c..74bb22bbbfe36 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -54,6 +54,9 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok for pred in where_clauses.into_iter().flat_map(|c| c.predicates) { s.add_where_predicate(pred); } + + let impl_traversable_s = s.clone(); + let body_visit = s.each(|bind| { quote! { match ::rustc_ast_ir::visit::VisitorResult::branch( @@ -68,7 +71,7 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok }); s.bind_with(|_| synstructure::BindStyle::Move); - s.bound_impl(quote!(::rustc_type_ir::visit::TypeVisitable), quote! { + let visitable_impl = s.bound_impl(quote!(::rustc_type_ir::visit::TypeVisitable), quote! { fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor>( &self, __visitor: &mut __V @@ -76,7 +79,19 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok match *self { #body_visit } <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() } - }) + }); + + let traversable_impl = impl_traversable_s.bound_impl( + quote!(::rustc_type_ir::traverse::TypeTraversable), + quote! { + type Kind = ::rustc_type_ir::traverse::ImportantTypeTraversal; + }, + ); + + quote! { + #visitable_impl + #traversable_impl + } } fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { From 7bfb0ecf79e7976a2cae256d728ceda47cca86bc Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 23 Oct 2024 02:05:47 +0200 Subject: [PATCH 7/7] it compiles :3 --- .../src/infer/canonical/query_response.rs | 17 +-- .../src/traits/structural_impls.rs | 6 ++ compiler/rustc_middle/src/thir.rs | 5 +- compiler/rustc_middle/src/ty/adt.rs | 4 +- compiler/rustc_middle/src/ty/generic_args.rs | 6 +- .../rustc_middle/src/ty/structural_impls.rs | 100 +++++++++--------- compiler/rustc_middle/src/ty/sty.rs | 6 +- .../src/solve/eval_ctxt/canonical.rs | 2 +- compiler/rustc_trait_selection/src/infer.rs | 5 +- .../src/traits/engine.rs | 4 +- .../src/traits/query/type_op/custom.rs | 10 +- .../src/traits/query/type_op/mod.rs | 3 +- compiler/rustc_type_ir/src/binder.rs | 8 +- compiler/rustc_type_ir/src/const_kind.rs | 8 +- compiler/rustc_type_ir/src/lib.rs | 2 + compiler/rustc_type_ir/src/traverse/mod.rs | 6 +- compiler/rustc_type_ir/src/traverse/visit.rs | 8 +- 17 files changed, 113 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 1d3d32ef74979..cdc3d50c4a84e 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -15,8 +15,10 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::fold::TypeFoldable; +use rustc_middle::ty::traverse::AlwaysTraversable; use rustc_middle::ty::{self, BoundVar, GenericArg, GenericArgKind, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; +use rustc_type_ir::traverse::OptTryFoldWith; use tracing::{debug, instrument}; use crate::infer::canonical::instantiate::{CanonicalExt, instantiate_value}; @@ -60,7 +62,7 @@ impl<'tcx> InferCtxt<'tcx> { fulfill_cx: &mut dyn TraitEngine<'tcx, ScrubbedTraitError<'tcx>>, ) -> Result, NoSolution> where - T: Debug + TypeFoldable>, + T: OptTryFoldWith>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, { let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?; @@ -107,7 +109,7 @@ impl<'tcx> InferCtxt<'tcx> { fulfill_cx: &mut dyn TraitEngine<'tcx, ScrubbedTraitError<'tcx>>, ) -> Result, NoSolution> where - T: Debug + TypeFoldable>, + T: OptTryFoldWith>, { let tcx = self.tcx; @@ -243,7 +245,7 @@ impl<'tcx> InferCtxt<'tcx> { output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, ) -> InferResult<'tcx, R> where - R: Debug + TypeFoldable>, + R: OptTryFoldWith>, { let InferOk { value: result_args, mut obligations } = self .query_response_instantiation_guess( @@ -326,8 +328,11 @@ impl<'tcx> InferCtxt<'tcx> { .map(|p_c| instantiate_value(self.tcx, &result_args, p_c.clone())), ); - let user_result: R = - query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone()); + let user_result: R = query_response + .instantiate_projected(self.tcx, &result_args, |q_r| { + AlwaysTraversable(q_r.value.clone()) + }) + .0; Ok(InferOk { value: user_result, obligations }) } @@ -396,7 +401,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where - R: Debug + TypeFoldable>, + R: OptTryFoldWith>, { // For each new universe created in the query result that did // not appear in the original query, create a local diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 31f585c0c9edd..e185feba26db9 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -4,6 +4,7 @@ use rustc_ast_ir::try_visit; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable}; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor}; use rustc_middle::ty::{self, TyCtxt}; +use rustc_type_ir::traverse::{ImportantTypeTraversal, TypeTraversable}; use crate::traits; use crate::traits::project::Normalized; @@ -55,6 +56,11 @@ impl<'tcx, O: TypeFoldable>> TypeFoldable> } } +impl<'tcx, O: TypeVisitable>> TypeTraversable> + for traits::Obligation<'tcx, O> +{ + type Kind = ImportantTypeTraversal; +} impl<'tcx, O: TypeVisitable>> TypeVisitable> for traits::Obligation<'tcx, O> { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 1202371eec96e..9173a7518a4b5 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -17,7 +17,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::{IndexVec, newtype_index}; -use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable}; +use rustc_macros::{HashStable, NoopTypeTraversable, TyDecodable, TyEncodable, TypeVisitable}; use rustc_middle::middle::region; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp}; @@ -234,7 +234,8 @@ pub enum StmtKind<'tcx> { }, } -#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] +#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable)] +#[derive(NoopTypeTraversable, TyEncodable, TyDecodable)] pub struct LocalVarId(pub HirId); /// A THIR expression. diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 3322a2643d7d3..c32ba563816f4 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -13,7 +13,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; use rustc_index::{IndexSlice, IndexVec}; -use rustc_macros::{HashStable, TyDecodable, TyEncodable}; +use rustc_macros::{HashStable, NoopTypeTraversable, TyDecodable, TyEncodable}; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; @@ -168,7 +168,7 @@ impl<'a> HashStable> for AdtDefData { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable, NoopTypeTraversable)] #[rustc_pass_by_value] pub struct AdtDef<'tcx>(pub Interned<'tcx, AdtDefData>); diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 702e46bce5de8..7f6edb0a61c76 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -14,7 +14,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, extension}; use rustc_serialize::{Decodable, Encodable}; use rustc_type_ir::WithCachedTypeInfo; -use rustc_type_ir::traverse::{ImportantTypeTraversal, NoopTypeTraversal, TypeTraversable}; +use rustc_type_ir::traverse::{ImportantTypeTraversal, TypeTraversable}; use smallvec::SmallVec; use crate::ty::codec::{TyDecoder, TyEncoder}; @@ -646,8 +646,8 @@ impl<'tcx> TypeFoldable> for &'tcx ty::List> { } } -impl<'tcx, T: TypeVisitable>> TypeTraversable> for &'tcx ty::List { - type Kind = ImportantTypeTraversal; +impl<'tcx, T: TypeTraversable>> TypeTraversable> for &'tcx ty::List { + type Kind = T::Kind; } impl<'tcx, T: TypeVisitable>> TypeVisitable> for &'tcx ty::List { #[inline] diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 8509d9dff0780..9c743f06c6c78 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -209,55 +209,56 @@ impl<'tcx> fmt::Debug for Region<'tcx> { // For things for which the type library provides traversal implementations // for all Interners, we only need to provide a Lift implementation: TrivialLiftImpls! { - (), - bool, - usize, - u64, + (), + bool, + usize, + u64, + crate::ty::ParamConst, } // For some things about which the type library does not know, or does not // provide any traversal implementations, we need to provide a traversal // implementation (only for TyCtxt<'_> interners). TrivialTypeTraversalImpls! { - ::rustc_target::abi::FieldIdx, - ::rustc_target::abi::VariantIdx, - crate::middle::region::Scope, - ::rustc_ast::InlineAsmOptions, - ::rustc_ast::InlineAsmTemplatePiece, - ::rustc_ast::NodeId, - ::rustc_span::symbol::Symbol, - ::rustc_hir::def::Res, - ::rustc_hir::def_id::LocalDefId, - ::rustc_hir::ByRef, - ::rustc_hir::HirId, - ::rustc_hir::RangeEnd, - ::rustc_hir::MatchSource, - ::rustc_target::asm::InlineAsmRegOrRegClass, - crate::mir::coverage::BlockMarkerId, - crate::mir::coverage::CounterId, - crate::mir::coverage::ExpressionId, - crate::mir::coverage::ConditionId, - crate::mir::Local, - crate::mir::Promoted, - crate::traits::Reveal, - crate::ty::adjustment::AutoBorrowMutability, - crate::ty::AdtKind, - crate::ty::BoundRegion, - // Including `BoundRegionKind` is a *bit* dubious, but direct - // references to bound region appear in `ty::Error`, and aren't - // really meant to be folded. In general, we can only fold a fully - // general `Region`. - crate::ty::BoundRegionKind, - crate::ty::AssocItem, - crate::ty::AssocKind, - crate::ty::Placeholder, - crate::ty::Placeholder, - crate::ty::Placeholder, +::rustc_target::abi::FieldIdx, +::rustc_target::abi::VariantIdx, +crate::middle::region::Scope, +::rustc_ast::InlineAsmOptions, +::rustc_ast::InlineAsmTemplatePiece, +::rustc_ast::NodeId, +::rustc_ast::ast::BindingMode, +::rustc_span::symbol::Symbol, +::rustc_hir::def::Res, +::rustc_hir::def_id::LocalDefId, +::rustc_hir::ByRef, +::rustc_hir::HirId, +::rustc_hir::RangeEnd, +::rustc_hir::MatchSource, +::rustc_target::asm::InlineAsmRegOrRegClass, +crate::mir::coverage::BlockMarkerId, +crate::mir::coverage::CounterId, +crate::mir::coverage::ExpressionId, +crate::mir::coverage::ConditionId, +crate::mir::Local, +crate::mir::Promoted, +crate::ty::adjustment::AutoBorrowMutability, +crate::ty::AdtKind, +crate::ty::BoundRegion, +// Including `BoundRegionKind` is a *bit* dubious, but direct +// references to bound region appear in `ty::Error`, and aren't +// really meant to be folded. In general, we can only fold a fully +// general `Region`. +crate::ty::BoundRegionKind, +crate::ty::AssocItem, +crate::ty::AssocKind, +crate::ty::Placeholder, +crate::ty::Placeholder, +crate::ty::Placeholder,} +TrivialTypeTraversalImpls! { crate::ty::LateParamRegion, crate::ty::adjustment::PointerCoercion, ::rustc_span::Span, ::rustc_span::symbol::Ident, - ty::BoundVar, } // For some things about which the type library does not know, or does not // provide any traversal implementations, we need to provide a traversal @@ -268,7 +269,6 @@ TrivialTypeTraversalAndLiftImpls! { ::rustc_hir::Safety, ::rustc_target::spec::abi::Abi, crate::ty::ClosureKind, - crate::ty::ParamConst, crate::ty::ParamTy, crate::ty::instance::ReifyReason, interpret::AllocId, @@ -578,12 +578,12 @@ impl<'tcx> TypeSuperFoldable> for ty::Const<'tcx> { folder: &mut F, ) -> Result { let kind = match self.kind() { - ConstKind::Param(p) => ConstKind::Param(p.try_fold_with(folder)?), - ConstKind::Infer(i) => ConstKind::Infer(i.try_fold_with(folder)?), + ConstKind::Param(p) => ConstKind::Param(p.noop_try_fold_with(folder)?), + ConstKind::Infer(i) => ConstKind::Infer(i.noop_try_fold_with(folder)?), ConstKind::Bound(d, b) => { - ConstKind::Bound(d.try_fold_with(folder)?, b.try_fold_with(folder)?) + ConstKind::Bound(d.noop_try_fold_with(folder)?, b.noop_try_fold_with(folder)?) } - ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?), + ConstKind::Placeholder(p) => ConstKind::Placeholder(p.noop_try_fold_with(folder)?), ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?), ConstKind::Value(t, v) => { ConstKind::Value(t.try_fold_with(folder)?, v.noop_try_fold_with(folder)?) @@ -598,17 +598,17 @@ impl<'tcx> TypeSuperFoldable> for ty::Const<'tcx> { impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { fn super_visit_with>>(&self, visitor: &mut V) -> V::Result { match self.kind() { - ConstKind::Param(p) => p.visit_with(visitor), - ConstKind::Infer(i) => i.visit_with(visitor), + ConstKind::Param(p) => p.noop_visit_with(visitor), + ConstKind::Infer(i) => i.noop_visit_with(visitor), ConstKind::Bound(d, b) => { - try_visit!(d.visit_with(visitor)); - b.visit_with(visitor) + try_visit!(d.noop_visit_with(visitor)); + b.noop_visit_with(visitor) } - ConstKind::Placeholder(p) => p.visit_with(visitor), + ConstKind::Placeholder(p) => p.noop_visit_with(visitor), ConstKind::Unevaluated(uv) => uv.visit_with(visitor), ConstKind::Value(t, v) => { try_visit!(t.visit_with(visitor)); - v.visit_with(visitor) + v.noop_visit_with(visitor) } ConstKind::Error(e) => e.visit_with(visitor), ConstKind::Expr(e) => e.visit_with(visitor), diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 74de378c4d78e..16d5dc03dcb17 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -13,7 +13,9 @@ use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::LangItem; use rustc_hir::def_id::DefId; -use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension}; +use rustc_macros::{ + HashStable, NoopTypeTraversable, TyDecodable, TyEncodable, TypeFoldable, extension, +}; use rustc_span::symbol::{Symbol, sym}; use rustc_span::{DUMMY_SP, Span}; use rustc_target::abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; @@ -323,7 +325,7 @@ impl<'tcx> ParamTy { } #[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] -#[derive(HashStable)] +#[derive(HashStable, NoopTypeTraversable)] pub struct ParamConst { pub index: u32, pub name: Symbol, diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 4d03d9affa3b8..72743f440149e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -442,7 +442,7 @@ where // FIXME: needs to be pub to be accessed by downstream // `rustc_trait_selection::solve::inspect::analyse`. -pub fn instantiate_canonical_state>( +pub fn instantiate_canonical_state>( delegate: &D, span: D::Span, param_env: I::ParamEnv, diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index bacb3b1b1b861..ee7037f799454 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,5 +1,3 @@ -use std::fmt::Debug; - use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; pub use rustc_infer::infer::*; @@ -11,6 +9,7 @@ use rustc_middle::infer::canonical::{ use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast}; use rustc_span::DUMMY_SP; +use rustc_type_ir::traverse::OptTryFoldWith; use tracing::instrument; use crate::infer::at::ToTrace; @@ -139,7 +138,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { ) -> Result, NoSolution> where K: TypeFoldable>, - R: Debug + TypeFoldable>, + R: OptTryFoldWith>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>, { let (infcx, key, canonical_inference_vars) = diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 5e270b62b0081..5b2115cb61d1a 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -1,5 +1,4 @@ use std::cell::RefCell; -use std::fmt::Debug; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::ErrorGuaranteed; @@ -15,6 +14,7 @@ use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::error::TypeError; +use rustc_middle::ty::traverse::OptTryFoldWith; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance}; use rustc_type_ir::relate::Relate; @@ -259,7 +259,7 @@ impl<'tcx> ObligationCtxt<'_, 'tcx, ScrubbedTraitError<'tcx>> { answer: T, ) -> Result, NoSolution> where - T: Debug + TypeFoldable>, + T: OptTryFoldWith>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, { self.infcx.make_canonicalized_query_response( diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 18010603286d1..4c6d4fb8a161a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -3,8 +3,10 @@ use std::fmt; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_middle::traits::query::NoSolution; -use rustc_middle::ty::{TyCtxt, TypeFoldable}; +use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::traverse::AlwaysTraversable; use rustc_span::Span; +use rustc_type_ir::traverse::OptTryFoldWith; use tracing::info; use crate::infer::InferCtxt; @@ -29,7 +31,7 @@ impl CustomTypeOp { impl<'tcx, F, R> super::TypeOp<'tcx> for CustomTypeOp where F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result, - R: fmt::Debug + TypeFoldable>, + R: fmt::Debug + OptTryFoldWith>, { type Output = R; /// We can't do any custom error reporting for `CustomTypeOp`, so @@ -67,7 +69,7 @@ pub fn scrape_region_constraints<'tcx, Op, R>( span: Span, ) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed> where - R: TypeFoldable>, + R: OptTryFoldWith>, Op: super::TypeOp<'tcx, Output = R>, { // During NLL, we expect that nobody will register region @@ -97,7 +99,7 @@ where })?; // Next trait solver performs operations locally, and normalize goals should resolve vars. - let value = infcx.resolve_vars_if_possible(value); + let value = infcx.resolve_vars_if_possible(AlwaysTraversable(value)).0; let region_obligations = infcx.take_registered_region_obligations(); let region_constraint_data = infcx.take_and_reset_region_constraints(); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index a618d96ce9507..66d349ff51823 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -6,6 +6,7 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_span::Span; +use rustc_type_ir::traverse::OptTryFoldWith; use crate::infer::canonical::{ CanonicalQueryInput, CanonicalQueryResponse, Certainty, OriginalQueryValues, @@ -62,7 +63,7 @@ pub struct TypeOpOutput<'tcx, Op: TypeOp<'tcx>> { /// /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 'tcx { - type QueryResponse: TypeFoldable>; + type QueryResponse: OptTryFoldWith>; /// Give query the option for a simple fast path that never /// actually hits the tcx cache lookup etc. Return `Some(r)` with diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index fb0637fcac7fa..40fba75cc90a1 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -14,7 +14,7 @@ use crate::data_structures::SsoHashSet; use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::inherent::*; use crate::lift::Lift; -use crate::traverse::{ImportantTypeTraversal, TypeTraversable}; +use crate::traverse::{ImportantTypeTraversal, OptVisitWith, TypeTraversable}; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use crate::{self as ty, Interner}; @@ -186,14 +186,14 @@ impl Binder { Binder { value: &self.value, bound_vars: self.bound_vars } } - pub fn map_bound_ref>(&self, f: F) -> Binder + pub fn map_bound_ref>(&self, f: F) -> Binder where F: FnOnce(&T) -> U, { self.as_ref().map_bound(f) } - pub fn map_bound>(self, f: F) -> Binder + pub fn map_bound>(self, f: F) -> Binder where F: FnOnce(T) -> U, { @@ -201,7 +201,7 @@ impl Binder { let value = f(value); if cfg!(debug_assertions) { let mut validator = ValidateBoundVars::new(bound_vars); - value.visit_with(&mut validator); + OptVisitWith::mk_visit_with()(&value, &mut validator); } Binder { value, bound_vars } } diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 7a8c612057fa2..29b2b67b632bb 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -5,7 +5,9 @@ use derive_where::derive_where; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + Lift_Generic, NoopTypeTraversable_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::{self as ty, DebruijnIndex, Interner}; @@ -77,6 +79,7 @@ impl UnevaluatedConst { rustc_index::newtype_index! { /// A **`const`** **v**ariable **ID**. + #[derive(NoopTypeTraversable_Generic)] #[encodable] #[orderable] #[debug_format = "?{}c"] @@ -92,6 +95,7 @@ rustc_index::newtype_index! { /// relate an effect variable with a normal one, we would ICE, which can catch bugs /// where we are not correctly using the effect var for an effect param. Fallback /// is also implemented on top of having separate effect and normal const variables. + #[derive(NoopTypeTraversable_Generic)] #[encodable] #[orderable] #[debug_format = "?{}e"] @@ -100,7 +104,7 @@ rustc_index::newtype_index! { } /// An inference variable for a const, for use in const generics. -#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, NoopTypeTraversable_Generic)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum InferConst { /// Infer the value of the const. diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 409f458cdeeba..81d4c74853792 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -75,6 +75,7 @@ pub use opaque_ty::*; pub use predicate::*; pub use predicate_kind::*; pub use region_kind::*; +use rustc_type_ir_macros::NoopTypeTraversable_Generic; pub use traverse::{fold, visit}; pub use ty_info::*; pub use ty_kind::*; @@ -379,6 +380,7 @@ impl Default for UniverseIndex { rustc_index::newtype_index! { #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] + #[derive(NoopTypeTraversable_Generic)] #[encodable] #[orderable] #[debug_format = "{}"] diff --git a/compiler/rustc_type_ir/src/traverse/mod.rs b/compiler/rustc_type_ir/src/traverse/mod.rs index c389c4fab2654..b732bc11925fb 100644 --- a/compiler/rustc_type_ir/src/traverse/mod.rs +++ b/compiler/rustc_type_ir/src/traverse/mod.rs @@ -10,10 +10,14 @@ use std::fmt; use fold::{FallibleTypeFolder, TypeFoldable}; use rustc_ast_ir::visit::VisitorResult; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use visit::{TypeVisitable, TypeVisitor}; use crate::Interner; +#[derive(Debug, Clone, TypeVisitable_Generic, TypeFoldable_Generic)] +pub struct AlwaysTraversable(pub T); + /// A trait which allows the compiler to reason about the disjointness /// of `TypeVisitable` and `NoopTypeTraversable`. /// @@ -23,7 +27,7 @@ pub trait TypeTraversable: fmt::Debug + Clone { type Kind; #[inline(always)] - fn noop_visit>(&self, _: &mut V) -> V::Result + fn noop_visit_with>(&self, _: &mut V) -> V::Result where Self: TypeTraversable, { diff --git a/compiler/rustc_type_ir/src/traverse/visit.rs b/compiler/rustc_type_ir/src/traverse/visit.rs index 3f8bb32e1c826..ebba04cfc0407 100644 --- a/compiler/rustc_type_ir/src/traverse/visit.rs +++ b/compiler/rustc_type_ir/src/traverse/visit.rs @@ -221,13 +221,13 @@ impl> TypeVisitable for ThinVec { } } -impl> TypeTraversable for &[T] { - type Kind = ImportantTypeTraversal; +impl> TypeTraversable for &[T] { + type Kind = T::Kind; } -impl> TypeVisitable for &[T] { +impl> TypeVisitable for &[T] { fn visit_with>(&self, visitor: &mut V) -> V::Result { for elem in self.iter() { - try_visit!(OptVisitWith::mk_visit_with()(elem, visitor)); + try_visit!(elem.visit_with(visitor)); } V::Result::output() }