diff --git a/Cargo.lock b/Cargo.lock index 61f2cfb9e22c4..5797cd6fa3b84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4693,6 +4693,7 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", + "rustc_type_ir", "smallvec", "tracing", ] @@ -4803,6 +4804,7 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", + "rustc_type_ir", "smallvec", "tracing", ] @@ -5300,6 +5302,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", + "rustc_type_ir", "scoped-tls", "sha1", "sha2", @@ -5338,6 +5341,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", + "rustc_type_ir", "serde_json", "tracing", ] @@ -5369,6 +5373,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_transmute", + "rustc_type_ir", "smallvec", "tracing", ] @@ -5405,6 +5410,7 @@ dependencies = [ "rustc_middle", "rustc_span", "rustc_target", + "rustc_type_ir", "tracing", ] diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7c88205da3b9a..7d6389c7bb323 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -14,8 +14,9 @@ use rustc_infer::traits::ObligationCause; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, - FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, - ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, + FakeReadCause, FakeReadCauseAndPlace, LocalDecl, LocalInfo, LocalKind, Location, Operand, + Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, + VarBindingForm, }; use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty}; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; @@ -670,8 +671,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; // Find out if the predicates show that the type is a Fn or FnMut - let find_fn_kind_from_did = |(pred, _): (ty::Predicate<'tcx>, _)| { - if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred.kind().skip_binder() + let find_fn_kind_from_did = |pred: ty::Spanned>| { + if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred.node.kind().skip_binder() && pred.self_ty() == ty { if Some(pred.def_id()) == tcx.lang_items().fn_trait() { @@ -2578,9 +2579,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) { match statement { - Statement { kind: StatementKind::FakeRead(box (cause, place)), .. } - if *place == self.place => - { + Statement { + kind: StatementKind::FakeRead(box FakeReadCauseAndPlace(cause, place)), + .. + } if *place == self.place => { self.cause = Some(*cause); } _ => (), diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 62b3f3ecfc32f..f25bd3042176d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -6,8 +6,8 @@ use rustc_hir::intravisit::Visitor; use rustc_index::vec::IndexVec; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::{ - Body, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, Operand, Place, - Rvalue, Statement, StatementKind, TerminatorKind, + Body, CastKind, ConstraintCategory, FakeReadCause, FakeReadCauseAndPlace, Local, LocalInfo, + Location, Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind, }; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::{self, RegionVid, TyCtxt}; @@ -482,7 +482,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let block = &self.body.basic_blocks[location.block]; let kind = if let Some(&Statement { - kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), place)), + kind: + StatementKind::FakeRead(box FakeReadCauseAndPlace( + FakeReadCause::ForLet(_), + place, + )), .. }) = block.statements.get(location.statement_index) { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 611abb01238b8..d09781ce1b026 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -9,8 +9,9 @@ use rustc_hir::GeneratorKind; use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt}; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ - AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand, - Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, + AggregateKind, Constant, FakeReadCause, FakeReadCauseAndPlace, Field, Local, LocalInfo, + LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, + StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; @@ -818,7 +819,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // StatementKind::FakeRead only contains a def_id if they are introduced as a result // of pattern matching within a closure. - if let StatementKind::FakeRead(box (cause, place)) = stmt.kind { + if let StatementKind::FakeRead(box FakeReadCauseAndPlace(cause, place)) = stmt.kind { match cause { FakeReadCause::ForMatchedPlace(Some(closure_def_id)) | FakeReadCause::ForLet(Some(closure_def_id)) => { diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 3662bec0c7636..dd465ad5bd748 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -103,7 +103,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // opt_match_place is None for let [mut] x = ... statements, // whether or not the right-hand side is a place expression if let LocalInfo::User(BindingForm::Var(VarBindingForm { - opt_match_place: Some((opt_match_place, match_span)), + opt_match_place: + Some(ty::Spanned { node: opt_match_place, span: match_span }), binding_mode: _, opt_ty_info: _, pat_span: _, diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index a71c416328611..378dd1e5dab43 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -62,7 +62,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.mutate_place(location, *lhs, Shallow(None)); } - StatementKind::FakeRead(box (_, _)) => { + StatementKind::FakeRead(_) => { // Only relevant for initialized/liveness/safety checks. } StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 5e77f6b190a69..4fe9a48e2b03e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -30,8 +30,8 @@ use rustc_infer::infer::{ }; use rustc_macros::fluent_messages; use rustc_middle::mir::{ - traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand, - Place, PlaceElem, PlaceRef, VarDebugInfoContents, + traversal, Body, ClearCrossCrate, FakeReadCauseAndPlace, Local, Location, Mutability, + NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, VarDebugInfoContents, }; use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; @@ -663,7 +663,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx self.mutate_place(location, (*lhs, span), Shallow(None), flow_state); } - StatementKind::FakeRead(box (_, place)) => { + StatementKind::FakeRead(box FakeReadCauseAndPlace(_, place)) => { // Read for match doesn't access any memory and is used to // assert that a place is safe and live. So we don't have to // do any checks here. diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index b27d5d2053213..07c25e0f02822 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -107,10 +107,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { instantiated_predicates: ty::InstantiatedPredicates<'tcx>, locations: Locations, ) { - for (predicate, span) in instantiated_predicates { - debug!(?predicate); - let category = ConstraintCategory::Predicate(span); - let predicate = self.normalize_with_category(predicate, locations, category); + for predicate in instantiated_predicates { + debug!(?predicate.node); + let category = ConstraintCategory::Predicate(predicate.span); + let predicate = self.normalize_with_category(predicate.node, locations, category); self.prove_predicate(predicate, locations, category); } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 53fef4d75bf67..ce5c51c450ef8 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1247,7 +1247,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } } - StatementKind::AscribeUserType(box (place, projection), variance) => { + StatementKind::AscribeUserType(box AscribeUserType(place, projection), variance) => { let place_ty = place.ty(body, tcx).ty; if let Err(terr) = self.relate_type_and_user_type( place_ty, diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index d39bf700035f9..cc771e80d9ffe 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -451,13 +451,13 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { loop { let scope_data = &self.mir.source_scopes[source_info.scope]; - if let Some((callee, callsite_span)) = scope_data.inlined { + if let Some(callee) = scope_data.inlined { // Stop inside the most nested non-`#[track_caller]` function, // before ever reaching its caller (which is irrelevant). - if !callee.def.requires_caller_location(self.tcx) { + if !callee.node.def.requires_caller_location(self.tcx) { return span_to_caller_location(self, source_info.span); } - source_info.span = callsite_span; + source_info.span = callee.span; } // Skip past all of the parents with `inlined: None`. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 99e4ded62f1a7..cbd747ffcb315 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -87,13 +87,13 @@ fn make_mir_scope<'ll, 'tcx>( let file_metadata = file_metadata(cx, &loc.file); let dbg_scope = match scope_data.inlined { - Some((callee, _)) => { + Some(callee) => { // FIXME(eddyb) this would be `self.monomorphize(&callee)` // if this is moved to `rustc_codegen_ssa::mir::debuginfo`. let callee = cx.tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - callee, + callee.node, ); let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty()); cx.dbg_scope_fn(callee, callee_fn_abi, None) @@ -109,11 +109,11 @@ fn make_mir_scope<'ll, 'tcx>( }, }; - let inlined_at = scope_data.inlined.map(|(_, callsite_span)| { + let inlined_at = scope_data.inlined.map(|callee| { // FIXME(eddyb) this doesn't account for the macro-related // `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does. - let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span); - cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span) + let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callee.span); + cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callee.span) }); debug_context.scopes[scope] = DebugScope { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index bdfc0aa1c30c7..196619c8f7b4f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1497,13 +1497,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { loop { let scope_data = &self.mir.source_scopes[source_info.scope]; - if let Some((callee, callsite_span)) = scope_data.inlined { + if let Some(callee) = scope_data.inlined { // Stop inside the most nested non-`#[track_caller]` function, // before ever reaching its caller (which is irrelevant). - if !callee.def.requires_caller_location(tcx) { + if !callee.node.def.requires_caller_location(tcx) { return span_to_caller_location(source_info.span); } - source_info.span = callsite_span; + source_info.span = callee.span; } // Skip past all of the parents with `inlined: None`. diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 76c8d0a975ac0..7fd2000a718c2 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -44,13 +44,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { loop { let scope_data = &frame.body.source_scopes[source_info.scope]; - if let Some((callee, callsite_span)) = scope_data.inlined { + if let Some(callee) = scope_data.inlined { // Stop inside the most nested non-`#[track_caller]` function, // before ever reaching its caller (which is irrelevant). - if !callee.def.requires_caller_location(*self.tcx) { + if !callee.node.def.requires_caller_location(*self.tcx) { return source_info.span; } - source_info.span = callsite_span; + source_info.span = callee.span; } // Skip past all of the parents with `inlined: None`. diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index ba94f3776eb90..0dee7ccefb312 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs @@ -24,6 +24,10 @@ mod private { #[rustc_pass_by_value] pub struct Interned<'a, T>(pub &'a T, pub private::PrivateZst); +pub trait Internable<'a, I>: Sized { + fn intern(self, interner: I) -> Interned<'a, Self>; +} + impl<'a, T> Interned<'a, T> { /// Create a new `Interned` value. The value referred to *must* be interned /// and thus be unique, and it *must* remain unique in the future. This diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 129f8d235adbc..e15a84329325c 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -15,6 +15,7 @@ rustc_index = { path = "../rustc_index" } rustc_span = { path = "../rustc_span" } rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } +rustc_type_ir = { path = "../rustc_type_ir" } tracing = "0.1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } odht = { version = "0.3.1", features = ["nightly"] } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f4b46b9a131fb..123112a17623d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3190,7 +3190,10 @@ impl<'hir> Item<'hir> { } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(Encodable, Decodable, HashStable_Generic)] +#[derive(Encodable, Decodable, HashStable_Generic, TypeFoldable, TypeVisitable)] +#[skip_traversal(but_impl_because = " + `Unsafety` impls `Relate`, which is a subtrait of `TypeFoldable`. +")] pub enum Unsafety { Unsafe, Normal, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 6a27383121d2d..d1f30429da153 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1314,20 +1314,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut trait_bounds = vec![]; let mut projection_bounds = vec![]; - for (pred, span) in bounds.predicates() { - let bound_pred = pred.kind(); + for pred in bounds.predicates() { + let bound_pred = pred.node.kind(); match bound_pred.skip_binder() { ty::PredicateKind::Clause(clause) => match clause { ty::Clause::Trait(trait_pred) => { assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive); trait_bounds.push(( bound_pred.rebind(trait_pred.trait_ref), - span, + pred.span, trait_pred.constness, )); } ty::Clause::Projection(proj) => { - projection_bounds.push((bound_pred.rebind(proj), span)); + projection_bounds.push((bound_pred.rebind(proj), pred.span)); } ty::Clause::TypeOutlives(_) => { // Do nothing, we deal with regions separately @@ -1784,8 +1784,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { || { traits::transitive_bounds_that_define_assoc_type( tcx, - predicates.iter().filter_map(|(p, _)| { - Some(p.to_opt_poly_trait_pred()?.map_bound(|t| t.trait_ref)) + predicates.iter().filter_map(|p| { + Some(p.node.to_opt_poly_trait_pred()?.map_bound(|t| t.trait_ref)) }), assoc_name, ) diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 0880c8c15f2e0..bdae0ca8d293b 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -23,7 +23,7 @@ use rustc_span::Span; /// include the self type (e.g., `trait_bounds`) but in others we do not #[derive(Default, PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { - pub predicates: Vec<(ty::Predicate<'tcx>, Span)>, + pub predicates: Vec>>, } impl<'tcx> Bounds<'tcx> { @@ -33,7 +33,7 @@ impl<'tcx> Bounds<'tcx> { region: ty::PolyTypeOutlivesPredicate<'tcx>, span: Span, ) { - self.predicates.push((region.to_predicate(tcx), span)); + self.predicates.push(ty::Spanned { node: region.to_predicate(tcx), span }); } pub fn push_trait_bound( @@ -43,7 +43,10 @@ impl<'tcx> Bounds<'tcx> { span: Span, constness: ty::BoundConstness, ) { - self.predicates.push((trait_ref.with_constness(constness).to_predicate(tcx), span)); + self.predicates.push(ty::Spanned { + node: trait_ref.with_constness(constness).to_predicate(tcx), + span, + }); } pub fn push_projection_bound( @@ -52,17 +55,18 @@ impl<'tcx> Bounds<'tcx> { projection: ty::PolyProjectionPredicate<'tcx>, span: Span, ) { - self.predicates.push((projection.to_predicate(tcx), span)); + self.predicates.push(ty::Spanned { node: projection.to_predicate(tcx), span }); } pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized_def_id, [ty])); // Preferrable to put this obligation first, since we report better errors for sized ambiguity. - self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span)); + self.predicates + .insert(0, ty::Spanned { node: trait_ref.without_const().to_predicate(tcx), span }); } - pub fn predicates(&self) -> impl Iterator, Span)> + '_ { + pub fn predicates(&self) -> impl Iterator>> + '_ { self.predicates.iter().cloned() } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 872fec3954b29..976c6f6d8b4e4 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -320,7 +320,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( let prohibit_opaque = tcx .explicit_item_bounds(def_id) .iter() - .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor)); + .try_for_each(|predicate| predicate.node.visit_with(&mut visitor)); if let Some(ty) = prohibit_opaque.break_value() { visitor.visit_item(&item); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 32b6aeed5f8cc..5a2129af18f56 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -187,7 +187,7 @@ fn compare_method_predicate_entailment<'tcx>( hybrid_preds.predicates.extend( trait_m_predicates .instantiate_own(tcx, trait_to_placeholder_substs) - .map(|(predicate, _)| predicate), + .map(|predicate| predicate.node), ); // Construct trait parameter environment and then shift it into the placeholder viewpoint. @@ -207,7 +207,7 @@ fn compare_method_predicate_entailment<'tcx>( debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds()); let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs); - for (predicate, span) in impl_m_own_bounds { + for ty::Spanned { node: predicate, span } in impl_m_own_bounds { let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); let predicate = ocx.normalize(&normalize_cause, param_env, predicate); @@ -846,7 +846,7 @@ impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { }); self.types.insert(proj.def_id, (infer_ty, proj.substs)); // Recurse into bounds - for (pred, pred_span) in self.interner().bound_explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) { + for ty::Spanned { node: pred, span: pred_span } in self.interner().bound_explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( &ObligationCause::misc(self.span, self.body_id), @@ -1804,7 +1804,7 @@ fn compare_type_predicate_entailment<'tcx>( hybrid_preds.predicates.extend( trait_ty_predicates .instantiate_own(tcx, trait_to_impl_substs) - .map(|(predicate, _)| predicate), + .map(|predicate| predicate.node), ); debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds); @@ -1822,7 +1822,7 @@ fn compare_type_predicate_entailment<'tcx>( debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds()); - for (predicate, span) in impl_ty_own_bounds { + for ty::Spanned { node: predicate, span } in impl_ty_own_bounds { let cause = ObligationCause::misc(span, impl_ty_def_id); let predicate = ocx.normalize(&cause, param_env, predicate); @@ -2043,9 +2043,14 @@ pub(super) fn check_type_bounds<'tcx>( let obligations = tcx .bound_explicit_item_bounds(trait_ty.def_id) .subst_iter_copied(tcx, rebased_substs) - .map(|(concrete_ty_bound, span)| { - debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); - traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) + .map(|concrete_ty_bound| { + debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound.node); + traits::Obligation::new( + tcx, + mk_cause(concrete_ty_bound.span), + param_env, + concrete_ty_bound.node, + ) }) .collect(); debug!("check_type_bounds: item_bounds={:?}", obligations); diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 2bb724138f584..8d30c3f7826a5 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -155,7 +155,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( // just to look for all the predicates directly. assert_eq!(dtor_predicates.parent, None); - for &(predicate, predicate_sp) in dtor_predicates.predicates { + for &ty::Spanned { node: predicate, span: predicate_sp } in dtor_predicates.predicates { // (We do not need to worry about deep analysis of type // expressions etc because the Drop impls are already forced // to take on a structure that is roughly an alpha-renaming of diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 9acfc1b3d2924..267be0430249a 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -302,9 +302,9 @@ fn bounds_from_generic_predicates<'tcx>( ) -> (String, String) { let mut types: FxHashMap, Vec> = FxHashMap::default(); let mut projections = vec![]; - for (predicate, _) in predicates.predicates { - debug!("predicate {:?}", predicate); - let bound_predicate = predicate.kind(); + for predicate in predicates.predicates { + debug!("predicate {:?}", predicate.node); + let bound_predicate = predicate.node.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { let entry = types.entry(trait_predicate.self_ty()).or_default(); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 4120ad45f6a6b..837378762f875 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1134,14 +1134,14 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); - let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { - let normalized_bound = wfcx.normalize(span, None, bound); + let wf_obligations = bounds.iter().flat_map(|&bound| { + let normalized_bound = wfcx.normalize(span, None, bound.node); traits::wf::predicate_obligations( wfcx.infcx, wfcx.param_env, wfcx.body_def_id, normalized_bound, - bound_span, + bound.span, ) }); @@ -1377,7 +1377,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let default_obligations = predicates .predicates .iter() - .flat_map(|&(pred, sp)| { + .flat_map(|&pred| { #[derive(Default)] struct CountParams { params: FxHashSet, @@ -1404,18 +1404,18 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id } } let mut param_count = CountParams::default(); - let has_region = pred.visit_with(&mut param_count).is_break(); - let substituted_pred = ty::EarlyBinder(pred).subst(tcx, substs); + let has_region = pred.node.visit_with(&mut param_count).is_break(); + let substituted_pred = ty::EarlyBinder(pred.node).subst(tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region { None - } else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { + } else if predicates.predicates.iter().any(|&p| p.node == substituted_pred) { // Avoid duplication of predicates that contain no parameters, for example. None } else { - Some((substituted_pred, sp)) + Some((substituted_pred, pred.span)) } }) .map(|(pred, sp)| { @@ -1443,13 +1443,13 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id debug!(?predicates.predicates); assert_eq!(predicates.predicates.len(), predicates.spans.len()); - let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| { + let wf_obligations = predicates.into_iter().flat_map(|p| { traits::wf::predicate_obligations( infcx, wfcx.param_env.without_const(), wfcx.body_def_id, - p, - sp, + p.node, + p.span, ) }); let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect(); @@ -1566,7 +1566,7 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>( { let span = tcx.def_span(opaque_ty.def_id); let bounds = wfcx.tcx().explicit_item_bounds(opaque_ty.def_id); - let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { + let wf_obligations = bounds.iter().flat_map(|&ty::Spanned { node: bound, span: bound_span }| { let bound = ty::EarlyBinder(bound).subst(tcx, opaque_ty.substs); let normalized_bound = wfcx.normalize(span, None, bound); traits::wf::predicate_obligations( diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 604d54cafb532..6c9db1c18bc5d 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1448,8 +1448,9 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate "predicates_defined_on: inferred_outlives_of({:?}) = {:?}", def_id, inferred_outlives, ); - let inferred_outlives_iter = - inferred_outlives.iter().map(|(clause, span)| ((*clause).to_predicate(tcx), *span)); + let inferred_outlives_iter = inferred_outlives + .iter() + .map(|(clause, span)| ty::Spanned { node: (*clause).to_predicate(tcx), span: *span }); if result.predicates.is_empty() { result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter); } else { diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index df0258ff7a36c..620d88582a067 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -19,7 +19,7 @@ fn associated_type_bounds<'tcx>( assoc_item_def_id: DefId, ast_bounds: &'tcx [hir::GenericBound<'tcx>], span: Span, -) -> &'tcx [(ty::Predicate<'tcx>, Span)] { +) -> &'tcx [ty::Spanned>] { let item_ty = tcx.mk_projection( assoc_item_def_id, InternalSubsts::identity_for_item(tcx, assoc_item_def_id), @@ -33,15 +33,17 @@ fn associated_type_bounds<'tcx>( let trait_def_id = tcx.parent(assoc_item_def_id); let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local()); - let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| { - match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Trait(tr)) => tr.self_ty() == item_ty, - ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => { - proj.projection_ty.self_ty() == item_ty - } - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(outlives)) => outlives.0 == item_ty, - _ => false, + let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|pred| match pred + .node + .kind() + .skip_binder() + { + ty::PredicateKind::Clause(ty::Clause::Trait(tr)) => tr.self_ty() == item_ty, + ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => { + proj.projection_ty.self_ty() == item_ty } + ty::PredicateKind::Clause(ty::Clause::TypeOutlives(outlives)) => outlives.0 == item_ty, + _ => false, }); let all_bounds = tcx.arena.alloc_from_iter(bounds.predicates().chain(bounds_from_parent)); @@ -60,7 +62,7 @@ fn opaque_type_bounds<'tcx>( ast_bounds: &'tcx [hir::GenericBound<'tcx>], item_ty: Ty<'tcx>, span: Span, -) -> &'tcx [(ty::Predicate<'tcx>, Span)] { +) -> &'tcx [ty::Spanned>] { ty::print::with_no_queries!({ let icx = ItemCtxt::new(tcx, opaque_def_id); let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds); @@ -75,7 +77,7 @@ fn opaque_type_bounds<'tcx>( pub(super) fn explicit_item_bounds( tcx: TyCtxt<'_>, def_id: DefId, -) -> &'_ [(ty::Predicate<'_>, Span)] { +) -> &'_ [ty::Spanned>] { match tcx.opt_rpitit_info(def_id) { // RPITIT's bounds are the same as opaque type bounds, but with // a projection self type. @@ -126,7 +128,7 @@ pub(super) fn item_bounds( let bounds = tcx.mk_predicates_from_iter( util::elaborate_predicates( tcx, - tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound), + tcx.explicit_item_bounds(def_id).iter().map(|&bound| bound.node), ) .map(|obligation| obligation.predicate), ); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 2badd66e346f1..c079896396674 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericPredicates, ToPredicate}; use rustc_span::symbol::{sym, Ident}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::DUMMY_SP; #[derive(Debug)] struct OnlySelfBounds(bool); @@ -49,11 +49,13 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic }; let span = rustc_span::DUMMY_SP; - result.predicates = - tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( - ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx), + result.predicates = tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain( + std::iter::once(ty::Spanned { + node: + ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx), span, - )))); + }), + )); } debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); result @@ -77,7 +79,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP // We use an `IndexSet` to preserve order of insertion. // Preserving the order of insertion is important here so as not to break UI tests. - let mut predicates: FxIndexSet<(ty::Predicate<'_>, Span)> = FxIndexSet::default(); + let mut predicates: FxIndexSet>> = FxIndexSet::default(); let ast_generics = match node { Node::TraitItem(item) => item.generics, @@ -136,7 +138,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP // (see below). Recall that a default impl is not itself an impl, but rather a // set of defaults that can be incorporated into another impl. if let Some(trait_ref) = is_default_impl_trait { - predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id))); + predicates.insert(ty::Spanned { + node: trait_ref.without_const().to_predicate(tcx), + span: tcx.def_span(def_id), + }); } // Collect the region predicates that were declared inline as @@ -187,7 +192,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP ty::Clause::ConstArgHasType(ct, ct_ty), )) .to_predicate(tcx); - predicates.insert((predicate, param.span)); + predicates.insert(ty::Spanned { node: predicate, span: param.span }); index += 1; } @@ -219,7 +224,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP ty::PredicateKind::WellFormed(ty.into()), bound_vars, ); - predicates.insert((predicate.to_predicate(tcx), span)); + predicates.insert(ty::Spanned { node: predicate.to_predicate(tcx), span }); } } @@ -242,7 +247,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP )) .to_predicate(icx.tcx); - (pred, span) + ty::Spanned { node: pred, span } })) } @@ -302,20 +307,20 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP index: dup_index, name: duplicate.name.ident().name, }); - predicates.push(( - ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::RegionOutlives( + predicates.push(ty::Spanned { + node: ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::RegionOutlives( ty::OutlivesPredicate(orig_region, dup_region), ))) .to_predicate(icx.tcx), - duplicate.span, - )); - predicates.push(( - ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::RegionOutlives( + span: duplicate.span, + }); + predicates.push(ty::Spanned { + node: ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::RegionOutlives( ty::OutlivesPredicate(dup_region, orig_region), ))) .to_predicate(icx.tcx), - duplicate.span, - )); + span: duplicate.span, + }); } debug!(?predicates); } @@ -329,10 +334,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP fn const_evaluatable_predicates_of( tcx: TyCtxt<'_>, def_id: LocalDefId, -) -> FxIndexSet<(ty::Predicate<'_>, Span)> { +) -> FxIndexSet>> { struct ConstCollector<'tcx> { tcx: TyCtxt<'tcx>, - preds: FxIndexSet<(ty::Predicate<'tcx>, Span)>, + preds: FxIndexSet>>, } impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> { @@ -340,11 +345,11 @@ fn const_evaluatable_predicates_of( let ct = ty::Const::from_anon_const(self.tcx, c.def_id); if let ty::ConstKind::Unevaluated(_) = ct.kind() { let span = self.tcx.def_span(c.def_id); - self.preds.insert(( - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct)) + self.preds.insert(ty::Spanned { + node: ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct)) .to_predicate(self.tcx), span, - )); + }); } } @@ -428,7 +433,7 @@ pub(super) fn explicit_predicates_of<'tcx>( .predicates .iter() .copied() - .filter(|(pred, _)| match pred.kind().skip_binder() { + .filter(|pred| match pred.node.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(tr)) => !is_assoc_item_ty(tr.self_ty()), ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => { !is_assoc_item_ty(proj.projection_ty.self_ty()) @@ -475,9 +480,9 @@ pub(super) fn explicit_predicates_of<'tcx>( let filtered_predicates = parent_preds .predicates .into_iter() - .filter(|(pred, _)| { + .filter(|pred| { if let ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, _)) = - pred.kind().skip_binder() + pred.node.kind().skip_binder() { match ct.kind() { ty::ConstKind::Param(param_const) => { @@ -598,12 +603,12 @@ pub(super) fn super_predicates_that_define_assoc_type( if assoc_name.is_none() { // Now require that immediate supertraits are converted, // which will, in turn, reach indirect supertraits. - for &(pred, span) in superbounds { - debug!("superbound: {:?}", pred); + for &pred in superbounds { + debug!("superbound: {:?}", pred.node); if let ty::PredicateKind::Clause(ty::Clause::Trait(bound)) = - pred.kind().skip_binder() + pred.node.kind().skip_binder() { - tcx.at(span).super_predicates_of(bound.def_id()); + tcx.at(pred.span).super_predicates_of(bound.def_id()); } } } @@ -674,8 +679,10 @@ pub(super) fn type_param_predicates( // Implied `Self: Trait` and supertrait bounds. if param_id == item_hir_id { let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); - extend = - Some((identity_trait_ref.without_const().to_predicate(tcx), item.span)); + extend = Some(ty::Spanned { + node: identity_trait_ref.without_const().to_predicate(tcx), + span: item.span, + }); } generics } @@ -701,7 +708,7 @@ pub(super) fn type_param_predicates( Some(assoc_name), ) .into_iter() - .filter(|(predicate, _)| match predicate.kind().skip_binder() { + .filter(|predicate| match predicate.node.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(data)) => data.self_ty().is_param(index), _ => false, }), @@ -724,7 +731,7 @@ impl<'tcx> ItemCtxt<'tcx> { ty: Ty<'tcx>, only_self_bounds: OnlySelfBounds, assoc_name: Option, - ) -> Vec<(ty::Predicate<'tcx>, Span)> { + ) -> Vec>> { ast_generics .predicates .iter() @@ -779,7 +786,7 @@ fn predicates_from_bound<'tcx>( param_ty: Ty<'tcx>, bound: &'tcx hir::GenericBound<'tcx>, bound_vars: &'tcx ty::List, -) -> Vec<(ty::Predicate<'tcx>, Span)> { +) -> Vec>> { let mut bounds = Bounds::default(); astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars); bounds.predicates().collect() diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 465ae047de373..6468f1bedb326 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1700,8 +1700,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } let predicates = tcx.super_predicates_that_define_assoc_type((def_id, Some(assoc_name))); - let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| { - let bound_predicate = pred.kind(); + let obligations = predicates.predicates.iter().filter_map(|&pred| { + let bound_predicate = pred.node.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(data)) => { // The order here needs to match what we would get from `subst_supertrait` diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index e18b0f082798b..5f4432c80dd7f 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -1,7 +1,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::source_map::Span; use std::ops::ControlFlow; #[derive(Clone, PartialEq, Eq, Hash, Debug)] @@ -151,7 +150,7 @@ pub fn identify_constrained_generic_params<'tcx>( /// think of any. pub fn setup_constraining_predicates<'tcx>( tcx: TyCtxt<'tcx>, - predicates: &mut [(ty::Predicate<'tcx>, Span)], + predicates: &mut [ty::Spanned>], impl_trait_ref: Option>, input_parameters: &mut FxHashSet, ) { @@ -188,7 +187,7 @@ pub fn setup_constraining_predicates<'tcx>( // Note that we don't have to care about binders here, // as the impl trait ref never contains any late-bound regions. if let ty::PredicateKind::Clause(ty::Clause::Projection(projection)) = - predicates[j].0.kind().skip_binder() + predicates[j].node.kind().skip_binder() { // Special case: watch out for some kind of sneaky attempt // to project out an associated type defined by this very diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 58dd03811f78c..f82dfc68f4008 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -212,9 +212,9 @@ fn unconstrained_parent_impl_substs<'tcx>( // what we want here. We want only a list of constrained parameters while // the functions in `cgp` add the constrained parameters to a list of // unconstrained parameters. - for (predicate, _) in impl_generic_predicates.predicates.iter() { + for predicate in impl_generic_predicates.predicates.iter() { if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = - predicate.kind().skip_binder() + predicate.node.kind().skip_binder() { let projection_ty = proj.projection_ty; let projected_ty = proj.term; @@ -324,9 +324,10 @@ fn check_predicates<'tcx>( instantiated.predicates, // Don't drop predicates (unsound!) because `spans` is too short instantiated.spans.into_iter().chain(std::iter::repeat(span)), - ), + ) + .map(|(node, span)| ty::Spanned { node, span }), ) - .map(|obligation| (obligation.predicate, obligation.cause.span)) + .map(|obligation| ty::Spanned { node: obligation.predicate, span: obligation.cause.span }) .collect(); let mut impl2_predicates = if impl2_node.is_from_trait() { @@ -361,9 +362,9 @@ fn check_predicates<'tcx>( // which is sound because we forbid impls like the following // // impl AlwaysApplicable for D { } - let always_applicable_traits = impl1_predicates.iter().copied().filter(|&(predicate, _)| { + let always_applicable_traits = impl1_predicates.iter().copied().filter(|&predicate| { matches!( - trait_predicate_kind(tcx, predicate), + trait_predicate_kind(tcx, predicate.node), Some(TraitSpecializationKind::AlwaysApplicable) ) }); @@ -385,9 +386,12 @@ fn check_predicates<'tcx>( .map(|obligation| obligation.predicate), ); - for (predicate, span) in impl1_predicates { - if !impl2_predicates.iter().any(|pred2| trait_predicates_eq(tcx, predicate, *pred2, span)) { - check_specialization_on(tcx, predicate, span) + for predicate in impl1_predicates { + if !impl2_predicates + .iter() + .any(|pred2| trait_predicates_eq(tcx, predicate.node, *pred2, predicate.span)) + { + check_specialization_on(tcx, predicate.node, predicate.span) } } } diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index 9ee6785970c46..47c571b9b9168 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -28,8 +28,8 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { let mut required_predicates = RequiredPredicates::default(); // process predicates and convert to `RequiredPredicates` entry, see below - for &(predicate, span) in predicates.predicates { - match predicate.kind().skip_binder() { + for predicate in predicates.predicates { + match predicate.node.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::TypeOutlives(OutlivesPredicate( ty, reg, @@ -37,7 +37,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { tcx, ty.into(), reg, - span, + predicate.span, &mut required_predicates, ), @@ -48,7 +48,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { tcx, reg1.into(), reg2, - span, + predicate.span, &mut required_predicates, ), diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 361e8948e851a..96512bca4ee20 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -154,7 +154,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; let id_substs = ty::InternalSubsts::identity_for_item(tcx, item_def_id.to_def_id()); for pred in tcx.bound_explicit_item_bounds(item_def_id.to_def_id()).transpose_iter() { - let pred = pred.map_bound(|(pred, _)| *pred).subst(tcx, id_substs); + let pred = pred.map_bound(|pred| pred.node).subst(tcx, id_substs); debug!(?pred); // We only ignore opaque type substs if the opaque type is the outermost type. diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 035ccf30b2462..2a22fdd39d97a 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -528,12 +528,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } for ty in [first_ty, second_ty] { - for (pred, _) in self + for pred in self .tcx .bound_explicit_item_bounds(rpit_def_id) .subst_iter_copied(self.tcx, substs) { - let pred = pred.kind().rebind(match pred.kind().skip_binder() { + let pred = pred.node.kind().rebind(match pred.node.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => { // FIXME(rpitit): This will need to be fixed when we move to associated types assert!(matches!( diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index ecbe4a97dd967..5ab7cc2c2e239 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -385,21 +385,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) { let predicates = self.tcx.predicates_of(def_id); let predicates = predicates.instantiate(self.tcx, subst); - for (predicate, predicate_span) in predicates { + for predicate in predicates { let obligation = Obligation::new( self.tcx, ObligationCause::dummy_with_span(callee_expr.span), self.param_env, - predicate, + predicate.node, ); let result = self.evaluate_obligation(&obligation); self.tcx .sess .struct_span_err( callee_expr.span, - &format!("evaluate({:?}) = {:?}", predicate, result), + &format!("evaluate({:?}) = {:?}", predicate.node, result), ) - .span_label(predicate_span, "predicate") + .span_label(predicate.span, "predicate") .emit(); } } diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index ec391ea80f48b..3cbe4e5cc9c1c 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -186,7 +186,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates( self.tcx.mk_ty_var(self.root_var(vid)), - self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)), + self.obligations_for_self_ty(vid) + .map(|obl| ty::Spanned { node: obl.predicate, span: obl.cause.span }), ), ty::FnPtr(sig) => { let expected_sig = ExpectedSig { cause_span: None, sig }; @@ -199,7 +200,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn deduce_closure_signature_from_predicates( &self, expected_ty: Ty<'tcx>, - predicates: impl DoubleEndedIterator, Span)>, + predicates: impl DoubleEndedIterator>>, ) -> (Option>, Option) { let mut expected_sig = None; let mut expected_kind = None; @@ -712,13 +713,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .bound_explicit_item_bounds(def_id) .subst_iter_copied(self.tcx, substs) - .find_map(|(p, s)| get_future_output(p, s))?, + .find_map(|p| get_future_output(p.node, p.span))?, ty::Error(_) => return None, ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => self .tcx .bound_explicit_item_bounds(proj.def_id) .subst_iter_copied(self.tcx, proj.substs) - .find_map(|(p, s)| get_future_output(p, s))?, + .find_map(|p| get_future_output(p.node, p.span))?, _ => span_bug!( self.tcx.def_span(expr_def_id), "async fn generator return type not an inference variable: {ret_ty}" diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 29db16849dd5b..4370eb4fc7162 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -866,7 +866,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let new_cause = ObligationCause::new( cause.span, cause.body_id, - ObligationCauseCode::OpaqueReturnType(Some((return_expr_ty, span))), + ObligationCauseCode::OpaqueReturnType(Some(ty::Spanned { + node: return_expr_ty, + span, + })), ); *cause = new_cause; } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index ec14bd3c6f43e..c220cde8c09e0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -503,7 +503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Err(expr); } let relevant_broken_predicate: ty::PredicateKind<'tcx> = - impl_predicates.predicates[impl_predicate_index].0.kind().skip_binder(); + impl_predicates.predicates[impl_predicate_index].node.kind().skip_binder(); match relevant_broken_predicate { ty::PredicateKind::Clause(ty::Clause::Trait(broken_trait)) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 61338ac613aea..8f07eeca4881b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1866,13 +1866,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(compiler-errors): This could be problematic if something has two // fn-like predicates with different args, but callable types really never // do that, so it's OK. - for (predicate, span) in instantiated + for predicate in instantiated { - if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.kind().skip_binder() + if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.node.kind().skip_binder() && pred.self_ty().peel_refs() == callee_ty && self.tcx.is_fn_trait(pred.def_id()) { - err.span_note(span, "callable defined here"); + err.span_note(predicate.span, "callable defined here"); return; } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 1dea3e6f900d4..e1af9eef138b8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -228,7 +228,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { { // HACK(eddyb) should get the original `Span`. let span = tcx.def_span(def_id); - Some((predicate, span)) + Some(ty::Spanned { node: predicate, span }) } _ => None, } diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 9ecc870a70dbd..a2af1aef1a281 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -577,10 +577,10 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for &(predicate, _) in fcx.tcx.explicit_item_bounds(def) { + for &predicate in fcx.tcx.explicit_item_bounds(def) { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = - predicate.kind().skip_binder() + predicate.node.kind().skip_binder() { let def_id = poly_trait_predicate.trait_ref.def_id; let descr_pre = &format!("{}implementer{} of ", data.descr_pre, plural_suffix); diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index a0aa43deadcfd..fae75a3e80c5f 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -582,11 +582,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { { let span = predicates .iter() - .find_map( - |(p, span)| { - if p == obligation.predicate { Some(span) } else { None } - }, - ) + .find_map(|p| (p.node == obligation.predicate).then_some(p.span)) .unwrap_or(rustc_span::DUMMY_SP); Some((trait_pred, span)) } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index c36c75e444368..a53c81c1f13d3 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -561,7 +561,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (lhs, Some((true, rhs_ty, rhs_sp))) => one_side_err(rhs_sp, rhs_ty, lhs), _ => span_bug!(span, "Impossible, verified above."), } - if (lhs, rhs).references_error() { + if (lhs.map(|(_, ty, _)| ty), rhs.map(|(_, ty, _)| ty)).references_error() { err.downgrade_to_delayed_bug(); } if self.tcx.sess.teach(&err.get_code().unwrap()) { diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 02ac83a5e8b25..89d83a45e916f 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -17,4 +17,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } +rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index fd16363a1db01..acff07d90de70 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -375,8 +375,9 @@ impl<'tcx> InferCtxt<'tcx> { let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs).find_map( - |(predicate, _)| { + |predicate| { predicate + .node .kind() .map_bound(|kind| match kind { ty::PredicateKind::Clause(ty::Clause::Projection(projection_predicate)) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 7ffe1fd20b49a..26e88603bac73 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -314,9 +314,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .tcx .explicit_predicates_of(trait_item_def_id) .instantiate_own(self.tcx, trait_item_substs) - .map(|(pred, _)| { - if pred.is_suggestable(self.tcx, false) { - Ok(pred.to_string()) + .map(|pred| { + if pred.node.is_suggestable(self.tcx, false) { + Ok(pred.node.to_string()) } else { Err(()) } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 49f823a47b83d..d1501fd2b2342 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -547,8 +547,8 @@ impl<'tcx> InferCtxt<'tcx> { let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id()); - for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) { - let predicate = predicate.fold_with(&mut BottomUpFolder { + for predicate in item_bounds.subst_iter_copied(tcx, substs) { + let predicate = predicate.node.fold_with(&mut BottomUpFolder { tcx, ty_op: |ty| match *ty.kind() { // We can't normalize associated types from `rustc_infer`, diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 77c67c14ecc55..e4fe32bb181ca 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -34,7 +34,7 @@ pub use rustc_middle::traits::*; /// either identifying an `impl` (e.g., `impl Eq for i32`) that /// satisfies the obligation, or else finding a bound that is in /// scope. The eventual result is usually a `Selection` (defined below). -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] pub struct Obligation<'tcx, T> { /// The reason we have to prove this thing. pub cause: ObligationCause<'tcx>, diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 3a5273b0359e4..d823e8b78cb31 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -1,11 +1,8 @@ use crate::traits; use crate::traits::project::Normalized; -use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable}; -use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty; use std::fmt; -use std::ops::ControlFlow; // Structural impls for the structs in `traits`. @@ -57,31 +54,3 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { write!(f, "MismatchedProjectionTypes({:?})", self.err) } } - -/////////////////////////////////////////////////////////////////////////// -// TypeFoldable implementations. - -impl<'tcx, O: TypeFoldable>> TypeFoldable> - for traits::Obligation<'tcx, O> -{ - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - Ok(traits::Obligation { - cause: self.cause, - recursion_depth: self.recursion_depth, - predicate: self.predicate.try_fold_with(folder)?, - param_env: self.param_env.try_fold_with(folder)?, - }) - } -} - -impl<'tcx, O: TypeVisitable>> TypeVisitable> - for traits::Obligation<'tcx, O> -{ - fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { - self.predicate.visit_with(visitor)?; - self.param_env.visit_with(visitor) - } -} diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index c07ff51657994..5754170d05a29 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -3,9 +3,8 @@ use smallvec::smallvec; use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::traits::{self, Obligation, ObligationCause, PredicateObligation}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_middle::ty::{self, ToPredicate, TyCtxt}; +use rustc_middle::ty::{self, Spanned, ToPredicate, TyCtxt}; use rustc_span::symbol::Ident; -use rustc_span::Span; pub fn anonymize_predicate<'tcx>( tcx: TyCtxt<'tcx>, @@ -100,10 +99,10 @@ pub fn elaborate_predicates<'tcx>( pub fn elaborate_predicates_with_span<'tcx>( tcx: TyCtxt<'tcx>, - predicates: impl Iterator, Span)>, + predicates: impl Iterator>>, ) -> Elaborator<'tcx> { let obligations = predicates - .map(|(predicate, span)| { + .map(|ty::Spanned { node: predicate, span }| { predicate_obligation( predicate, ty::ParamEnv::empty(), @@ -154,8 +153,8 @@ impl<'tcx> Elaborator<'tcx> { // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); - let obligations = - predicates.predicates.iter().enumerate().map(|(index, &(mut pred, span))| { + let obligations = predicates.predicates.iter().enumerate().map( + |(index, &Spanned { node: mut pred, span })| { // when parent predicate is non-const, elaborate it to non-const predicates. if data.constness == ty::BoundConstness::NotConst { pred = pred.without_const(tcx); @@ -179,7 +178,8 @@ impl<'tcx> Elaborator<'tcx> { obligation.param_env, cause, ) - }); + }, + ); debug!(?data, ?obligations, "super_predicates"); self.extend_deduped(obligations); } @@ -362,8 +362,8 @@ pub fn transitive_bounds_that_define_assoc_type<'tcx>( trait_ref.def_id(), Some(assoc_name), )); - for (super_predicate, _) in super_predicates.predicates { - let subst_predicate = super_predicate.subst_supertrait(tcx, &trait_ref); + for super_predicate in super_predicates.predicates { + let subst_predicate = super_predicate.node.subst_supertrait(tcx, &trait_ref); if let Some(binder) = subst_predicate.to_opt_poly_trait_pred() { stack.push(binder.map_bound(|t| t.trait_ref)); } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index b1ff76865abda..3f5f046950856 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1590,8 +1590,8 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { if cx.tcx.features().trivial_bounds { let predicates = cx.tcx.predicates_of(item.owner_id); - for &(predicate, span) in predicates.predicates { - let predicate_kind_name = match predicate.kind().skip_binder() { + for &predicate in predicates.predicates { + let predicate_kind_name = match predicate.node.kind().skip_binder() { Clause(Clause::Trait(..)) => "trait", Clause(Clause::TypeOutlives(..)) | Clause(Clause::RegionOutlives(..)) => "lifetime", @@ -1614,11 +1614,11 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { Ambiguous | TypeWellFormedFromEnv(..) => continue, }; - if predicate.is_global() { + if predicate.node.is_global() { cx.emit_spanned_lint( TRIVIAL_BOUNDS, - span, - BuiltinTrivialBounds { predicate_kind_name, predicate }, + predicate.span, + BuiltinTrivialBounds { predicate_kind_name, predicate: predicate.node }, ); } } diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index c2ed0e19f4011..6d871e1b5a569 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { .super_predicates_of(def_id) .predicates .into_iter() - .filter_map(|(pred, _)| pred.to_opt_poly_trait_pred()); + .filter_map(|pred| pred.node.to_opt_poly_trait_pred()); if direct_super_traits_iter.count() > 1 { cx.emit_spanned_lint( MULTIPLE_SUPERTRAIT_UPCASTABLE, diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 883a56cb3ce6b..e31f73cb23fe5 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -70,10 +70,10 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // For every projection predicate in the opaque type's explicit bounds, // check that the type that we're assigning actually satisfies the bounds // of the associated type. - for &(pred, pred_span) in cx.tcx.explicit_item_bounds(def_id) { + for &pred in cx.tcx.explicit_item_bounds(def_id) { // Liberate bound regions in the predicate since we // don't actually care about lifetimes in this check. - let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind()); + let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.node.kind()); let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = predicate else { continue; }; @@ -95,12 +95,12 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // For example, in `impl Trait`, for all of the bounds on `Assoc`, // e.g. `type Assoc: OtherTrait`, replace `::Assoc: OtherTrait` // with `impl Send: OtherTrait`. - for (assoc_pred, assoc_pred_span) in cx + for assoc_pred_spanned in cx .tcx .bound_explicit_item_bounds(proj.projection_ty.def_id) .subst_iter_copied(cx.tcx, &proj.projection_ty.substs) { - let assoc_pred = assoc_pred.fold_with(proj_replacer); + let assoc_pred = assoc_pred_spanned.node.fold_with(proj_replacer); let Ok(assoc_pred) = traits::fully_normalize(infcx, traits::ObligationCause::dummy(), cx.param_env, assoc_pred) else { continue; }; @@ -127,14 +127,14 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { }; cx.emit_spanned_lint( OPAQUE_HIDDEN_INFERRED_BOUND, - pred_span, + pred.span, OpaqueHiddenInferredBoundLint { ty: cx.tcx.mk_opaque( def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id), ), proj_ty: proj_term, - assoc_pred_span, + assoc_pred_span: assoc_pred_spanned.span, add_bound, }, ); diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 7ea1a138b7e60..0f99c445d10ac 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -91,8 +91,8 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { use rustc_middle::ty::PredicateKind::*; let predicates = cx.tcx.explicit_predicates_of(item.owner_id); - for &(predicate, span) in predicates.predicates { - let Clause(Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else { + for &predicate in predicates.predicates { + let Clause(Clause::Trait(trait_predicate)) = predicate.node.kind().skip_binder() else { continue }; let def_id = trait_predicate.trait_ref.def_id; @@ -106,8 +106,8 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { }; cx.emit_spanned_lint( DROP_BOUNDS, - span, - DropTraitConstraintsDiag { predicate, tcx: cx.tcx, def_id }, + predicate.span, + DropTraitConstraintsDiag { predicate: predicate.node, tcx: cx.tcx, def_id }, ); } } diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 737500cc257eb..5d98bdc731d66 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -20,8 +20,7 @@ mod newtype; mod query; mod serialize; mod symbols; -mod type_foldable; -mod type_visitable; +mod traversable; #[proc_macro] pub fn rustc_queries(input: TokenStream) -> TokenStream { @@ -121,25 +120,80 @@ 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)] => + [TypeFoldable, attributes(skip_traversal)] => /// 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 + /// Folds will produce a value of the same struct or enum variant as the input, with each field + /// respectively folded (in definition order) using the `TypeFoldable` implementation for its + /// type if it has one. Fields of non-generic types that do not contain anything that may be of + /// interest to folders will automatically be left unchanged whether the type implements + /// `TypeFoldable` or not; the same behaviour can be achieved for fields of generic types by + /// applying `#[skip_traversal]` to the field definition (or even to a variant definition if it + /// should apply to all fields therein), but the derived implementation will only be applicable + /// to concrete types where such annotated fields do not contain anything that may be of + /// interest to folders (thus preventing fields from being left unchanged erroneously). + /// + /// In some rare situations, it may be necessary for `TypeFoldable` to be implemented for types + /// that do not contain anything of interest to folders. Whilst the macro expansion in such + /// cases would (as described above) result in folds that merely reconstruct `self`, this is + /// accomplished via method calls that might not get optimised away. One can therefore annotate + /// the type itself with `#[skip_traversal]` to immediately return `self` instead; as above, + /// such derived implementations are only applicable if the annotated type does not contain + /// anything that may be of interest to a folder. Moreover, since such implementations should + /// rarely be necessary, a descriptive reason for the implementation must also be provided: + /// e.g. `#[skip_traversal(but_impl_because = "")]`. If applied to a + /// non-generic type (which cannot ever contain anything that may be of interest to folders), + /// this attribute is mandatory. + /// + /// The derived implementation will use `TyCtxt<'tcx>` as the interner iff the annotated type + /// has a `'tcx` lifetime parameter; otherwise it will be generic over all interners. It + /// therefore matters how any lifetime parameters of the annotated type are named. For example, + /// deriving `TypeFoldable` for both `Foo<'a>` and `Bar<'tcx>` will respectively produce: + /// + /// `impl<'a, I: Interner> TypeFoldable for Foo<'a>` + /// + /// and + /// + /// `impl<'tcx> TypeFoldable> for Bar<'tcx>` + traversable::traversable_derive:: ); decl_derive!( - [TypeVisitable, attributes(type_visitable)] => + [TypeVisitable, attributes(skip_traversal)] => /// 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 + /// Each field of the struct or enum variant will be visited (in definition order) using the + /// `TypeVisitable` implementation for its type if it has one. Fields of non-generic types that + /// do not contain anything that may be of interest to visitors will automatically be skipped + /// whether the type implements `TypeVisitable` or not; the same behaviour can be achieved for + /// fields of generic types by applying `#[skip_traversal]` to the field definition (or even to + /// a variant definition if it should apply to all fields therein), but the derived + /// implementation will only be applicable to concrete types where such annotated fields do not + /// contain anything that may be of interest to visitors (thus preventing fields from being so + /// skipped erroneously). + /// + /// In some rare situations, it may be necessary for `TypeVisitable` to be implemented for + /// types that do not contain anything of interest to visitors. Whilst the macro expansion in + /// such cases would (as described above) result in visits that skip all fields, this is + /// accomplished via method calls that might not get optimised away. One can therefore annotate + /// the type itself with `#[skip_traversal]` to immediately return `Continue(())` instead; as + /// above, such derived implementations are only applicable if the annotated type does not + /// contain anything that may be of interest to visitors. Moreover, since such implementations + /// should rarely be necessary, a descriptive reason for the implementation must also be + /// provided: e.g. `#[skip_traversal(but_impl_because = "")]`. If applied to + /// a non-generic type (which cannot ever contain anything that may be of interest to + /// visitors), this attribute is mandatory. + /// + /// The derived implementation will use `TyCtxt<'tcx>` as the interner iff the annotated type + /// has a `'tcx` lifetime parameter; otherwise it will be generic over all interners. It + /// therefore matters how any lifetime parameters of the annotated type are named. For example, + /// deriving `TypeVisitable` for both `Foo<'a>` and `Bar<'tcx>` will respectively produce: + /// + /// `impl<'a, I: Interner> TypeVisitable for Foo<'a>` + /// + /// and + /// + /// `impl<'tcx> TypeVisitable> for Bar<'tcx>` + traversable::traversable_derive:: ); decl_derive!([Lift, attributes(lift)] => lift::lift_derive); decl_derive!( diff --git a/compiler/rustc_macros/src/traversable.rs b/compiler/rustc_macros/src/traversable.rs new file mode 100644 index 0000000000000..366a31771c1ea --- /dev/null +++ b/compiler/rustc_macros/src/traversable.rs @@ -0,0 +1,248 @@ +use proc_macro2::{Span, TokenStream}; +use quote::{quote, quote_spanned, ToTokens}; +use std::collections::HashMap; +use syn::{ + parse::{Error, ParseStream}, + parse_quote, + spanned::Spanned, + Attribute, Generics, Ident, LitStr, Token, +}; + +mod kw { + syn::custom_keyword!(but_impl_because); +} + +fn parse_skip_reason(input: ParseStream<'_>) -> Result<(), Error> { + input.parse::()?; + input.parse::()?; + let reason = input.parse::()?; + if reason.value().trim().is_empty() { + Err(Error::new_spanned( + reason, + "the value of `but_impl_because` must be a non-empty string", + )) + } else { + Ok(()) + } +} + +/// Generate a type parameter with the given `suffix` that does not conflict with +/// any of the `existing` generics. +fn gen_param(suffix: impl ToString, existing: &Generics) -> Ident { + let mut suffix = suffix.to_string(); + while existing.type_params().any(|t| t.ident == suffix) { + suffix.insert(0, '_'); + } + Ident::new(&suffix, Span::call_site()) +} + +/// Return the interner for the given `structure`. +/// +/// If the input represented by `structure` has a `'tcx` lifetime parameter, then we `TyCtxt<'tcx>` +/// will be returned; otherwise our derived implementation will be generic over the interner. +fn gen_interner(structure: &mut synstructure::Structure<'_>) -> TokenStream { + structure + .ast() + .generics + .lifetimes() + .find_map(|def| (def.lifetime.ident == "tcx").then_some(&def.lifetime)) + .map(|lt| quote! { ::rustc_middle::ty::TyCtxt<#lt> }) + .unwrap_or_else(|| { + let ident = gen_param("I", &structure.ast().generics); + structure.add_impl_generic(parse_quote! { #ident: ::rustc_type_ir::Interner }); + ident.into_token_stream() + }) +} + +/// Returns the first `#[skip_traversal]` attribute in `attrs`. +fn find_skip_traversal_attribute(attrs: &[Attribute]) -> Option<&Attribute> { + attrs.iter().find(|&attr| attr.path.is_ident("skip_traversal")) +} + +pub struct Foldable; +pub struct Visitable; + +/// An abstraction over traversable traits. +pub trait Traversable { + /// The trait that this `Traversable` represents, parameterised by `interner`. + fn traversable(interner: &impl ToTokens) -> TokenStream; + + /// Any supertraits that this trait is required to implement. + fn supertraits(interner: &impl ToTokens) -> TokenStream; + + /// A (`noop`) traversal of this trait upon the `bind` expression. + fn traverse(bind: TokenStream, noop: bool) -> TokenStream; + + /// A `match` arm for `variant`, where `f` generates the tokens for each binding. + fn arm( + variant: &synstructure::VariantInfo<'_>, + f: impl FnMut(&synstructure::BindingInfo<'_>) -> TokenStream, + ) -> TokenStream; + + /// The body of an implementation given the `interner`, `traverser` and match expression `body`. + fn impl_body( + interner: impl ToTokens, + traverser: impl ToTokens, + body: impl ToTokens, + ) -> TokenStream; +} + +impl Traversable for Foldable { + fn traversable(interner: &impl ToTokens) -> TokenStream { + quote! { ::rustc_type_ir::fold::TypeFoldable<#interner> } + } + fn supertraits(interner: &impl ToTokens) -> TokenStream { + Visitable::traversable(interner) + } + fn traverse(bind: TokenStream, noop: bool) -> TokenStream { + if noop { + bind + } else { + quote! { ::rustc_type_ir::prefer_noop_traversal_if_applicable!(#bind.try_fold_with(folder))? } + } + } + fn arm( + variant: &synstructure::VariantInfo<'_>, + mut f: impl FnMut(&synstructure::BindingInfo<'_>) -> TokenStream, + ) -> TokenStream { + let bindings = variant.bindings(); + variant.construct(|_, index| f(&bindings[index])) + } + fn impl_body( + interner: impl ToTokens, + traverser: impl ToTokens, + body: impl ToTokens, + ) -> TokenStream { + quote! { + fn try_fold_with<#traverser: ::rustc_type_ir::fold::FallibleTypeFolder<#interner>>( + self, + folder: &mut #traverser + ) -> ::core::result::Result { + ::core::result::Result::Ok(#body) + } + } + } +} + +impl Traversable for Visitable { + fn traversable(interner: &impl ToTokens) -> TokenStream { + quote! { ::rustc_type_ir::visit::TypeVisitable<#interner> } + } + fn supertraits(_: &impl ToTokens) -> TokenStream { + quote! { ::core::clone::Clone + ::core::fmt::Debug } + } + fn traverse(bind: TokenStream, noop: bool) -> TokenStream { + if noop { + quote! {} + } else { + quote! { ::rustc_type_ir::prefer_noop_traversal_if_applicable!(#bind.visit_with(visitor))?; } + } + } + fn arm( + variant: &synstructure::VariantInfo<'_>, + f: impl FnMut(&synstructure::BindingInfo<'_>) -> TokenStream, + ) -> TokenStream { + variant.bindings().iter().map(f).collect() + } + fn impl_body( + interner: impl ToTokens, + traverser: impl ToTokens, + body: impl ToTokens, + ) -> TokenStream { + quote! { + fn visit_with<#traverser: ::rustc_type_ir::visit::TypeVisitor<#interner>>( + &self, + visitor: &mut #traverser + ) -> ::core::ops::ControlFlow<#traverser::BreakTy> { + #body + ::core::ops::ControlFlow::Continue(()) + } + } + } +} + +pub fn traversable_derive( + mut structure: synstructure::Structure<'_>, +) -> TokenStream { + let skip_traversal = quote! { ::rustc_type_ir::SkipTraversalAutoImplOnly }; + + let interner = gen_interner(&mut structure); + let traverser = gen_param("T", &structure.ast().generics); + let traversable = T::traversable(&interner); + let ast = structure.ast(); + + structure.add_bounds(synstructure::AddBounds::None); + structure.bind_with(|_| synstructure::BindStyle::Move); + + // If our derived implementation will be generic over the traversable type, then we must + // constrain it to only those generic combinations that satisfy the traversable trait's + // supertraits. + let is_generic = !ast.generics.params.is_empty(); + if is_generic { + let supertraits = T::supertraits(&interner); + structure.add_where_predicate(parse_quote! { Self: #supertraits }); + } + + let body = if let Some(attr) = find_skip_traversal_attribute(&ast.attrs) { + if let Err(err) = attr.parse_args_with(parse_skip_reason) { + return err.into_compile_error(); + } + // If `is_generic`, it's possible that this no-op impl may not be applicable; but that's fine as it + // will cause a compilation error forcing removal of the inappropriate `#[skip_traversal]` attribute. + structure.add_where_predicate(parse_quote! { Self: #skip_traversal }); + T::traverse(quote! { self }, true) + } else if !is_generic { + quote_spanned!(ast.ident.span() => { + ::core::compile_error!("\ + traversal of non-generic types are no-ops by default, so explicitly deriving the traversable traits for them is rarely necessary\n\ + if the need has arisen to due the appearance of this type in an anonymous tuple, consider replacing that tuple with a named struct\n\ + otherwise add `#[skip_traversal(but_impl_because = \"\")]` to this type\ + ") + }) + } else { + // We add predicates to each generic field type, rather than to our generic type parameters. + // This results in a "perfect derive" that avoids having to propagate `#[skip_traversal]` annotations + // into wrapping types, but it can result in trait solver cycles if any type parameters are involved + // in recursive type definitions; fortunately that is not the case (yet). + let mut predicates = HashMap::new(); + let arms = structure.each_variant(|variant| { + let skipped_variant_span = find_skip_traversal_attribute(&variant.ast().attrs).map(Spanned::span); + if variant.referenced_ty_params().is_empty() { + if let Some(span) = skipped_variant_span { + return quote_spanned!(span => { + ::core::compile_error!("non-generic variants are automatically skipped where possible"); + }); + } + } + T::arm(variant, |bind| { + let ast = bind.ast(); + let skipped_span = skipped_variant_span.or_else(|| find_skip_traversal_attribute(&ast.attrs).map(Spanned::span)); + if bind.referenced_ty_params().is_empty() { + if skipped_variant_span.is_none() && let Some(span) = skipped_span { + return quote_spanned!(span => { + ::core::compile_error!("non-generic fields are automatically skipped where possible"); + }); + } + } else if let Some(prev) = predicates.insert(ast.ty.clone(), skipped_span) && let Some(span) = prev.xor(skipped_span) { + // It makes no sense to allow this. Skipping the field requires that its type impls the `SkipTraversalAutoImplOnly` + // auto-trait, which means that it does not contain anything interesting to traversers; not also skipping all other + // fields of identical type is indicative of a likely erroneous assumption on the author's part--especially since + // such other (unannotated) fields will be skipped anyway, as the noop traversal takes precedence. + return quote_spanned!(span => { + ::core::compile_error!("generic field skipped here, but another field of the same type is not skipped"); + }); + } + T::traverse(bind.into_token_stream(), skipped_span.is_some()) + }) + }); + // the order in which `where` predicates appear in rust source is irrelevant + #[allow(rustc::potential_query_instability)] + for (ty, skip) in predicates { + let bound = if skip.is_some() { &skip_traversal } else { &traversable }; + structure.add_where_predicate(parse_quote! { #ty: #bound }); + } + quote! { match self { #arms } } + }; + + structure.bound_impl(traversable, T::impl_body(interner, traverser, body)) +} diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs deleted file mode 100644 index 388e254cd6453..0000000000000 --- a/compiler/rustc_macros/src/type_foldable.rs +++ /dev/null @@ -1,57 +0,0 @@ -use quote::{quote, ToTokens}; -use syn::{parse_quote, Attribute, Meta, NestedMeta}; - -pub fn type_foldable_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.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { - s.add_impl_generic(parse_quote! { 'tcx }); - } - - s.add_bounds(synstructure::AddBounds::Generics); - 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)] - let fixed = bind - .ast() - .attrs - .iter() - .map(Attribute::parse_meta) - .filter_map(Result::ok) - .flat_map(|attr| match attr { - Meta::List(list) if list.path.is_ident("type_foldable") => list.nested, - _ => Default::default(), - }) - .any(|nested| match nested { - NestedMeta::Meta(Meta::Path(path)) => path.is_ident("identity"), - _ => false, - }); - - if fixed { - bind.to_token_stream() - } else { - quote! { - ::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)? - } - } - }) - }); - - s.bound_impl( - quote!(::rustc_middle::ty::fold::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>), - quote! { - fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>( - self, - __folder: &mut __F - ) -> Result { - Ok(match self { #body_fold }) - } - }, - ) -} diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs deleted file mode 100644 index f6f4c4779c302..0000000000000 --- a/compiler/rustc_macros/src/type_visitable.rs +++ /dev/null @@ -1,50 +0,0 @@ -use quote::quote; -use syn::{parse_quote, Attribute, Meta, NestedMeta}; - -pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { - if let syn::Data::Union(_) = s.ast().data { - panic!("cannot derive on union") - } - - // ignore fields with #[type_visitable(ignore)] - s.filter(|bi| { - !bi.ast() - .attrs - .iter() - .map(Attribute::parse_meta) - .filter_map(Result::ok) - .flat_map(|attr| match attr { - Meta::List(list) if list.path.is_ident("type_visitable") => list.nested, - _ => Default::default(), - }) - .any(|nested| match nested { - NestedMeta::Meta(Meta::Path(path)) => path.is_ident("ignore"), - _ => false, - }) - }); - - if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { - s.add_impl_generic(parse_quote! { 'tcx }); - } - - s.add_bounds(synstructure::AddBounds::Generics); - let body_visit = s.each(|bind| { - quote! { - ::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor)?; - } - }); - s.bind_with(|_| synstructure::BindStyle::Move); - - 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>>>( - &self, - __visitor: &mut __V - ) -> ::std::ops::ControlFlow<__V::BreakTy> { - match *self { #body_visit } - ::std::ops::ControlFlow::Continue(()) - } - }, - ) -} diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 0070e46ffdf02..68e0cbcb49aed 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -651,7 +651,7 @@ impl<'a, 'tcx> Decodable> for Symbol { } } -impl<'a, 'tcx> Decodable> for &'tcx [(ty::Predicate<'tcx>, Span)] { +impl<'a, 'tcx> Decodable> for &'tcx [ty::Spanned>] { fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self { ty::codec::RefDecodable::decode(d) } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 6dc6041b284ea..1abc247f4cb7d 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -351,7 +351,7 @@ define_tables! { is_type_alias_impl_trait: Table, attr_flags: Table, def_path_hashes: Table, - explicit_item_bounds: Table, Span)>>, + explicit_item_bounds: Table>>>, inferred_outlives_of: Table, Span)>>, inherent_impls: Table>, associated_types_for_impl_traits_in_associated_fn: Table>, diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs index 83d3b0100b844..dd91577a78a66 100644 --- a/compiler/rustc_middle/src/hir/place.rs +++ b/compiler/rustc_middle/src/hir/place.rs @@ -5,7 +5,6 @@ use rustc_hir::HirId; use rustc_target::abi::VariantIdx; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub enum PlaceBase { /// A temporary variable. Rvalue, @@ -18,7 +17,6 @@ pub enum PlaceBase { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub enum ProjectionKind { /// A dereference of a pointer, reference or `Box` of the given type. Deref, diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 7f8fc17744dc9..6b7a9188f27b1 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -387,11 +387,9 @@ impl<'tcx, V> Canonical<'tcx, V> { pub type QueryOutlivesConstraint<'tcx> = (ty::OutlivesPredicate, Region<'tcx>>, ConstraintCategory<'tcx>); -TrivialTypeTraversalAndLiftImpls! { - for <'tcx> { - crate::infer::canonical::Certainty, - crate::infer::canonical::CanonicalTyVarKind, - } +CloneLiftImpls! { + crate::infer::canonical::Certainty, + crate::infer::canonical::CanonicalTyVarKind, } impl<'tcx> CanonicalVarValues<'tcx> { diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index a8d71ce030c2a..0b392d79a7a55 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -62,56 +62,3 @@ macro_rules! CloneLiftImpls { } }; } - -/// Used for types that are `Copy` and which **do not care arena -/// allocated data** (i.e., don't need to be folded). -#[macro_export] -macro_rules! TrivialTypeTraversalImpls { - (for <$tcx:lifetime> { $($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) - -> ::std::ops::ControlFlow - { - ::std::ops::ControlFlow::Continue(()) - } - } - )+ - }; - - ($($ty:ty,)+) => { - TrivialTypeTraversalImpls! { - for<'tcx> { - $($ty,)+ - } - } - }; -} - -#[macro_export] -macro_rules! TrivialTypeTraversalAndLiftImpls { - ($($t:tt)*) => { - TrivialTypeTraversalImpls! { $($t)* } - CloneLiftImpls! { $($t)* } - } -} diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index b93871769b791..97e7d5d011d08 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -174,7 +174,7 @@ impl<'tcx> graph::WithPredecessors for BasicBlocks<'tcx> { } } -TrivialTypeTraversalAndLiftImpls! { +CloneLiftImpls! { Cache, } diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index db24dae11304f..7d235aa662296 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -95,7 +95,7 @@ impl From for ExpressionOperandId { } } -#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] +#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] pub enum CoverageKind { Counter { function_source_hash: u64, @@ -147,7 +147,6 @@ impl Debug for CoverageKind { } #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, Eq, PartialOrd, Ord)] -#[derive(TypeFoldable, TypeVisitable)] pub struct CodeRegion { pub file_name: Symbol, pub start_line: u32, @@ -167,7 +166,6 @@ impl Debug for CodeRegion { } #[derive(Copy, Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub enum Op { Subtract, Add, diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index c5137cf0666ea..18920e56ba85f 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -27,7 +27,7 @@ impl From for ErrorHandled { } } -TrivialTypeTraversalAndLiftImpls! { +CloneLiftImpls! { ErrorHandled, } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 42c0354d03af5..535a09529f9b7 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -9,10 +9,10 @@ use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor}; +use crate::ty::visit::TypeVisitableExt; use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, ScalarInt, UserTypeAnnotationIndex}; -use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; +use crate::ty::{GenericArg, InternalSubsts, Spanned, SubstsRef}; use rustc_data_structures::captures::Captures; use rustc_errors::ErrorGuaranteed; @@ -36,7 +36,7 @@ use either::Either; use std::borrow::Cow; use std::fmt::{self, Debug, Display, Formatter, Write}; -use std::ops::{ControlFlow, Index, IndexMut}; +use std::ops::{Index, IndexMut}; use std::{iter, mem}; pub use self::query::*; @@ -674,7 +674,7 @@ pub enum LocalKind { ReturnPointer, } -#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] +#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] pub struct VarBindingForm<'tcx> { /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`? pub binding_mode: ty::BindingMode, @@ -691,12 +691,12 @@ pub struct VarBindingForm<'tcx> { /// (a) the right-hand side isn't evaluated as a place expression. /// (b) it gives a way to separate this case from the remaining cases /// for diagnostics. - pub opt_match_place: Option<(Option>, Span)>, + pub opt_match_place: Option>>>, /// The span of the pattern in which this variable was bound. pub pat_span: Span, } -#[derive(Clone, Debug, TyEncodable, TyDecodable)] +#[derive(Clone, Debug, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)] pub enum BindingForm<'tcx> { /// This is a binding for a non-`self` binding, or a `self` that has an explicit type. Var(VarBindingForm<'tcx>), @@ -706,7 +706,7 @@ pub enum BindingForm<'tcx> { RefForGuard, } -TrivialTypeTraversalAndLiftImpls! { +CloneLiftImpls! { for<'tcx> { BindingForm<'tcx>, } @@ -1434,7 +1434,7 @@ impl Debug for Statement<'_> { use self::StatementKind::*; match self.kind { Assign(box (ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv), - FakeRead(box (ref cause, ref place)) => { + FakeRead(box FakeReadCauseAndPlace(ref cause, ref place)) => { write!(fmt, "FakeRead({:?}, {:?})", cause, place) } Retag(ref kind, ref place) => write!( @@ -1457,7 +1457,7 @@ impl Debug for Statement<'_> { PlaceMention(ref place) => { write!(fmt, "PlaceMention({:?})", place) } - AscribeUserType(box (ref place, ref c_ty), ref variance) => { + AscribeUserType(box self::AscribeUserType(ref place, ref c_ty), ref variance) => { write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty) } Coverage(box self::Coverage { ref kind, code_region: Some(ref rgn) }) => { @@ -1802,10 +1802,10 @@ impl SourceScope { source_scopes: &IndexVec>, ) -> Option> { let scope_data = &source_scopes[self]; - if let Some((inlined_instance, _)) = scope_data.inlined { - Some(inlined_instance) + if let Some(inlined_instance) = scope_data.inlined { + Some(inlined_instance.node) } else if let Some(inlined_scope) = scope_data.inlined_parent_scope { - Some(source_scopes[inlined_scope].inlined.unwrap().0) + Some(source_scopes[inlined_scope].inlined.unwrap().node) } else { None } @@ -1820,7 +1820,7 @@ pub struct SourceScopeData<'tcx> { /// Whether this scope is the root of a scope tree of another body, /// inlined into this body by the MIR inliner. /// `ty::Instance` is the callee, and the `Span` is the call site. - pub inlined: Option<(ty::Instance<'tcx>, Span)>, + pub inlined: Option>>, /// Nearest (transitive) parent scope (if any) which is inlined. /// This is an optimization over walking up `parent_scope` @@ -2635,7 +2635,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { /// The first will lead to the constraint `w: &'1 str` (for some /// inferred region `'1`). The second will lead to the constraint `w: /// &'static str`. -#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub struct UserTypeProjections { pub contents: Vec<(UserTypeProjection, Span)>, } @@ -2693,6 +2693,10 @@ impl<'tcx> UserTypeProjections { } } +#[derive(Clone, Debug, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)] +#[derive(TypeFoldable, TypeVisitable)] +pub struct AscribeUserType<'tcx>(pub Place<'tcx>, pub UserTypeProjection); + /// Encodes the effect of a user-supplied type annotation on the /// subcomponents of a pattern. The effect is determined by applying the /// given list of projections to some underlying base type. Often, @@ -2752,28 +2756,6 @@ impl UserTypeProjection { } } -impl<'tcx> TypeFoldable> for UserTypeProjection { - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - Ok(UserTypeProjection { - base: self.base.try_fold_with(folder)?, - projs: self.projs.try_fold_with(folder)?, - }) - } -} - -impl<'tcx> TypeVisitable> for UserTypeProjection { - fn visit_with>>( - &self, - visitor: &mut Vs, - ) -> ControlFlow { - self.base.visit_with(visitor) - // Note: there's nothing in `self.proj` to visit. - } -} - rustc_index::newtype_index! { #[derive(HashStable)] #[debug_format = "promoted[{}]"] diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 7e51953599d5a..1b970d9891c83 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -612,14 +612,18 @@ fn write_scope_tree( let child_data = &body.source_scopes[child]; assert_eq!(child_data.parent_scope, Some(parent)); - let (special, span) = if let Some((callee, callsite_span)) = child_data.inlined { + let (special, span) = if let Some(callee) = child_data.inlined { ( format!( " (inlined {}{})", - if callee.def.requires_caller_location(tcx) { "#[track_caller] " } else { "" }, - callee + if callee.node.def.requires_caller_location(tcx) { + "#[track_caller] " + } else { + "" + }, + callee.node ), - Some(callsite_span), + Some(callee.span), ) } else { (String::new(), None) diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index d85d68870d7d8..053131256ea46 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -161,8 +161,6 @@ pub struct GeneratorLayout<'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, } @@ -372,7 +370,7 @@ pub enum ConstraintCategory<'tcx> { } #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] -#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)] +#[derive(TyEncodable, TyDecodable, HashStable)] pub enum ReturnConstraint { Normal, ClosureUpvar(Field), diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index b16b6616415aa..e1ea1dc7c117c 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -3,7 +3,7 @@ //! This is in a dedicated file so that changes to this file can be reviewed more carefully. //! The intention is that this file only contains datatype declarations, no code. -use super::{BasicBlock, Constant, Field, Local, SwitchTargets, UserTypeProjection}; +use super::{AscribeUserType, BasicBlock, Constant, Field, Local, SwitchTargets}; use crate::mir::coverage::{CodeRegion, CoverageKind}; use crate::traits::Reveal; @@ -278,7 +278,7 @@ pub enum StatementKind<'tcx> { /// When executed at runtime this is a nop. /// /// Disallowed after drop elaboration. - FakeRead(Box<(FakeReadCause, Place<'tcx>)>), + FakeRead(Box>), /// Write the discriminant for a variant to the enum Place. /// @@ -350,7 +350,7 @@ pub enum StatementKind<'tcx> { /// When executed at runtime this is a nop. /// /// Disallowed after drop elaboration. - AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance), + AscribeUserType(Box>, ty::Variance), /// Marks the start of a "coverage region", injected with '-Cinstrument-coverage'. A /// `Coverage` statement carries metadata about the coverage region, used to inject a coverage @@ -434,6 +434,10 @@ pub enum RetagKind { Default, } +#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, Hash, HashStable, PartialEq)] +#[derive(TypeFoldable, TypeVisitable)] +pub struct FakeReadCauseAndPlace<'tcx>(pub FakeReadCause, pub Place<'tcx>); + /// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists. #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, Hash, HashStable, PartialEq)] pub enum FakeReadCause { @@ -491,7 +495,6 @@ pub enum FakeReadCause { } #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub struct Coverage { pub kind: CoverageKind, pub code_region: Option, @@ -901,6 +904,7 @@ pub enum ProjectionElem { /// /// The `x[i]` is turned into a `Deref` followed by an `Index`, not just an `Index`. The same /// thing is true of the `ConstantIndex` and `Subslice` projections below. + #[skip_traversal] Index(V), /// These indices are generated by slice patterns. Easiest to explain @@ -1184,7 +1188,7 @@ pub enum NullOp { } #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)] +#[derive(HashStable, TyEncodable, TyDecodable)] pub enum UnOp { /// The `!` operator for logical inversion Not, @@ -1193,7 +1197,7 @@ pub enum UnOp { } #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] -#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[derive(TyEncodable, TyDecodable, HashStable)] pub enum BinOp { /// The `+` operator (addition) Add, diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 9881583214eb4..e32632b6bee38 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -1,11 +1,9 @@ //! `TypeFoldable` implementations for MIR types -use rustc_ast::InlineAsmTemplatePiece; - use super::*; use crate::ty; -TrivialTypeTraversalAndLiftImpls! { +CloneLiftImpls! { BlockTailInfo, MirPhase, SourceInfo, @@ -24,30 +22,6 @@ TrivialTypeTraversalAndLiftImpls! { GeneratorSavedLocal, } -TrivialTypeTraversalImpls! { - for <'tcx> { - ConstValue<'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, diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index cffdd7ff37f22..8c98e573b2d47 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -322,7 +322,7 @@ macro_rules! make_mir_visitor { if let Some(parent_scope) = parent_scope { self.visit_source_scope($(& $mutability)? *parent_scope); } - if let Some((callee, callsite_span)) = inlined { + if let Some(Spanned { node: callee, span: callsite_span }) = inlined { let location = Location::START; self.visit_span($(& $mutability)? *callsite_span); @@ -367,7 +367,7 @@ macro_rules! make_mir_visitor { ) => { self.visit_assign(place, rvalue, location); } - StatementKind::FakeRead(box (_, place)) => { + StatementKind::FakeRead(box FakeReadCauseAndPlace(_, place)) => { self.visit_place( place, PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect), @@ -413,7 +413,7 @@ macro_rules! make_mir_visitor { ); } StatementKind::AscribeUserType( - box (place, user_ty), + box AscribeUserType(place, user_ty), variance ) => { self.visit_ascribe_user_ty(place, $(& $mutability)? *variance, user_ty, location); diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 6e961a775c1ff..d14917325de1f 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -353,6 +353,18 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { } } +impl<'tcx> Key for ty::InstanceOfArg<'tcx> { + type CacheSelector = DefaultCacheSelector; + + #[inline(always)] + fn query_crate_is_local(&self) -> bool { + self.0.krate == LOCAL_CRATE + } + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.0.default_span(tcx) + } +} + impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) { type CacheSelector = DefaultCacheSelector; @@ -365,7 +377,7 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) { } } -impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) { +impl<'tcx> Key for ty::InstanceOfConstArg<'tcx> { type CacheSelector = DefaultCacheSelector; #[inline(always)] diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4bf81c97d06ad..2b9c5709d625c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -273,7 +273,7 @@ rustc_queries! { /// `key` is the `DefId` of the associated type or opaque type. /// /// Bounds from the parent (e.g. with nested impl trait) are not included. - query explicit_item_bounds(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] { + query explicit_item_bounds(key: DefId) -> &'tcx [ty::Spanned>] { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern @@ -2133,14 +2133,14 @@ rustc_queries! { /// from `Ok(None)` to avoid misleading diagnostics when an error /// has already been/will be emitted, for the original cause query resolve_instance( - key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)> + key: ty::ParamEnvAnd<'tcx, ty::InstanceOfArg<'tcx>> ) -> Result>, ErrorGuaranteed> { desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } remap_env_constness } query resolve_instance_of_const_arg( - key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)> + key: ty::ParamEnvAnd<'tcx, ty::InstanceOfConstArg<'tcx>> ) -> Result>, ErrorGuaranteed> { desc { "resolving instance of the const argument `{}`", diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 3b11fab8cdf57..a9b3ccf55bddc 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -231,7 +231,6 @@ pub enum StmtKind<'tcx> { } #[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] -#[derive(TypeFoldable, TypeVisitable)] pub struct LocalVarId(pub hir::HirId); /// A THIR expression. diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index fb3e9cb126317..0940de147ab68 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -14,7 +14,7 @@ use crate::infer::canonical::Canonical; use crate::mir::ConstraintCategory; use crate::ty::abstract_const::NotConstEvaluatable; use crate::ty::subst::SubstsRef; -use crate::ty::{self, AdtKind, Ty, TyCtxt}; +use crate::ty::{self, AdtKind, Spanned, Ty, TyCtxt}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diagnostic}; @@ -407,7 +407,7 @@ pub enum ObligationCauseCode<'tcx> { ReturnType, /// Opaque return type of this function - OpaqueReturnType(Option<(Ty<'tcx>, Span)>), + OpaqueReturnType(Option>>), /// Block implicit return BlockTailExpression(hir::HirId), @@ -451,7 +451,6 @@ pub enum ObligationCauseCode<'tcx> { /// we can walk in order to obtain precise spans for any /// 'nested' types (e.g. `Foo` in `Option`). #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)] -#[derive(TypeVisitable, TypeFoldable)] pub enum WellFormedLoc { /// Use the type of the provided definition. Ty(LocalDefId), diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 1cc9fd526b44f..9179f26fae490 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -304,7 +304,7 @@ impl From for OverflowError { } } -TrivialTypeTraversalAndLiftImpls! { +CloneLiftImpls! { OverflowError, } diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 92d3e73e683cd..911606e9744ad 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -1,15 +1,10 @@ -use std::ops::ControlFlow; - use rustc_data_structures::intern::Interned; use rustc_query_system::cache::Cache; use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints}; use crate::traits::query::NoSolution; use crate::traits::Canonical; -use crate::ty::{ - self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, - TypeVisitor, -}; +use crate::ty::{self, ToPredicate, Ty, TyCtxt}; pub type EvaluationCache<'tcx> = Cache, QueryResult<'tcx>>; @@ -47,7 +42,7 @@ pub struct Response<'tcx> { pub certainty: Certainty, } -#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub enum Certainty { Yes, Maybe(MaybeCause), @@ -77,7 +72,7 @@ impl Certainty { } /// Why we failed to evaluate a goal. -#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub enum MaybeCause { /// We failed due to ambiguity. This ambiguity can either /// be a true ambiguity, i.e. there are multiple different answers, @@ -99,7 +94,7 @@ pub type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>; /// solver, merge the two responses again. pub type QueryResult<'tcx> = Result, NoSolution>; -#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] +#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, TypeFoldable, TypeVisitable)] pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>); impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> { @@ -117,42 +112,3 @@ pub struct ExternalConstraintsData<'tcx> { pub region_constraints: QueryRegionConstraints<'tcx>, pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, } - -// FIXME: Having to clone `region_constraints` for folding feels bad and -// probably isn't great wrt performance. -// -// Not sure how to fix this, maybe we should also intern `opaque_types` and -// `region_constraints` here or something. -impl<'tcx> TypeFoldable> for ExternalConstraints<'tcx> { - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - Ok(FallibleTypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { - region_constraints: self.region_constraints.clone().try_fold_with(folder)?, - opaque_types: self - .opaque_types - .iter() - .map(|opaque| opaque.try_fold_with(folder)) - .collect::>()?, - })) - } - - fn fold_with>>(self, folder: &mut F) -> Self { - TypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { - region_constraints: self.region_constraints.clone().fold_with(folder), - opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(), - }) - } -} - -impl<'tcx> TypeVisitable> for ExternalConstraints<'tcx> { - fn visit_with>>( - &self, - visitor: &mut V, - ) -> std::ops::ControlFlow { - self.region_constraints.visit_with(visitor)?; - self.opaque_types.visit_with(visitor)?; - ControlFlow::Continue(()) - } -} diff --git a/compiler/rustc_middle/src/traits/util.rs b/compiler/rustc_middle/src/traits/util.rs index d54b8c599d954..e2cd2cedf9b3e 100644 --- a/compiler/rustc_middle/src/traits/util.rs +++ b/compiler/rustc_middle/src/traits/util.rs @@ -25,8 +25,8 @@ impl<'tcx> Elaborator<'tcx> { .super_predicates_of(trait_ref.def_id()) .predicates .into_iter() - .flat_map(|(pred, _)| { - pred.subst_supertrait(self.tcx, &trait_ref).to_opt_poly_trait_pred() + .flat_map(|pred| { + pred.node.subst_supertrait(self.tcx, &trait_ref).to_opt_poly_trait_pred() }) .map(|t| t.map_bound(|pred| pred.trait_ref)) .filter(|supertrait_ref| self.visited.insert(*supertrait_ref)); diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index f889ce82706b3..34933f0c568b1 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -7,7 +7,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; #[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)] -#[derive(TyDecodable, TyEncodable, HashStable, TypeVisitable, TypeFoldable)] +#[derive(TyDecodable, TyEncodable, HashStable)] pub enum CastKind { /// thir::ExprKind::As As, @@ -28,7 +28,7 @@ impl From for NotConstEvaluatable { } } -TrivialTypeTraversalAndLiftImpls! { +CloneLiftImpls! { NotConstEvaluatable, } diff --git a/compiler/rustc_middle/src/ty/binding.rs b/compiler/rustc_middle/src/ty/binding.rs index a5b05a4f9b526..5a88a2649a785 100644 --- a/compiler/rustc_middle/src/ty/binding.rs +++ b/compiler/rustc_middle/src/ty/binding.rs @@ -6,7 +6,7 @@ pub enum BindingMode { BindByValue(Mutability), } -TrivialTypeTraversalAndLiftImpls! { BindingMode, } +CloneLiftImpls! { BindingMode, } impl BindingMode { pub fn convert(BindingAnnotation(by_ref, mutbl): BindingAnnotation) -> BindingMode { diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index dc2bd54b7fe48..1547810e713aa 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -20,7 +20,6 @@ use self::BorrowKind::*; pub const CAPTURE_STRUCT_LOCAL: mir::Local = mir::Local::from_u32(1); #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub struct UpvarPath { pub hir_id: hir::HirId, } @@ -29,7 +28,6 @@ pub struct UpvarPath { /// the original var ID (that is, the root variable that is referenced /// by the upvar) and the ID of the closure expression. #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub struct UpvarId { pub var_path: UpvarPath, pub closure_expr_id: LocalDefId, @@ -44,7 +42,6 @@ impl UpvarId { /// Information describing the capture of an upvar. This is computed /// during `typeck`, specifically by `regionck`. #[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub enum UpvarCapture { /// Upvar is captured by value. This is always true when the /// closure is labeled `move`, but can also be true in other cases @@ -298,7 +295,6 @@ pub fn is_ancestor_or_same_capture( /// for a particular capture as well as identifying the part of the source code /// that triggered this capture to occur. #[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub struct CaptureInfo { /// Expr Id pointing to use that resulted in selecting the current capture kind /// @@ -377,7 +373,6 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc } #[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, Copy, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] pub enum BorrowKind { /// Data must be immutable and is aliasable. ImmBorrow, diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 3ce80e06ad9ef..c3f6e9d9a36dc 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -355,7 +355,7 @@ impl<'tcx, D: TyDecoder>> Decodable for AdtDef<'tcx> { } impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> - for [(ty::Predicate<'tcx>, Span)] + for [ty::Spanned>] { fn decode(decoder: &mut D) -> &'tcx Self { decoder.interner().arena.alloc_from_iter( diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e4694809cd1a2..a7ccd048d8a0a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -30,7 +30,7 @@ use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::intern::Interned; +use rustc_data_structures::intern::{Internable, Interned}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; @@ -68,7 +68,7 @@ use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; use rustc_type_ir::sty::TyKind::*; use rustc_type_ir::WithCachedTypeInfo; -use rustc_type_ir::{CollectAndApply, DynKind, Interner, TypeFlags}; +use rustc_type_ir::{CollectAndApply, DynKind, Interner, SkipTraversalAutoImplOnly, TypeFlags}; use std::any::Any; use std::assert_matches::debug_assert_matches; @@ -130,6 +130,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type PlaceholderRegion = ty::PlaceholderRegion; } +impl !SkipTraversalAutoImplOnly for Binder<'_, T> {} +impl !SkipTraversalAutoImplOnly for Ty<'_> {} +impl !SkipTraversalAutoImplOnly for ty::Const<'_> {} +impl !SkipTraversalAutoImplOnly for Region<'_> {} +impl !SkipTraversalAutoImplOnly for Predicate<'_> {} + type InternedSet<'tcx, T> = ShardedHashMap, ()>; pub struct CtxtInterners<'tcx> { @@ -1549,11 +1555,17 @@ macro_rules! direct_interners { } } + impl<'tcx> Internable<'tcx, TyCtxt<'tcx>> for $ty { + fn intern(self, tcx: TyCtxt<'tcx>) -> Interned<'tcx, Self> { + Interned::new_unchecked(tcx.interners.$name.intern(self, |v| { + InternedInSet(tcx.interners.arena.alloc(v)) + }).0) + } + } + impl<'tcx> TyCtxt<'tcx> { $vis fn $method(self, v: $ty) -> $ret_ty { - $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| { - InternedInSet(self.interners.arena.alloc(v)) - }).0)) + $ret_ctor(v.intern(self)) } })+ } @@ -1626,8 +1638,8 @@ impl<'tcx> TyCtxt<'tcx> { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, None); - self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { - let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else { + self.explicit_item_bounds(def_id).iter().any(|predicate| { + let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.node.kind().skip_binder() else { return false; }; trait_predicate.trait_ref.def_id == future_trait @@ -1649,9 +1661,9 @@ impl<'tcx> TyCtxt<'tcx> { let trait_did = stack.pop()?; let generic_predicates = self.super_predicates_of(trait_did); - for (predicate, _) in generic_predicates.predicates { + for predicate in generic_predicates.predicates { if let ty::PredicateKind::Clause(ty::Clause::Trait(data)) = - predicate.kind().skip_binder() + predicate.node.kind().skip_binder() { if set.insert(data.def_id()) { stack.push(data.def_id()); diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index d66f436f947a3..976b5369fb1e3 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -4,7 +4,9 @@ use rustc_hir::def_id::DefId; use std::collections::BTreeMap; -pub use rustc_type_ir::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; +pub use rustc_type_ir::fold::{ + FallibleTypeFolder, SpecTypeFoldable, TypeFoldable, TypeFolder, TypeSuperFoldable, +}; /////////////////////////////////////////////////////////////////////////// // Some sample folders diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index baef4ffeda732..1f9a06f7f9198 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -6,7 +6,9 @@ use rustc_hir::def_id::DefId; use rustc_span::symbol::{kw, Symbol}; use rustc_span::Span; -use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predicate, TyCtxt}; +use super::{ + EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predicate, Spanned, TyCtxt, +}; #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub enum GenericParamDefKind { @@ -323,7 +325,7 @@ impl<'tcx> Generics { #[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)] pub struct GenericPredicates<'tcx> { pub parent: Option, - pub predicates: &'tcx [(Predicate<'tcx>, Span)], + pub predicates: &'tcx [Spanned>], } impl<'tcx> GenericPredicates<'tcx> { @@ -341,7 +343,7 @@ impl<'tcx> GenericPredicates<'tcx> { &self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator + ) -> impl Iterator>> + DoubleEndedIterator + ExactSizeIterator { EarlyBinder(self.predicates).subst_iter_copied(tcx, substs) } @@ -358,8 +360,8 @@ impl<'tcx> GenericPredicates<'tcx> { } instantiated .predicates - .extend(self.predicates.iter().map(|(p, _)| EarlyBinder(*p).subst(tcx, substs))); - instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp)); + .extend(self.predicates.iter().map(|p| EarlyBinder(p.node).subst(tcx, substs))); + instantiated.spans.extend(self.predicates.iter().map(|p| p.span)); } pub fn instantiate_identity(&self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> { @@ -376,7 +378,7 @@ impl<'tcx> GenericPredicates<'tcx> { if let Some(def_id) = self.parent { tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated); } - instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p)); - instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s)); + instantiated.predicates.extend(self.predicates.iter().map(|p| p.node)); + instantiated.spans.extend(self.predicates.iter().map(|p| p.span)); } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 5fc98f01a5470..4bf012dc57e51 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -319,6 +319,12 @@ impl<'tcx> fmt::Display for Instance<'tcx> { } } +#[derive(Clone, Copy, Debug, Eq, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)] +pub struct InstanceOfConstArg<'tcx>(pub ty::LocalDefId, pub DefId, pub SubstsRef<'tcx>); + +#[derive(Clone, Copy, Debug, Eq, Hash, HashStable, PartialEq, TypeFoldable, TypeVisitable)] +pub struct InstanceOfArg<'tcx>(pub DefId, pub SubstsRef<'tcx>); + impl<'tcx> Instance<'tcx> { pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> Instance<'tcx> { assert!( @@ -419,10 +425,10 @@ impl<'tcx> Instance<'tcx> { // FIXME(eddyb) should this always use `param_env.with_reveal_all()`? if let Some((did, param_did)) = def.as_const_arg() { tcx.resolve_instance_of_const_arg( - tcx.erase_regions(param_env.and((did, param_did, substs))), + tcx.erase_regions(param_env.and(InstanceOfConstArg(did, param_did, substs))), ) } else { - tcx.resolve_instance(tcx.erase_regions(param_env.and((def.did, substs)))) + tcx.resolve_instance(tcx.erase_regions(param_env.and(InstanceOfArg(def.did, substs)))) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 298b2c3073cd3..290c6d339371f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -48,6 +48,7 @@ use rustc_serialize::{Decodable, Encodable}; use rustc_session::lint::LintBuffer; pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; +pub use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{ExpnId, ExpnKind, Span}; use rustc_target::abi::{Align, Integer, IntegerType, VariantIdx}; @@ -87,7 +88,9 @@ pub use self::context::{ tls, CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TyCtxtFeed, }; -pub use self::instance::{Instance, InstanceDef, ShortInstance, UnusedGenericParams}; +pub use self::instance::{ + Instance, InstanceDef, InstanceOfArg, InstanceOfConstArg, ShortInstance, UnusedGenericParams, +}; pub use self::list::List; pub use self::parameterized::ParameterizedOverTcx; pub use self::rvalue_scopes::RvalueScopes; @@ -246,6 +249,9 @@ pub enum ImplSubject<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] #[derive(TypeFoldable, TypeVisitable)] +#[skip_traversal(but_impl_because = " + `ImplPolarity` impls `Relate`, which is a subtrait of `TypeFoldable`. +")] pub enum ImplPolarity { /// `impl Trait for Type` Positive, @@ -288,6 +294,10 @@ pub enum Visibility { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeFoldable, TypeVisitable)] +#[skip_traversal(but_impl_because = " + `BoundConstness` impls `Relate`, which is a subtrait of `TypeFoldable`. +")] pub enum BoundConstness { /// `T: Trait` NotConst, @@ -1290,27 +1300,34 @@ impl<'tcx> InstantiatedPredicates<'tcx> { } impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> { - type Item = (Predicate<'tcx>, Span); + type Item = Spanned>; - type IntoIter = std::iter::Zip>, std::vec::IntoIter>; + type IntoIter = std::iter::Map< + std::iter::Zip>, std::vec::IntoIter>, + fn((Predicate<'tcx>, Span)) -> Spanned>, + >; fn into_iter(self) -> Self::IntoIter { debug_assert_eq!(self.predicates.len(), self.spans.len()); - std::iter::zip(self.predicates, self.spans) + std::iter::zip(self.predicates, self.spans).map(|(node, span)| Spanned { node, span }) } } impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> { - type Item = (Predicate<'tcx>, Span); - - type IntoIter = std::iter::Zip< - std::iter::Copied>>, - std::iter::Copied>, + type Item = Spanned>; + + type IntoIter = std::iter::Map< + std::iter::Zip< + std::iter::Copied>>, + std::iter::Copied>, + >, + fn((Predicate<'tcx>, Span)) -> Spanned>, >; fn into_iter(self) -> Self::IntoIter { debug_assert_eq!(self.predicates.len(), self.spans.len()); std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied()) + .map(|(node, span)| Spanned { node, span }) } } @@ -1425,6 +1442,14 @@ pub struct BoundConst<'tcx> { pub type PlaceholderConst<'tcx> = Placeholder; +#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)] +#[derive(PartialEq, Eq, PartialOrd, Ord)] +#[derive(Hash, HashStable)] +pub struct SubstsWithOptConstParam<'tcx, T>( + #[skip_traversal] pub WithOptConstParam, + pub SubstsRef<'tcx>, +); + /// A `DefId` which, in case it is a const argument, is potentially bundled with /// the `DefId` of the generic parameter it instantiates. /// @@ -1476,7 +1501,7 @@ pub type PlaceholderConst<'tcx> = Placeholder; /// except that instead of a `Ty` we bundle the `DefId` of the const parameter. /// Meaning that we need to use `type_of(const_param_did)` if `const_param_did` is `Some` /// to get the type of `did`. -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, Debug, Lift, TyEncodable, TyDecodable)] #[derive(PartialEq, Eq, PartialOrd, Ord)] #[derive(Hash, HashStable)] pub struct WithOptConstParam { @@ -1627,17 +1652,31 @@ impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { folder: &mut F, ) -> Result { Ok(ParamEnv::new( - self.caller_bounds().try_fold_with(folder)?, - self.reveal().try_fold_with(folder)?, - self.constness(), + rustc_type_ir::prefer_noop_traversal_if_applicable!( + { self.caller_bounds() }.try_fold_with(folder) + )?, + rustc_type_ir::prefer_noop_traversal_if_applicable!( + { self.reveal() }.try_fold_with(folder) + )?, + rustc_type_ir::prefer_noop_traversal_if_applicable!( + { self.constness() }.try_fold_with(folder) + )?, )) } } impl<'tcx> TypeVisitable> for ParamEnv<'tcx> { fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { - self.caller_bounds().visit_with(visitor)?; - self.reveal().visit_with(visitor) + rustc_type_ir::prefer_noop_traversal_if_applicable!( + { &self.caller_bounds() }.visit_with(visitor) + )?; + rustc_type_ir::prefer_noop_traversal_if_applicable!( + { &self.reveal() }.visit_with(visitor) + )?; + rustc_type_ir::prefer_noop_traversal_if_applicable!( + { &self.constness() }.visit_with(visitor) + )?; + ControlFlow::Continue(()) } } diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 7534d06ae91f1..ed45bf960b8d5 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -36,6 +36,10 @@ impl ParameterizedOverTcx for ty::EarlyBinder { type Value<'tcx> = ty::EarlyBinder>; } +impl ParameterizedOverTcx for ty::Spanned { + type Value<'tcx> = ty::Spanned>; +} + #[macro_export] macro_rules! trivially_parameterized_over_tcx { ($($ty:ty),+ $(,)?) => { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index fffdbfc9660bb..8dd0100363b28 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -916,8 +916,8 @@ pub trait PrettyPrinter<'tcx>: let mut is_sized = false; let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); - for (predicate, _) in bounds.subst_iter_copied(tcx, substs) { - let bound_predicate = predicate.kind(); + for predicate in bounds.subst_iter_copied(tcx, substs) { + let bound_predicate = predicate.node.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index ef643531bb288..d5a9a1417ef83 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -8,10 +8,10 @@ use crate::mir::{Field, ProjectionKind}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; +use crate::ty::{self, AliasTy, Lift, Term, TermKind, Ty, TyCtxt}; use rustc_hir::def::Namespace; use rustc_index::vec::{Idx, IndexVec}; -use rustc_target::abi::TyAndLayout; +use rustc_span::source_map::Spanned; use std::fmt; use std::ops::ControlFlow; @@ -208,13 +208,7 @@ CloneLiftImpls! { u64, String, rustc_type_ir::DebruijnIndex, -} -// For things about which the type library does not know, or does not -// provide any traversal implementations, we need to provide both a Lift -// implementation and traversal implementations (the latter only for -// TyCtxt<'_> interners). -TrivialTypeTraversalAndLiftImpls! { ::rustc_target::abi::VariantIdx, crate::middle::region::Scope, crate::ty::FloatTy, @@ -242,10 +236,6 @@ TrivialTypeTraversalAndLiftImpls! { crate::ty::adjustment::AutoBorrowMutability, crate::ty::AdtKind, crate::ty::BoundConstness, - // 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, @@ -272,7 +262,7 @@ TrivialTypeTraversalAndLiftImpls! { ty::Placeholder, } -TrivialTypeTraversalAndLiftImpls! { +CloneLiftImpls! { for<'tcx> { ty::ValTree<'tcx>, } @@ -369,27 +359,15 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { } } -/////////////////////////////////////////////////////////////////////////// -// Traversal implementations. - -/// AdtDefs are basically the same as a DefId. -impl<'tcx> TypeFoldable> for ty::AdtDef<'tcx> { - fn try_fold_with>>( - self, - _folder: &mut F, - ) -> Result { - Ok(self) +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Spanned { + type Lifted = Spanned; + fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { + Some(Spanned { node: tcx.lift(self.node)?, span: self.span }) } } -impl<'tcx> TypeVisitable> for ty::AdtDef<'tcx> { - fn visit_with>>( - &self, - _visitor: &mut V, - ) -> ControlFlow { - ControlFlow::Continue(()) - } -} +/////////////////////////////////////////////////////////////////////////// +// Traversal implementations. impl<'tcx, T: TypeFoldable>> TypeFoldable> for ty::Binder<'tcx, T> { fn try_fold_with>>( @@ -680,36 +658,3 @@ impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { self.kind().visit_with(visitor) } } - -impl<'tcx> TypeFoldable> for InferConst<'tcx> { - fn try_fold_with>>( - self, - _folder: &mut F, - ) -> Result { - Ok(self) - } -} - -impl<'tcx> TypeVisitable> for InferConst<'tcx> { - fn visit_with>>( - &self, - _visitor: &mut V, - ) -> ControlFlow { - ControlFlow::Continue(()) - } -} - -impl<'tcx> TypeSuperVisitable> for ty::UnevaluatedConst<'tcx> { - fn super_visit_with>>( - &self, - visitor: &mut V, - ) -> ControlFlow { - self.substs.visit_with(visitor) - } -} - -impl<'tcx> TypeVisitable> for TyAndLayout<'tcx, Ty<'tcx>> { - fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { - visitor.visit_ty(self.ty) - } -} diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index dc585f438f4cd..456a639b5fc11 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -678,7 +678,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn bound_explicit_item_bounds( self, def_id: DefId, - ) -> ty::EarlyBinder<&'tcx [(ty::Predicate<'tcx>, rustc_span::Span)]> { + ) -> ty::EarlyBinder<&'tcx [ty::Spanned>]> { ty::EarlyBinder(self.explicit_item_bounds(def_id)) } diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 6814cadb9a8e4..c9d4dfdaede78 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; use std::ops::ControlFlow; -pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +pub use rustc_type_ir::visit::{SpecTypeVisitable, TypeSuperVisitable, TypeVisitable, TypeVisitor}; pub trait TypeVisitableExt<'tcx>: TypeVisitable> { /// Returns `true` if `self` has any late-bound regions that are either diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 2643d33cee00a..0156150e3c217 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -231,7 +231,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { remainder_span, pattern, None, - Some((Some(&destination), initializer_span)), + Some(ty::Spanned { + node: Some(&destination), + span: initializer_span, + }), ); this.visit_primary_bindings( pattern, @@ -308,7 +311,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { remainder_span, pattern, None, - Some((None, initializer_span)), + Some(ty::Spanned { + node: None, + span: initializer_span, + }), ); this.expr_into_pattern(block, &pattern, init) // irrefutable pattern diff --git a/compiler/rustc_mir_build/src/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs index 4f1623b4c6a7c..254f1d5d776fc 100644 --- a/compiler/rustc_mir_build/src/build/cfg.rs +++ b/compiler/rustc_mir_build/src/build/cfg.rs @@ -85,7 +85,7 @@ impl<'tcx> CFG<'tcx> { cause: FakeReadCause, place: Place<'tcx>, ) { - let kind = StatementKind::FakeRead(Box::new((cause, place))); + let kind = StatementKind::FakeRead(Box::new(FakeReadCauseAndPlace(cause, place))); let stmt = Statement { source_info, kind }; self.push(block, stmt); } diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 33200b80a572d..7af5130273328 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -487,7 +487,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Statement { source_info, kind: StatementKind::AscribeUserType( - Box::new(( + Box::new(AscribeUserType( place, UserTypeProjection { base: annotation_index, projs: vec![] }, )), @@ -514,7 +514,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Statement { source_info, kind: StatementKind::AscribeUserType( - Box::new(( + Box::new(AscribeUserType( Place::from(temp), UserTypeProjection { base: annotation_index, projs: vec![] }, )), diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 2d52102db2cc6..cfef8c449322b 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -345,8 +345,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // }; // ``` let scrutinee_place = scrutinee_place_builder.try_to_place(this); - let opt_scrutinee_place = - scrutinee_place.as_ref().map(|place| (Some(place), scrutinee_span)); + let opt_scrutinee_place = scrutinee_place + .as_ref() + .map(|place| ty::Spanned { node: Some(place), span: scrutinee_span }); let scope = this.declare_bindings( None, arm.span, @@ -530,7 +531,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Statement { source_info: ty_source_info, kind: StatementKind::AscribeUserType( - Box::new((place, UserTypeProjection { base, projs: Vec::new() })), + Box::new(AscribeUserType( + place, + UserTypeProjection { base, projs: Vec::new() }, + )), // We always use invariant as the variance here. This is because the // variance field from the ascription refers to the variance to use // when applying the type to the value being matched, but this @@ -608,7 +612,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // ``` if let Some(place) = initializer.try_to_place(self) { let LocalInfo::User(BindingForm::Var( - VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. }, + VarBindingForm { opt_match_place: Some(ty::Spanned { node: ref mut match_place, .. }), .. }, )) = **self.local_decls[local].local_info.as_mut().assert_crate_local() else { bug!("Let binding to non-user variable.") }; @@ -643,7 +647,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scope_span: Span, pattern: &Pat<'tcx>, guard: Option<&Guard<'tcx>>, - opt_match_place: Option<(Option<&Place<'tcx>>, Span)>, + opt_match_place: Option>>>, ) -> Option { self.visit_primary_bindings( &pattern, @@ -665,7 +669,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ty, user_ty, ArmHasGuard(guard.is_some()), - opt_match_place.map(|(x, y)| (x.cloned(), y)), + opt_match_place.map(|x| ty::Spanned { node: x.node.cloned(), span: x.span }), pattern.span, ); }, @@ -1793,7 +1797,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut [&mut guard_candidate, &mut otherwise_candidate], ); let expr_place = expr_place_builder.try_to_place(self); - let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); + let opt_expr_place = + expr_place.as_ref().map(|place| ty::Spanned { node: Some(place), span: expr_span }); let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap(); self.break_for_else(otherwise_post_guard_block, else_target, self.source_info(expr_span)); @@ -2087,7 +2092,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Statement { source_info, kind: StatementKind::AscribeUserType( - Box::new(( + Box::new(AscribeUserType( ascription.source, UserTypeProjection { base, projs: Vec::new() }, )), @@ -2209,7 +2214,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { var_ty: Ty<'tcx>, user_ty: UserTypeProjections, has_guard: ArmHasGuard, - opt_match_place: Option<(Option>, Span)>, + opt_match_place: Option>>>, pat_span: Span, ) { let tcx = self.tcx; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 80d8b27336c54..25db800e9cb5a 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -884,7 +884,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { LocalInfo::User(BindingForm::Var(VarBindingForm { binding_mode, opt_ty_info: param.ty_span, - opt_match_place: Some((None, span)), + opt_match_place: Some(ty::Spanned { node: None, span }), pat_span: span, })) }; @@ -896,7 +896,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr.span, &pat, None, - Some((Some(&place), span)), + Some(ty::Spanned { node: Some(&place), span }), ); let place_builder = PlaceBuilder::from(local); unpack!(block = self.place_into_pattern(block, &pat, place_builder, false)); diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index d9ceac1154f4a..b6e636ba747c2 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -311,7 +311,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } self.gather_rvalue(rval); } - StatementKind::FakeRead(box (_, place)) => { + StatementKind::FakeRead(box FakeReadCauseAndPlace(_, place)) => { self.create_move_path(*place); } StatementKind::StorageLive(_) => {} diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index de7b8c63fc87a..761362f1d373b 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -113,7 +113,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { .predicates_of(def_id.to_def_id()) .predicates .iter() - .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); + .filter_map(|p| p.node.is_global().then_some(p.node)); if traits::impossible_predicates( tcx, traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(), diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 68e50070e56e1..2b7f007ff0dcb 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -90,7 +90,7 @@ impl<'tcx> MirLint<'tcx> for ConstProp { .predicates_of(def_id.to_def_id()) .predicates .iter() - .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); + .filter_map(|p| p.node.is_global().then_some(p.node)); if traits::impossible_predicates( tcx, traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(), diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 2f1202586594a..8e6030ec804e1 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -5,8 +5,8 @@ use itertools::Itertools; use rustc_data_structures::graph::WithNumNodes; use rustc_middle::mir::spanview::source_range_no_file; use rustc_middle::mir::{ - self, AggregateKind, BasicBlock, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, - TerminatorKind, + self, AggregateKind, BasicBlock, FakeReadCause, FakeReadCauseAndPlace, Rvalue, Statement, + StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::TyCtxt; use rustc_span::source_map::original_sp; @@ -823,10 +823,10 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option // and `_1` is the `Place` for `somenum`. // // If and when the Issue is resolved, remove this special case match pattern: - StatementKind::FakeRead(box (cause, _)) if cause == FakeReadCause::ForGuardBinding => None, + StatementKind::FakeRead(box FakeReadCauseAndPlace(cause, _)) if cause == FakeReadCause::ForGuardBinding => None, // Retain spans from all other statements - StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding` + StatementKind::FakeRead(_) // Not including `ForGuardBinding` | StatementKind::Intrinsic(..) | StatementKind::Assign(_) | StatementKind::SetDiscriminant { .. } diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 66d32b954e473..ca68e30813e7e 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -175,7 +175,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { let ty_params = fn_substs.types().map(|ty| format!("{}", ty)); let const_params = fn_substs.consts().map(|c| format!("{}", c)); let params = ty_params.chain(const_params).join(", "); - let num_args = fn_sig.inputs().map_bound(|inputs| inputs.len()).skip_binder(); + let num_args = fn_sig.inputs().skip_binder().len(); let variadic = if fn_sig.c_variadic() { ", ..." } else { "" }; let ret = if fn_sig.output().skip_binder().is_unit() { "" } else { " -> _" }; self.tcx.struct_span_lint_hir( diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index e6875fad3068d..bd97655f00fcc 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1785,10 +1785,10 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for &(predicate, _) in tcx.explicit_item_bounds(def) { + for &predicate in tcx.explicit_item_bounds(def) { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = - predicate.kind().skip_binder() + predicate.node.kind().skip_binder() { let def_id = poly_trait_predicate.trait_ref.def_id; let descr_pre = &format!("{}implementer{} of ", data.descr_pre, plural_suffix); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 9cba8870f2377..727490c3d0483 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -1059,7 +1059,10 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { // Mark the outermost callee scope as an inlined one. assert_eq!(scope_data.inlined, None); - scope_data.inlined = Some((self.callsite.callee, self.callsite.source_info.span)); + scope_data.inlined = Some(ty::Spanned { + node: self.callsite.callee, + span: self.callsite.source_info.span, + }); } else if scope_data.inlined_parent_scope.is_none() { // Make it easy to find the scope with `inlined` set above. scope_data.inlined_parent_scope = Some(self.map_scope(OUTERMOST_SOURCE_SCOPE)); diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index 1f37f03cff1ca..621d267990ea4 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -116,10 +116,10 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { } StatementKind::Deinit(box place) | StatementKind::SetDiscriminant { box place, variant_index: _ } - | StatementKind::AscribeUserType(box (place, _), _) + | StatementKind::AscribeUserType(box AscribeUserType(place, _), _) | StatementKind::Retag(_, box place) | StatementKind::PlaceMention(box place) - | StatementKind::FakeRead(box (_, place)) => Some(place), + | StatementKind::FakeRead(box FakeReadCauseAndPlace(_, place)) => Some(place), StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { Some(local.into()) } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index cd67644589846..5b6b324579367 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -189,7 +189,7 @@ where predicates: ty::GenericPredicates<'tcx>, ) -> ControlFlow { let ty::GenericPredicates { parent: _, predicates } = predicates; - predicates.iter().try_for_each(|&(predicate, _span)| self.visit_predicate(predicate)) + predicates.iter().try_for_each(|&predicate| self.visit_predicate(predicate.node)) } } @@ -1248,8 +1248,8 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { self.tcx.types.never, ); - for (pred, _) in bounds.predicates() { - match pred.kind().skip_binder() { + for pred in bounds.predicates() { + match pred.node.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { if self.visit_trait(trait_predicate.trait_ref).is_break() { return; diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index 35b7e5919e42a..44c7ffa9283d7 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -820,7 +820,7 @@ impl<'a, 'tcx> Decodable> } } -impl<'a, 'tcx> Decodable> for &'tcx [(ty::Predicate<'tcx>, Span)] { +impl<'a, 'tcx> Decodable> for &'tcx [ty::Spanned>] { fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { RefDecodable::decode(d) } diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index ae81d95e27967..3ed5cc2d9bff7 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -11,6 +11,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } rustc_arena = { path = "../rustc_arena" } +rustc_type_ir = { path = "../rustc_type_ir" } scoped-tls = "1.0" unicode-width = "0.1.4" cfg-if = "1.0" diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index ee895f53eba9b..265910bdf33d1 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -76,6 +76,7 @@ pub mod monotonic { } #[derive(Clone, Encodable, Decodable, Debug, Copy, HashStable_Generic)] +#[derive(Eq, PartialEq, Hash, TypeFoldable, TypeVisitable)] pub struct Spanned { pub node: T, pub span: Span, diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index 568c916a16328..027388c7b2fca 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -14,3 +14,4 @@ rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } +rustc_type_ir = { path = "../rustc_type_ir" } diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 8d2e92cc76c6f..8f10334889cc8 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -24,7 +24,7 @@ impl ToJson for Endian { /// to that obtained from `layout_of(ty)`, as we need to produce /// layouts for which Rust types do not exist, such as enum variants /// or synthetic fields of enums (i.e., discriminants) and fat pointers. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable_Generic)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable_Generic, TypeVisitable)] pub struct TyAndLayout<'a, Ty> { pub ty: Ty, pub layout: Layout<'a>, diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs index d4f7ed31b895c..73e9d52285013 100644 --- a/compiler/rustc_target/src/spec/abi.rs +++ b/compiler/rustc_target/src/spec/abi.rs @@ -8,7 +8,10 @@ use rustc_span::{Span, Symbol}; mod tests; #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)] -#[derive(HashStable_Generic, Encodable, Decodable)] +#[derive(HashStable_Generic, Encodable, Decodable, TypeFoldable, TypeVisitable)] +#[skip_traversal(but_impl_because = " + `Abi` impls `Relate`, which is a subtrait of `TypeFoldable`. +")] pub enum Abi { // Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the // hashing tests. These are used in many places, so giving them stable values reduces test diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index d3eba43b47e95..7724dc9b6c3ee 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -23,5 +23,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } +rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } itertools = "0.10.1" diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 186bfc701bc4c..ecac860dc84cf 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2108,7 +2108,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // but whose substs don't match. let other_pred = predicates.into_iter() .enumerate() - .find(|(other_idx, (pred, _))| match pred.kind().skip_binder() { + .find(|(other_idx, pred)| match pred.node.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) if self.tcx.is_fn_trait(trait_pred.def_id()) && other_idx != idx @@ -2116,12 +2116,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // (i.e. constraining this closure) && expected_self == self.tcx.anonymize_bound_vars( - pred.kind().rebind(trait_pred.self_ty()), + pred.node.kind().rebind(trait_pred.self_ty()), ) // But the substs don't match (i.e. incompatible args) && expected_substs != self.tcx.anonymize_bound_vars( - pred.kind().rebind(trait_pred.trait_ref.substs), + pred.node.kind().rebind(trait_pred.trait_ref.substs), ) => { true @@ -2129,9 +2129,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { _ => false, }); // If we found one, then it's very likely the cause of the error. - if let Some((_, (_, other_pred_span))) = other_pred { + if let Some((_, other_pred)) = other_pred { err.span_note( - other_pred_span, + other_pred.span, "closure inferred to have a different signature due to this bound", ); } @@ -3339,10 +3339,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } ObligationCauseCode::OpaqueReturnType(expr_info) => { - if let Some((expr_ty, expr_span)) = expr_info { - let expr_ty = with_forced_trimmed_paths!(self.ty_to_string(expr_ty)); + if let Some(expr) = expr_info { + let expr_ty = with_forced_trimmed_paths!(self.ty_to_string(expr.node)); err.span_label( - expr_span, + expr.span, with_forced_trimmed_paths!(format!( "return type was inferred to be `{expr_ty}` here", )), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bfeda88a6d40c..d56e0f52e178c 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -113,11 +113,11 @@ pub fn predicates_for_generics<'tcx>( param_env: ty::ParamEnv<'tcx>, generic_bounds: ty::InstantiatedPredicates<'tcx>, ) -> impl Iterator> { - generic_bounds.into_iter().enumerate().map(move |(idx, (predicate, span))| Obligation { - cause: cause(idx, span), + generic_bounds.into_iter().enumerate().map(move |(idx, predicate)| Obligation { + cause: cause(idx, predicate.span), recursion_depth: 0, param_env, - predicate, + predicate: predicate.node, }) } @@ -523,13 +523,13 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI let param_env = tcx.param_env(impl_def_id); let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id }; - let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| { - pred.visit_with(&mut visitor).is_continue().then(|| { + let predicates_for_trait = predicates.predicates.iter().filter_map(|pred| { + pred.node.visit_with(&mut visitor).is_continue().then(|| { Obligation::new( tcx, - ObligationCause::dummy_with_span(*span), + ObligationCause::dummy_with_span(pred.span), param_env, - ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs), + ty::EarlyBinder(pred.node).subst(tcx, impl_trait_ref.substs), ) }) }); diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index a5def4151bfda..917e0b40ed737 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -284,7 +284,10 @@ fn predicates_reference_self( predicates .predicates .iter() - .map(|&(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp)) + .map(|&predicate| ty::Spanned { + node: predicate.node.subst_supertrait(tcx, &trait_ref), + span: predicate.span, + }) .filter_map(|predicate| predicate_references_self(tcx, predicate)) .collect() } @@ -300,7 +303,7 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span fn predicate_references_self<'tcx>( tcx: TyCtxt<'tcx>, - (predicate, sp): (ty::Predicate<'tcx>, Span), + ty::Spanned { node: predicate, span: sp }: ty::Spanned>, ) -> Option { let self_ty = tcx.types.self_param; let has_self_ty = |arg: &GenericArg<'tcx>| arg.walk().any(|arg| arg == self_ty.into()); @@ -555,7 +558,7 @@ fn virtual_call_violation_for_method<'tcx>( // NOTE: This check happens last, because it results in a lint, and not a // hard error. - if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, span)| { + if tcx.predicates_of(method.def_id).predicates.iter().any(|&pred| { // dyn Trait is okay: // // trait Trait { @@ -565,7 +568,7 @@ fn virtual_call_violation_for_method<'tcx>( // because a trait object can't claim to live longer than the concrete // type. If the lifetime bound holds on dyn Trait then it's guaranteed // to hold as well on the concrete type. - if pred.to_opt_type_outlives().is_some() { + if pred.node.to_opt_type_outlives().is_some() { return false; } @@ -586,7 +589,7 @@ fn virtual_call_violation_for_method<'tcx>( trait_ref: pred_trait_ref, constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, - })) = pred.kind().skip_binder() + })) = pred.node.kind().skip_binder() && pred_trait_ref.self_ty() == tcx.types.self_param && tcx.trait_is_auto(pred_trait_ref.def_id) { @@ -596,14 +599,14 @@ fn virtual_call_violation_for_method<'tcx>( // auto trait. if pred_trait_ref.substs.len() != 1 { tcx.sess.diagnostic().delay_span_bug( - span, + pred.span, "auto traits cannot have generic parameters", ); } return false; } - contains_illegal_self_type_reference(tcx, trait_def_id, pred) + contains_illegal_self_type_reference(tcx, trait_def_id, pred.node) }) { return Some(MethodViolationCode::WhereClauseReferencesSelf); } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index b8d9cff9c489b..7b384b7660304 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2254,21 +2254,21 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( tcx.predicates_of(impl_fn_def_id).instantiate(tcx, impl_fn_substs), &mut obligations, ); - obligations.extend(predicates.into_iter().map(|(pred, span)| { + obligations.extend(predicates.into_iter().map(|pred| { Obligation::with_depth( tcx, ObligationCause::new( obligation.cause.span, obligation.cause.body_id, - if span.is_dummy() { + if pred.span.is_dummy() { super::ItemObligation(impl_fn_def_id) } else { - super::BindingObligation(impl_fn_def_id, span) + super::BindingObligation(impl_fn_def_id, pred.span) }, ), obligation.recursion_depth + 1, obligation.param_env, - pred, + pred.node, ) })); @@ -2299,13 +2299,13 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( let predicates = tcx .predicates_of(obligation.predicate.def_id) .instantiate_own(tcx, obligation.predicate.substs); - for (predicate, span) in predicates { + for predicate in predicates { let normalized = normalize_with_depth_to( selcx, obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - predicate, + predicate.node, nested, ); @@ -2316,7 +2316,7 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( | super::AscribeUserTypeProvePredicate(..) ) { obligation.cause.clone() - } else if span.is_dummy() { + } else if predicate.span.is_dummy() { ObligationCause::new( obligation.cause.span, obligation.cause.body_id, @@ -2326,7 +2326,7 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( ObligationCause::new( obligation.cause.span, obligation.cause.body_id, - super::BindingObligation(obligation.predicate.def_id, span), + super::BindingObligation(obligation.predicate.def_id, predicate.span), ) }; nested.push(Obligation::with_depth( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3d5dd18f4c1d7..2f3a185de9e36 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -184,13 +184,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() { let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); - for (predicate, _) in predicates { + for predicate in predicates { let normalized = normalize_with_depth_to( self, obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - predicate, + predicate.node, &mut obligations, ); obligations.push(Obligation::with_depth( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index bc1c72da1e175..31d31f054dc10 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2692,13 +2692,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> { assert_eq!(predicates.parent, None); let predicates = predicates.instantiate_own(tcx, substs); let mut obligations = Vec::with_capacity(predicates.len()); - for (index, (predicate, span)) in predicates.into_iter().enumerate() { + for (index, predicate) in predicates.into_iter().enumerate() { let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { ImplDerivedObligation(Box::new(ImplDerivedObligationCause { derived, impl_or_alias_def_id: def_id, impl_def_predicate_index: Some(index), - span, + span: predicate.span, })) }); let predicate = normalize_with_depth_to( @@ -2706,7 +2706,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { param_env, cause.clone(), recursion_depth, - predicate, + predicate.node, &mut obligations, ); obligations.push(Obligation { cause, recursion_depth, param_env, predicate }); diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 8e229dd8d6b98..f599af4e627e1 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -470,7 +470,7 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti let mut pretty_predicates = Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); - for (mut p, _) in predicates { + for ty::Spanned { node: mut p, .. } in predicates { if let Some(poly_trait_ref) = p.to_opt_poly_trait_pred() { if Some(poly_trait_ref.def_id()) == sized_trait { types_without_default_bounds.remove(&poly_trait_ref.self_ty().skip_binder()); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index ab4c36975a0ec..c1f583f7b9237 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -118,10 +118,10 @@ impl<'tcx> TraitAliasExpander<'tcx> { let predicates = tcx.super_predicates_of(trait_ref.def_id()); debug!(?predicates); - let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| { - pred.subst_supertrait(tcx, &trait_ref) - .to_opt_poly_trait_pred() - .map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span)) + let items = predicates.predicates.iter().rev().filter_map(|pred| { + pred.node.subst_supertrait(tcx, &trait_ref).to_opt_poly_trait_pred().map(|trait_ref| { + item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), pred.span) + }) }); debug!("expand_trait_aliases: items={:?}", items.clone().collect::>()); @@ -177,7 +177,7 @@ impl Iterator for SupertraitDefIds<'_> { predicates .predicates .iter() - .filter_map(|(pred, _)| pred.to_opt_poly_trait_pred()) + .filter_map(|pred| pred.node.to_opt_poly_trait_pred()) .map(|trait_ref| trait_ref.def_id()) .filter(|&super_def_id| visited.insert(super_def_id)), ); diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index a4e9928f8b2cf..ff711d6f9df40 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -113,8 +113,10 @@ pub(super) fn prepare_vtable_segments<'tcx, T>( .super_predicates_of(inner_most_trait_ref.def_id()) .predicates .into_iter() - .filter_map(move |(pred, _)| { - pred.subst_supertrait(tcx, &inner_most_trait_ref).to_opt_poly_trait_pred() + .filter_map(move |pred| { + pred.node + .subst_supertrait(tcx, &inner_most_trait_ref) + .to_opt_poly_trait_pred() }); 'diving_in_skip_visited_traits: loop { @@ -263,7 +265,7 @@ fn vtable_entries<'tcx>( let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); if impossible_predicates( tcx, - predicates.map(|(predicate, _)| predicate).collect(), + predicates.map(|predicate| predicate.node).collect(), ) { debug!("vtable_entries: predicates do not hold"); return VtblEntry::Vacant; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index d498af359c584..7245d49455ab5 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -773,7 +773,7 @@ impl<'tcx> WfPredicates<'tcx> { debug_assert_eq!(predicates.predicates.len(), origins.len()); iter::zip(predicates, origins.into_iter().rev()) - .map(|((mut pred, span), origin_def_id)| { + .map(|(ty::Spanned { node: mut pred, span }, origin_def_id)| { let code = if span.is_dummy() { traits::ItemObligation(origin_def_id) } else { diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index f8c8f744e6d53..1b8f60c7fa340 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -42,7 +42,7 @@ impl<'tcx> RustIrDatabase<'tcx> { .tcx .predicates_defined_on(def_id) .instantiate_own(self.interner.tcx, bound_vars) - .filter_map(|(wc, _)| LowerInto::lower_into(wc, self.interner)) + .filter_map(|wc| LowerInto::lower_into(wc.node, self.interner)) .collect() } @@ -54,7 +54,7 @@ impl<'tcx> RustIrDatabase<'tcx> { bounds .0 .iter() - .map(|(bound, _)| bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars)) + .map(|bound| bounds.rebind(bound.node).subst(self.interner.tcx, &bound_vars)) .filter_map(|bound| LowerInto::>::lower_into(bound, self.interner)) .collect() } @@ -511,8 +511,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t explicit_item_bounds .0 .iter() - .map(|(bound, _)| { - explicit_item_bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars) + .map(|bound| { + explicit_item_bounds.rebind(bound.node).subst(self.interner.tcx, &bound_vars) }) .map(|bound| { bound.fold_with(&mut ReplaceOpaqueTyFolder { diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index e0fd487b3d37f..75c7fd592f1e9 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -107,15 +107,15 @@ fn relate_mir_and_user_substs<'tcx>( let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs); debug!(?instantiated_predicates); - for (instantiated_predicate, predicate_span) in instantiated_predicates { - let span = if span == DUMMY_SP { predicate_span } else { span }; + for instantiated_predicate in instantiated_predicates { + let span = if span == DUMMY_SP { instantiated_predicate.span } else { span }; let cause = ObligationCause::new( span, CRATE_DEF_ID, - ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span), + ObligationCauseCode::AscribeUserTypeProvePredicate(instantiated_predicate.span), ); let instantiated_predicate = - ocx.normalize(&cause.clone(), param_env, instantiated_predicate); + ocx.normalize(&cause.clone(), param_env, instantiated_predicate.node); ocx.register_obligation(Obligation::new(tcx, cause, param_env, instantiated_predicate)); } diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index aa6fe7d241968..403890ac3169e 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -14,6 +14,7 @@ rustc_macros = { path = "../rustc_macros", optional = true} rustc_middle = { path = "../rustc_middle", optional = true} rustc_span = { path = "../rustc_span", optional = true} rustc_target = { path = "../rustc_target", optional = true} +rustc_type_ir = { path = "../rustc_type_ir", optional = true} [features] rustc = [ @@ -23,6 +24,7 @@ rustc = [ "rustc_macros", "rustc_span", "rustc_target", + "rustc_type_ir", ] [dev-dependencies] diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 2eaeca73da75f..c363a466f6be4 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,5 +1,5 @@ use rustc_errors::ErrorGuaranteed; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::subst::SubstsRef; @@ -10,26 +10,31 @@ use traits::{translate_substs, Reveal}; fn resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>, + key: ty::ParamEnvAnd<'tcx, ty::InstanceOfArg<'tcx>>, ) -> Result>, ErrorGuaranteed> { - let (param_env, (did, substs)) = key.into_parts(); + let (param_env, ty::InstanceOfArg(did, substs)) = key.into_parts(); if let Some(did) = did.as_local() { if let Some(param_did) = tcx.opt_const_param_of(did) { - return tcx.resolve_instance_of_const_arg(param_env.and((did, param_did, substs))); + return tcx.resolve_instance_of_const_arg( + param_env.and(ty::InstanceOfConstArg(did, param_did, substs)), + ); } } - inner_resolve_instance(tcx, param_env.and((ty::WithOptConstParam::unknown(did), substs))) + inner_resolve_instance( + tcx, + param_env.and(ty::SubstsWithOptConstParam(ty::WithOptConstParam::unknown(did), substs)), + ) } fn resolve_instance_of_const_arg<'tcx>( tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>, + key: ty::ParamEnvAnd<'tcx, ty::InstanceOfConstArg<'tcx>>, ) -> Result>, ErrorGuaranteed> { - let (param_env, (did, const_param_did, substs)) = key.into_parts(); + let (param_env, ty::InstanceOfConstArg(did, const_param_did, substs)) = key.into_parts(); inner_resolve_instance( tcx, - param_env.and(( + param_env.and(ty::SubstsWithOptConstParam( ty::WithOptConstParam { did: did.to_def_id(), const_param_did: Some(const_param_did) }, substs, )), @@ -38,9 +43,9 @@ fn resolve_instance_of_const_arg<'tcx>( fn inner_resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (ty::WithOptConstParam, SubstsRef<'tcx>)>, + key: ty::ParamEnvAnd<'tcx, ty::SubstsWithOptConstParam<'tcx, DefId>>, ) -> Result>, ErrorGuaranteed> { - let (param_env, (def, substs)) = key.into_parts(); + let (param_env, ty::SubstsWithOptConstParam(def, substs)) = key.into_parts(); let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) { debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 9fed1e57c9213..d3b76867c55da 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -65,7 +65,7 @@ fn sized_constraint_for_ty<'tcx>( .without_const() .to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; - if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } + if predicates.iter().any(|p| p.node == sized_predicate) { vec![] } else { vec![ty] } } Placeholder(..) | Bound(..) | Infer(..) => { diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 3a053d4c6a997..00b6da627f1ec 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -42,7 +42,8 @@ //! - ty.super_fold_with(folder) //! - u.fold_with(folder) //! ``` -use crate::{visit::TypeVisitable, Interner}; +use crate::{visit::TypeVisitable, Interner, SkipTraversalAutoImplOnly}; +use std::marker::PhantomData; /// This trait is implemented for every type that can be folded, /// providing the skeleton of the traversal. @@ -237,3 +238,38 @@ where Ok(self.fold_predicate(p)) } } + +pub trait SpecTypeFoldable { + type Item; + fn spec_try_fold_with>( + self, + value: Self::Item, + folder: &mut F, + ) -> Result; +} + +impl> SpecTypeFoldable for PhantomData { + type Item = T; + + #[inline(always)] + fn spec_try_fold_with>( + self, + value: T, + folder: &mut F, + ) -> Result { + value.try_fold_with(folder) + } +} + +impl SpecTypeFoldable for &PhantomData { + type Item = T; + + #[inline(always)] + fn spec_try_fold_with>( + self, + value: T, + _: &mut F, + ) -> Result { + Ok(value) + } +} diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 5a991e03dee52..83354d71f2b11 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,4 +1,5 @@ #![feature(associated_type_defaults)] +#![feature(auto_traits)] #![feature(fmt_helpers_for_derive)] #![feature(min_specialization)] #![feature(never_type)] @@ -27,7 +28,7 @@ pub mod ty_info; pub mod visit; #[macro_use] -mod macros; +pub mod macros; mod structural_impls; pub use codec::*; @@ -69,6 +70,23 @@ pub trait Interner: Sized { type PlaceholderRegion: Clone + Debug + Hash + Ord; } +/// Marker trait for types that do not need to be traversed by folders or visitors, +/// because they do not contain anything that could be of interest. +/// +/// Negative implementations of this trait should be provided by types that *are* +/// of interest for folders and visitors, namely for any given `I: Interner`: +/// * `I::Binder` +/// * `I::Ty` +/// * `I::Const` +/// * `I::Region` +/// * `I::Predicate` +/// +/// Manually implementing this trait is DANGEROUS and should NEVER be done, as it +/// can lead to miscompilation. Even if the type for which you wish to implement +/// this trait does not today contain anything of interest to folders or visitors, +/// a field added or changed in future may cause breakage. +pub auto trait SkipTraversalAutoImplOnly {} + /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` /// that produces `T` items. You could combine them with /// `f(&iter.collect::>())`, but this requires allocating memory for the diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index 6c181039730b7..0f7a50b1fa19a 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -1,39 +1,3 @@ -/// Used for types that are `Copy` and which **do not care arena -/// allocated data** (i.e., don't need to be folded). -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) - -> ::std::ops::ControlFlow - { - ::std::ops::ControlFlow::Continue(()) - } - } - )+ - }; -} - macro_rules! EnumTypeTraversalImpl { (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { $($variants:tt)* @@ -174,3 +138,31 @@ macro_rules! EnumTypeTraversalImpl { ) }; } + +#[inline(always)] +pub fn unreachable_phantom_constraint(_: T) -> std::marker::PhantomData { + unreachable!() +} + +#[macro_export] +macro_rules! prefer_noop_traversal_if_applicable { + ($val:tt.try_fold_with($folder:expr)) => {{ + use $crate::fold::SpecTypeFoldable as _; + $crate::prefer_noop_traversal_if_applicable!($val.spec_try_fold_with($folder)) + }}; + ($val:tt.visit_with($visitor:expr)) => {{ + use $crate::visit::SpecTypeVisitable as _; + $crate::prefer_noop_traversal_if_applicable!($val.spec_visit_with($visitor)) + }}; + ($val:tt.$method:ident($traverser:expr)) => {{ + let val = $val; + + #[allow(unreachable_code)] + let p = 'p: { + break 'p ::core::marker::PhantomData; + break 'p $crate::macros::unreachable_phantom_constraint(val); + }; + + (&&p).$method(val, $traverser) + }}; +} diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs index 3ebe241042f25..fd4732f950083 100644 --- a/compiler/rustc_type_ir/src/structural_impls.rs +++ b/compiler/rustc_type_ir/src/structural_impls.rs @@ -5,7 +5,10 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; -use rustc_data_structures::functor::IdFunctor; +use rustc_data_structures::{ + functor::IdFunctor, + intern::{Internable, Interned}, +}; use rustc_index::vec::{Idx, IndexVec}; use std::ops::ControlFlow; @@ -13,25 +16,32 @@ use std::rc::Rc; use std::sync::Arc; /////////////////////////////////////////////////////////////////////////// -// Atomic structs -// -// For things that don't carry any arena-allocated data (and are -// copy...), just add them to this list. +// Traversable implementations for upstream types. -TrivialTypeTraversalImpls! { - (), - bool, - usize, - u16, - u32, - u64, - String, - crate::DebruijnIndex, +// `()` is (obviously) a no-op traversal and therefore the auto-deref specialisation normally +// negates any need for explicit implementation, however `ProjectionElem`'s implementation +// requires its second type parameter to implement these traits and (annoyingly) +// `ProjectionKind` (currently) uses unit type for that parameter. +impl TypeFoldable for () { + fn try_fold_with>(self, _: &mut F) -> Result<(), F::Error> { + Ok(()) + } +} +impl TypeVisitable for () { + fn visit_with>(&self, _: &mut V) -> ControlFlow { + ControlFlow::Continue(()) + } } -/////////////////////////////////////////////////////////////////////////// -// Traversal implementations. - +// We provide implementations for 2- and 3-element tuples, however (absent specialisation) +// we can only provide for one case: we choose our implementations to be where all elements +// themselves implement the respective traits; thus if an element is a no-op traversal, it +// must provide explicit implementations even though the auto-deref specialisation normally +// would normally negate any need. The derive macros can be used for this purpose however. +// +// Note that if all elements are no-op traversals then the tuple itself will auto-implement +// the `SkipTraversalAutoImplOnly` trait and these implementations will be bypassed; +// consequently explicit implementations on the element types would not then be required. impl, U: TypeFoldable> 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)?)) @@ -70,19 +80,15 @@ impl, B: TypeVisitable, C: TypeVisitable> } } -EnumTypeTraversalImpl! { - impl TypeFoldable for Option { - (Some)(a), - (None), - } where I: Interner, T: TypeFoldable -} -EnumTypeTraversalImpl! { - impl TypeVisitable for Option { - (Some)(a), - (None), - } where I: Interner, T: TypeVisitable -} - +// As noted above for tuples, (absent specialisation) we can only provide implementations for +// `Result` in one case: we choose our implementations to be where both the `Ok` and `Err` +// types themselves implement the respective traits; thus if one of those types is a no-op +// traversal, it must provide explicit implementations even though the aute-deref specialisation +// normally would negate any need. The derive macros can be used for this purpose however. +// +// Note that if both elements are no-op traversals then the `Result` itself will auto-implement +// the `SkipTraversalAutoImplOnly` trait and these implementations will be bypassed; +// consequently explicit implementations on the element types would not then be required. EnumTypeTraversalImpl! { impl TypeFoldable for Result { (Ok)(a), @@ -96,6 +102,19 @@ EnumTypeTraversalImpl! { } where I: Interner, T: TypeVisitable, E: TypeVisitable, } +EnumTypeTraversalImpl! { + impl TypeFoldable for Option { + (Some)(a), + (None), + } where I: Interner, T: TypeFoldable +} +EnumTypeTraversalImpl! { + impl TypeVisitable for Option { + (Some)(a), + (None), + } where I: Interner, T: TypeVisitable +} + impl> TypeFoldable for Rc { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|value| value.try_fold_with(folder)) @@ -173,3 +192,15 @@ impl, Ix: Idx> TypeVisitable for IndexVec + TypeFoldable> TypeFoldable for Interned<'a, T> { + fn try_fold_with>(self, folder: &mut F) -> Result { + (*self).clone().try_fold_with(folder).map(|v| v.intern(folder.interner())) + } +} + +impl> TypeVisitable for Interned<'_, T> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + (**self).visit_with(visitor) + } +} diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 62239fd20066a..98f58a9645146 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -38,9 +38,10 @@ //! - ty.super_visit_with(visitor) //! - u.visit_with(visitor) //! ``` -use crate::Interner; +use crate::{Interner, SkipTraversalAutoImplOnly}; use std::fmt; +use std::marker::PhantomData; use std::ops::ControlFlow; /// This trait is implemented for every type that can be visited, @@ -113,3 +114,34 @@ pub trait TypeVisitor: Sized { p.super_visit_with(self) } } + +pub trait SpecTypeVisitable { + type Item: ?Sized; + fn spec_visit_with>( + self, + value: &Self::Item, + visitor: &mut V, + ) -> ControlFlow; +} + +impl> SpecTypeVisitable for PhantomData<&T> { + type Item = T; + + #[inline(always)] + fn spec_visit_with>( + self, + value: &T, + visitor: &mut V, + ) -> ControlFlow { + value.visit_with(visitor) + } +} + +impl SpecTypeVisitable for &PhantomData<&T> { + type Item = T; + + #[inline(always)] + fn spec_visit_with>(self, _: &T, _: &mut V) -> ControlFlow { + ControlFlow::Continue(()) + } +} diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e3e5454ef5443..eb49c8948d193 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -432,7 +432,7 @@ fn clean_projection<'tcx>( .tcx .explicit_item_bounds(ty.skip_binder().def_id) .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, ty.skip_binder().substs)) + .map(|bound| EarlyBinder(bound.node).subst(cx.tcx, ty.skip_binder().substs)) .collect::>(); return clean_middle_opaque_bounds(cx, bounds); } @@ -770,10 +770,10 @@ fn clean_ty_generics<'tcx>( let where_predicates = preds .predicates .iter() - .flat_map(|(p, _)| { + .flat_map(|p| { let mut projection = None; let param_idx = (|| { - let bound_p = p.kind(); + let bound_p = p.node.kind(); match bound_p.skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => { if let ty::Param(param) = pred.self_ty().kind() { @@ -803,7 +803,7 @@ fn clean_ty_generics<'tcx>( if let Some(param_idx) = param_idx && let Some(b) = impl_trait.get_mut(¶m_idx.into()) { - let p: WherePredicate = clean_predicate(*p, cx)?; + let p: WherePredicate = clean_predicate(p.node, cx)?; b.extend( p.get_bounds() @@ -839,7 +839,7 @@ fn clean_ty_generics<'tcx>( return None; } - Some(p) + Some(&p.node) }) .collect::>(); @@ -1849,7 +1849,7 @@ pub(crate) fn clean_middle_ty<'tcx>( .tcx .explicit_item_bounds(def_id) .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, substs)) + .map(|bound| EarlyBinder(bound.node).subst(cx.tcx, substs)) .collect::>(); clean_middle_opaque_bounds(cx, bounds) } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index dbbc25739aa07..7ee01db0915cb 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -131,8 +131,10 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId) predicates .predicates .iter() - .filter_map(|(pred, _)| { - if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred.kind().skip_binder() { + .filter_map(|pred| { + if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = + pred.node.kind().skip_binder() + { if pred.trait_ref.self_ty() == self_ty { Some(pred.def_id()) } else { None } } else { None diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index b8428d66a5dc8..3f350e6807093 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -502,8 +502,8 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> .collect::>(); let ty_predicates = tcx.predicates_of(did).predicates; - for (p, _) in ty_predicates { - if let PredicateKind::Clause(Clause::Trait(p)) = p.kind().skip_binder() + for p in ty_predicates { + if let PredicateKind::Clause(Clause::Trait(p)) = p.node.kind().skip_binder() && p.trait_ref.def_id == eq_trait_id && let ty::Param(self_ty) = p.trait_ref.self_ty().kind() && p.constness == BoundConstness::NotConst @@ -514,7 +514,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> } ParamEnv::new( - tcx.mk_predicates_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( + tcx.mk_predicates_from_iter(ty_predicates.iter().map(|p| p.node).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate { trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 9fb73a371b8f4..75baddf620d45 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -66,8 +66,8 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { if let ty::Alias(ty::Opaque, AliasTy { def_id, substs, .. }) = *ret_ty.kind() { let preds = cx.tcx.explicit_item_bounds(def_id); let mut is_future = false; - for &(p, _span) in preds { - let p = EarlyBinder(p).subst(cx.tcx, substs); + for p in preds { + let p = EarlyBinder(p.node).subst(cx.tcx, substs); if let Some(trait_pred) = p.to_opt_poly_trait_pred() { if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() { is_future = true; diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index 289ca4e9bed3c..e8693e469ce12 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -43,10 +43,10 @@ fn get_trait_predicates_for_trait_id<'tcx>( trait_id: Option, ) -> Vec> { let mut preds = Vec::new(); - for (pred, _) in generics.predicates { + for pred in generics.predicates { if_chain! { - if let PredicateKind::Clause(Clause::Trait(poly_trait_pred)) = pred.kind().skip_binder(); - let trait_pred = cx.tcx.erase_late_bound_regions(pred.kind().rebind(poly_trait_pred)); + if let PredicateKind::Clause(Clause::Trait(poly_trait_pred)) = pred.node.kind().skip_binder(); + let trait_pred = cx.tcx.erase_late_bound_regions(pred.node.kind().rebind(poly_trait_pred)); if let Some(trait_def_id) = trait_id; if trait_def_id == trait_pred.trait_ref.def_id; then { @@ -62,9 +62,9 @@ fn get_projection_pred<'tcx>( generics: GenericPredicates<'tcx>, trait_pred: TraitPredicate<'tcx>, ) -> Option> { - generics.predicates.iter().find_map(|(proj_pred, _)| { - if let ty::PredicateKind::Clause(Clause::Projection(pred)) = proj_pred.kind().skip_binder() { - let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred)); + generics.predicates.iter().find_map(|proj_pred| { + if let ty::PredicateKind::Clause(Clause::Projection(pred)) = proj_pred.node.kind().skip_binder() { + let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.node.kind().rebind(pred)); if projection_pred.projection_ty.substs == trait_pred.trait_ref.substs { return Some(projection_pred); } diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index babbc7294a173..d164d442d0c5c 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -72,7 +72,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: .iter() .flat_map(|v| v.fields.iter()) .any(|x| matches!(cx.tcx.type_of(x.did).subst_identity().peel_refs().kind(), ty::Param(_))) - && all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() { + && all_predicates_of(cx.tcx, fn_id).all(|pred| match pred.node.kind().skip_binder() { PredicateKind::Clause(ty::Clause::Trait(pred)) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker, _ => true, }) diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 29830557a4454..6a2cae0189346 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2102,7 +2102,7 @@ pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool { .predicates_of(did) .predicates .iter() - .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); + .filter_map(|p| p.is_global().then_some(p.node)); traits::impossible_predicates( cx.tcx, traits::elaborate_predicates(cx.tcx, predicates) diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 24403e8b6f347..95607947d9e0f 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -7,7 +7,7 @@ use crate::msrvs::Msrv; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::mir::{ - Body, CastKind, NonDivergingIntrinsic, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, + Body, CastKind, FakeReadCauseAndPlace, NonDivergingIntrinsic, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::subst::GenericArgKind; @@ -24,7 +24,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) let mut current = def_id; loop { let predicates = tcx.predicates_of(current); - for (predicate, _) in predicates.predicates { + for ty::Spanned { node: predicate, .. } in predicates.predicates { match predicate.kind().skip_binder() { ty::PredicateKind::Clause( ty::Clause::RegionOutlives(_) @@ -221,7 +221,7 @@ fn check_statement<'tcx>( check_rvalue(tcx, body, def_id, rval, span) }, - StatementKind::FakeRead(box (_, place)) => check_place(tcx, *place, span, body), + StatementKind::FakeRead(box FakeReadCauseAndPlace(_, place)) => check_place(tcx, *place, span, body), // just an assignment StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { check_place(tcx, **place, span, body) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index e0ea3952785bb..676050ae1af60 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::{ }; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::symbol::Ident; -use rustc_span::{sym, Span, Symbol, DUMMY_SP}; +use rustc_span::{sym, Symbol, DUMMY_SP}; use rustc_target::abi::{Size, VariantIdx}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; @@ -90,8 +90,8 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) { - match predicate.kind().skip_binder() { + for predicate in cx.tcx.explicit_item_bounds(def_id) { + match predicate.node.kind().skip_binder() { // For `impl Trait`, it will register a predicate of `T: Trait`, so we go through // and check substituions to find `U`. ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { @@ -267,8 +267,8 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { }, ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { - for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) { - if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() { + for predicate in cx.tcx.explicit_item_bounds(*def_id) { + if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.node.kind().skip_binder() { if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) { return true; } @@ -548,7 +548,7 @@ pub fn is_uninit_value_valid_for_ty(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { } /// Gets an iterator over all predicates which apply to the given item. -pub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator, Span)> { +pub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator>> { let mut next_id = Some(id); iter::from_fn(move || { next_id.take().map(|id| { @@ -726,18 +726,18 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option let mut output = None; let lang_items = cx.tcx.lang_items(); - for (pred, _) in cx + for pred in cx .tcx .bound_explicit_item_bounds(ty.def_id) .subst_iter_copied(cx.tcx, ty.substs) { - match pred.kind().skip_binder() { + match pred.node.kind().skip_binder() { PredicateKind::Clause(ty::Clause::Trait(p)) if (lang_items.fn_trait() == Some(p.def_id()) || lang_items.fn_mut_trait() == Some(p.def_id()) || lang_items.fn_once_trait() == Some(p.def_id())) => { - let i = pred.kind().rebind(p.trait_ref.substs.type_at(1)); + let i = pred.node.kind().rebind(p.trait_ref.substs.type_at(1)); if inputs.map_or(false, |inputs| inputs != i) { // Multiple different fn trait impls. Is this even allowed? @@ -752,7 +752,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option // Multiple different fn trait impls. Is this even allowed? return None; } - output = pred.kind().rebind(p.term.ty()).transpose(); + output = pred.node.kind().rebind(p.term.ty()).transpose(); }, _ => (), } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 21a413002d06e..d96fef7ce2a76 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -928,7 +928,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let scope = frame.current_source_info()?.scope; let inlined_parent = frame.body.source_scopes[scope].inlined_parent_scope?; let source = &frame.body.source_scopes[inlined_parent]; - source.inlined.expect("inlined_parent_scope points to scope without inline info").0 + source.inlined.expect("inlined_parent_scope points to scope without inline info").node }; // Fall back to the instance of the function itself. let instance = instance.unwrap_or(frame.instance);