From bea94aa91f606de5b026536d576339102dccde76 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Sun, 5 Feb 2023 17:59:58 +0000 Subject: [PATCH 1/8] Refactor functions used by HasEscapingVarsVisitor --- compiler/rustc_middle/src/ty/consts.rs | 6 ++++++ compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 12 +++++++----- .../rustc_middle/src/ty/structural_impls.rs | 4 +++- compiler/rustc_middle/src/ty/sty.rs | 18 ++++++++++-------- compiler/rustc_middle/src/ty/util.rs | 4 +++- compiler/rustc_middle/src/ty/visit.rs | 11 ++++++----- .../src/traits/query/normalize.rs | 2 +- compiler/rustc_type_ir/src/lib.rs | 18 +++++++++++++++--- 9 files changed, 52 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 65cbac3e8f1cd..e618ed7ecb6cf 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -239,6 +239,12 @@ impl<'tcx> Const<'tcx> { } } +impl<'tcx> ty::BoundIndex for Const<'tcx> { + fn bound_index(&self) -> Option { + if let ty::ConstKind::Bound(debruijn, _) = self.kind() { Some(debruijn) } else { None } + } +} + pub fn const_param_default(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> { let default_def_id = match tcx.hir().get_by_def_id(def_id.expect_local()) { hir::Node::GenericParam(hir::GenericParam { diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index dc6f5851b7d88..32103a1829ce7 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -1,5 +1,5 @@ use crate::ty::subst::{GenericArg, GenericArgKind}; -use crate::ty::{self, InferConst, Ty, TypeFlags}; +use crate::ty::{self, InferConst, OuterExclusiveBinder, Ty, TypeFlags}; use std::slice; #[derive(Debug)] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 09c3d5b736cf1..08895f3f602d6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -479,11 +479,6 @@ impl<'tcx> Predicate<'tcx> { self.0.flags } - #[inline(always)] - pub fn outer_exclusive_binder(self) -> DebruijnIndex { - self.0.outer_exclusive_binder - } - /// Flips the polarity of a Predicate. /// /// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`. @@ -557,6 +552,13 @@ impl<'tcx> Predicate<'tcx> { } } +impl<'tcx> ty::OuterExclusiveBinder for Predicate<'tcx> { + #[inline(always)] + fn outer_exclusive_binder(self) -> DebruijnIndex { + self.0.outer_exclusive_binder + } +} + impl rustc_errors::IntoDiagnosticArg for Predicate<'_> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string())) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 8df639750c701..49e505017fee5 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -7,7 +7,9 @@ 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, InferConst, Lift, OuterExclusiveBinder, Term, TermKind, Ty, TyCtxt, +}; use rustc_data_structures::functor::IdFunctor; use rustc_hir::def::Namespace; use rustc_index::vec::{Idx, IndexVec}; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 98d6b68356368..563bd27b4cdda 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1646,14 +1646,6 @@ impl<'tcx> Region<'tcx> { matches!(*self, ty::RePlaceholder(..)) } - #[inline] - pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool { - match *self { - ty::ReLateBound(debruijn, _) => debruijn >= index, - _ => false, - } - } - pub fn type_flags(self) -> TypeFlags { let mut flags = TypeFlags::empty(); @@ -1738,6 +1730,16 @@ impl<'tcx> Region<'tcx> { } } +impl<'tcx> ty::BoundAtOrAboveBinder for Region<'tcx> { + #[inline] + fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool { + match *self { + ty::ReLateBound(debruijn, _) => debruijn >= index, + _ => false, + } + } +} + /// Type utilities impl<'tcx> Ty<'tcx> { #[inline(always)] diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 796164b0d6af3..54d954a40f7b4 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1157,9 +1157,11 @@ impl<'tcx> Ty<'tcx> { } ty } +} +impl<'tcx> ty::OuterExclusiveBinder for Ty<'tcx> { #[inline] - pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex { + fn outer_exclusive_binder(self) -> ty::DebruijnIndex { self.0.outer_exclusive_binder } } diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index d7b7a09473726..9a9a8e1b97eb1 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -38,7 +38,10 @@ //! - ty.super_visit_with(visitor) //! - u.visit_with(visitor) //! ``` -use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; +use crate::ty::{ + self, flags::FlagComputation, Binder, BoundAtOrAboveBinder, BoundIndex, OuterExclusiveBinder, + Ty, TyCtxt, TypeFlags, +}; use rustc_errors::ErrorGuaranteed; use rustc_data_structures::fx::FxHashSet; @@ -537,10 +540,8 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { // otherwise we do want to remember to visit the rest of the // const, as it has types/regions embedded in a lot of other // places. - match ct.kind() { - ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => { - ControlFlow::Break(FoundEscapingVars) - } + match ct.bound_index() { + Some(debruijn) if debruijn >= self.outer_index => ControlFlow::Break(FoundEscapingVars), _ => ct.super_visit_with(self), } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 1b2533a5cf649..17f90c1123e35 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -13,7 +13,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::traits::Normalized; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{self, OuterExclusiveBinder, Ty, TyCtxt, TypeVisitor}; use rustc_span::DUMMY_SP; use std::ops::ControlFlow; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index d5de457a82ce9..1460d2550dc9e 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -32,9 +32,9 @@ pub trait Interner { type AdtDef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type SubstsRef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type DefId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Ty: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Const: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Region: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; + type Ty: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + OuterExclusiveBinder; + type Const: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + BoundIndex; + type Region: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + BoundAtOrAboveBinder; type TypeAndMut: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Mutability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Movability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; @@ -836,3 +836,15 @@ impl UniverseIndex { self.private < other.private } } + +pub trait OuterExclusiveBinder { + fn outer_exclusive_binder(self) -> DebruijnIndex; +} + +pub trait BoundAtOrAboveBinder { + fn bound_at_or_above_binder(self, index: DebruijnIndex) -> bool; +} + +pub trait BoundIndex { + fn bound_index(&self) -> Option; +} From e0767d959109e896f1b7506594227e83f3a12f4f Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Sun, 5 Feb 2023 18:37:03 +0000 Subject: [PATCH 2/8] Refactor functions used by HasTypeFlagsVisitor --- .../src/infer/canonical/canonicalizer.rs | 2 +- .../rustc_infer/src/infer/opaque_types.rs | 2 +- compiler/rustc_middle/src/ty/consts.rs | 6 ++ compiler/rustc_middle/src/ty/flags.rs | 4 +- compiler/rustc_middle/src/ty/mod.rs | 12 ++- .../rustc_middle/src/ty/structural_impls.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 92 ++++++++++--------- compiler/rustc_middle/src/ty/visit.rs | 8 +- compiler/rustc_type_ir/src/lib.rs | 18 +++- 9 files changed, 85 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 87c6dfad5fa2b..51c73adf41534 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -12,7 +12,7 @@ use crate::infer::InferCtxt; use rustc_middle::ty::flags::FlagComputation; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::subst::GenericArg; -use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags}; +use rustc_middle::ty::{self, BoundVar, Flags, InferConst, List, Ty, TyCtxt, TypeFlags}; use std::sync::atomic::Ordering; use rustc_data_structures::fx::FxHashMap; diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index b68b0baaa4062..9e6d5856e9276 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{ - self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, + self, Flags, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_span::Span; diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index e618ed7ecb6cf..9d4b1a7059425 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -239,6 +239,12 @@ impl<'tcx> Const<'tcx> { } } +impl<'tcx> ty::Flags for Const<'tcx> { + fn flags(self) -> ty::TypeFlags { + ty::flags::FlagComputation::for_const(self) + } +} + impl<'tcx> ty::BoundIndex for Const<'tcx> { fn bound_index(&self) -> Option { if let ty::ConstKind::Bound(debruijn, _) = self.kind() { Some(debruijn) } else { None } diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 32103a1829ce7..62215a9aaa276 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -1,5 +1,5 @@ use crate::ty::subst::{GenericArg, GenericArgKind}; -use crate::ty::{self, InferConst, OuterExclusiveBinder, Ty, TypeFlags}; +use crate::ty::{self, Flags, InferConst, OuterExclusiveBinder, Ty, TypeFlags}; use std::slice; #[derive(Debug)] @@ -302,7 +302,7 @@ impl FlagComputation { } fn add_region(&mut self, r: ty::Region<'_>) { - self.add_flags(r.type_flags()); + self.add_flags(r.flags()); if let ty::ReLateBound(debruijn, _) = *r { self.add_bound_var(debruijn); } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 08895f3f602d6..f64c583ccebb7 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -474,11 +474,6 @@ impl<'tcx> Predicate<'tcx> { self.0.internee } - #[inline(always)] - pub fn flags(self) -> TypeFlags { - self.0.flags - } - /// Flips the polarity of a Predicate. /// /// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`. @@ -552,6 +547,13 @@ impl<'tcx> Predicate<'tcx> { } } +impl<'tcx> ty::Flags for Predicate<'tcx> { + #[inline(always)] + fn flags(self) -> TypeFlags { + self.0.flags + } +} + impl<'tcx> ty::OuterExclusiveBinder for Predicate<'tcx> { #[inline(always)] fn outer_exclusive_binder(self) -> DebruijnIndex { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 49e505017fee5..d30497b39efed 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -8,7 +8,7 @@ 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, OuterExclusiveBinder, Term, TermKind, Ty, TyCtxt, + self, AliasTy, Flags, InferConst, Lift, OuterExclusiveBinder, Term, TermKind, Ty, TyCtxt, }; use rustc_data_structures::functor::IdFunctor; use rustc_hir::def::Namespace; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 563bd27b4cdda..ab9f4554766af 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1646,45 +1646,6 @@ impl<'tcx> Region<'tcx> { matches!(*self, ty::RePlaceholder(..)) } - pub fn type_flags(self) -> TypeFlags { - let mut flags = TypeFlags::empty(); - - match *self { - ty::ReVar(..) => { - flags = flags | TypeFlags::HAS_FREE_REGIONS; - flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; - flags = flags | TypeFlags::HAS_RE_INFER; - } - ty::RePlaceholder(..) => { - flags = flags | TypeFlags::HAS_FREE_REGIONS; - flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; - flags = flags | TypeFlags::HAS_RE_PLACEHOLDER; - } - ty::ReEarlyBound(..) => { - flags = flags | TypeFlags::HAS_FREE_REGIONS; - flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; - flags = flags | TypeFlags::HAS_RE_PARAM; - } - ty::ReFree { .. } => { - flags = flags | TypeFlags::HAS_FREE_REGIONS; - flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; - } - ty::ReStatic => { - flags = flags | TypeFlags::HAS_FREE_REGIONS; - } - ty::ReLateBound(..) => { - flags = flags | TypeFlags::HAS_RE_LATE_BOUND; - } - ty::ReErased => { - flags = flags | TypeFlags::HAS_RE_ERASED; - } - } - - debug!("type_flags({:?}) = {:?}", self, flags); - - flags - } - /// Given an early-bound or free region, returns the `DefId` where it was bound. /// For example, consider the regions in this snippet of code: /// @@ -1740,6 +1701,47 @@ impl<'tcx> ty::BoundAtOrAboveBinder for Region<'tcx> { } } +impl<'tcx> ty::Flags for Region<'tcx> { + fn flags(self) -> TypeFlags { + let mut flags = TypeFlags::empty(); + + match *self { + ty::ReVar(..) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; + flags = flags | TypeFlags::HAS_RE_INFER; + } + ty::RePlaceholder(..) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; + flags = flags | TypeFlags::HAS_RE_PLACEHOLDER; + } + ty::ReEarlyBound(..) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; + flags = flags | TypeFlags::HAS_RE_PARAM; + } + ty::ReFree { .. } => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; + } + ty::ReStatic => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + } + ty::ReLateBound(..) => { + flags = flags | TypeFlags::HAS_RE_LATE_BOUND; + } + ty::ReErased => { + flags = flags | TypeFlags::HAS_RE_ERASED; + } + } + + debug!("type_flags({:?}) = {:?}", self, flags); + + flags + } +} + /// Type utilities impl<'tcx> Ty<'tcx> { #[inline(always)] @@ -1747,11 +1749,6 @@ impl<'tcx> Ty<'tcx> { &self.0.0 } - #[inline(always)] - pub fn flags(self) -> TypeFlags { - self.0.0.flags - } - #[inline] pub fn is_unit(self) -> bool { match self.kind() { @@ -2442,6 +2439,13 @@ impl<'tcx> Ty<'tcx> { } } +impl<'tcx> ty::Flags for Ty<'tcx> { + #[inline(always)] + fn flags(self) -> TypeFlags { + self.0.0.flags + } +} + /// Extra information about why we ended up with a particular variance. /// This is only used to add more information to error messages, and /// has no effect on soundness. While choosing the 'wrong' `VarianceDiagInfo` diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 9a9a8e1b97eb1..a3088e7a19e83 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -39,8 +39,8 @@ //! - u.visit_with(visitor) //! ``` use crate::ty::{ - self, flags::FlagComputation, Binder, BoundAtOrAboveBinder, BoundIndex, OuterExclusiveBinder, - Ty, TyCtxt, TypeFlags, + self, Binder, BoundAtOrAboveBinder, BoundIndex, Flags, OuterExclusiveBinder, Ty, TyCtxt, + TypeFlags, }; use rustc_errors::ErrorGuaranteed; @@ -585,7 +585,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { #[inline] fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { - let flags = r.type_flags(); + let flags = r.flags(); if flags.intersects(self.flags) { ControlFlow::Break(FoundFlags) } else { @@ -595,7 +595,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { #[inline] fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { - let flags = FlagComputation::for_const(c); + let flags = c.flags(); trace!(r.flags=?flags); if flags.intersects(self.flags) { ControlFlow::Break(FoundFlags) diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 1460d2550dc9e..8d583ab8bfcc4 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -32,9 +32,17 @@ pub trait Interner { type AdtDef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type SubstsRef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type DefId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Ty: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + OuterExclusiveBinder; - type Const: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + BoundIndex; - type Region: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + BoundAtOrAboveBinder; + type Ty: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + OuterExclusiveBinder + Flags; + type Const: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + BoundIndex + Flags; + type Region: Clone + + Debug + + Hash + + PartialEq + + Eq + + PartialOrd + + Ord + + BoundAtOrAboveBinder + + Flags; type TypeAndMut: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Mutability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Movability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; @@ -848,3 +856,7 @@ pub trait BoundAtOrAboveBinder { pub trait BoundIndex { fn bound_index(&self) -> Option; } + +pub trait Flags { + fn flags(self) -> TypeFlags; +} From 2eb460989236a2fcfe1cdbf9d1baa63d7511b1f0 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Sun, 5 Feb 2023 18:50:09 +0000 Subject: [PATCH 3/8] Refactor default TypeVisitable::error_reported --- compiler/rustc_middle/src/ty/context.rs | 9 +++++++++ compiler/rustc_middle/src/ty/visit.rs | 14 +++----------- compiler/rustc_type_ir/src/lib.rs | 2 ++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9205a8a0ffed8..540128e065108 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -124,6 +124,15 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type FreeRegion = ty::FreeRegion; type RegionVid = ty::RegionVid; type PlaceholderRegion = ty::PlaceholderRegion; + + #[track_caller] + fn expect_failure() -> ErrorGuaranteed { + if let Some(reported) = ty::tls::with(|tcx| tcx.sess.is_compilation_going_to_fail()) { + reported + } else { + bug!("expect tcx.sess.is_compilation_going_to_fail return `Some`"); + } + } } type InternedSet<'tcx, T> = ShardedHashMap, ()>; diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index a3088e7a19e83..6cca4c3af9c47 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -39,8 +39,8 @@ //! - u.visit_with(visitor) //! ``` use crate::ty::{ - self, Binder, BoundAtOrAboveBinder, BoundIndex, Flags, OuterExclusiveBinder, Ty, TyCtxt, - TypeFlags, + self, Binder, BoundAtOrAboveBinder, BoundIndex, Flags, Interner, OuterExclusiveBinder, Ty, + TyCtxt, TypeFlags, }; use rustc_errors::ErrorGuaranteed; @@ -110,15 +110,7 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { self.has_type_flags(TypeFlags::HAS_ERROR) } fn error_reported(&self) -> Result<(), ErrorGuaranteed> { - if self.references_error() { - if let Some(reported) = ty::tls::with(|tcx| tcx.sess.is_compilation_going_to_fail()) { - Err(reported) - } else { - bug!("expect tcx.sess.is_compilation_going_to_fail return `Some`"); - } - } else { - Ok(()) - } + if self.references_error() { Err(TyCtxt::expect_failure()) } else { Ok(()) } } fn has_non_region_param(&self) -> bool { self.has_type_flags(TypeFlags::NEEDS_SUBST - TypeFlags::HAS_RE_PARAM) diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 8d583ab8bfcc4..30992aa9d8bbe 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -64,6 +64,8 @@ pub trait Interner { type FreeRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type RegionVid: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type PlaceholderRegion: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; + + fn expect_failure() -> Self::ErrorGuaranteed; } pub trait InternAs { From f92b450100dfa6c05b0a427349ef9dcbb9cf3f3b Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Sun, 5 Feb 2023 20:18:17 +0000 Subject: [PATCH 4/8] Project Binder and Predicate from Interner trait --- compiler/rustc_middle/src/ty/context.rs | 2 ++ compiler/rustc_type_ir/src/lib.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 540128e065108..801b5e8d91fe3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -103,6 +103,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Ty = Ty<'tcx>; type Const = ty::Const<'tcx>; type Region = Region<'tcx>; + type Binder = Binder<'tcx, T>; + type Predicate = Predicate<'tcx>; type TypeAndMut = TypeAndMut<'tcx>; type Mutability = hir::Mutability; type Movability = hir::Movability; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 30992aa9d8bbe..9cea9acc4d9da 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -43,6 +43,8 @@ pub trait Interner { + Ord + BoundAtOrAboveBinder + Flags; + type Binder; + type Predicate: OuterExclusiveBinder + Flags; type TypeAndMut: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Mutability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Movability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; From 8fcd967b25eac77910e451bbe0b80679f09bf683 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Sun, 5 Feb 2023 22:07:27 +0000 Subject: [PATCH 5/8] Make visiting generic over the interner --- .../src/constraint_generation.rs | 4 +- .../src/type_check/liveness/trace.rs | 6 +- .../rustc_const_eval/src/interpret/util.rs | 4 +- .../rustc_hir_analysis/src/check/check.rs | 4 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- .../src/coherence/orphan.rs | 2 +- .../src/collect/lifetimes.rs | 2 +- .../src/constrained_generic_params.rs | 4 +- .../rustc_hir_analysis/src/variance/mod.rs | 2 +- compiler/rustc_hir_typeck/src/closure.rs | 4 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 8 +- compiler/rustc_hir_typeck/src/writeback.rs | 2 +- .../src/infer/error_reporting/mod.rs | 6 +- .../nice_region_error/static_impl_trait.rs | 2 +- .../trait_impl_difference.rs | 2 +- .../error_reporting/nice_region_error/util.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 2 +- .../rustc_infer/src/infer/nll_relate/mod.rs | 4 +- .../rustc_infer/src/infer/opaque_types.rs | 4 +- compiler/rustc_infer/src/infer/resolve.rs | 2 +- .../src/traits/structural_impls.rs | 8 +- compiler/rustc_lint/src/types.rs | 2 +- compiler/rustc_macros/src/type_visitable.rs | 4 +- compiler/rustc_middle/src/macros.rs | 6 +- compiler/rustc_middle/src/mir/mod.rs | 7 +- .../rustc_middle/src/mir/type_visitable.rs | 4 +- compiler/rustc_middle/src/traits/solve.rs | 8 +- compiler/rustc_middle/src/ty/diagnostics.rs | 4 +- compiler/rustc_middle/src/ty/fold.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 10 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +- .../rustc_middle/src/ty/structural_impls.rs | 131 +++++++++++------- compiler/rustc_middle/src/ty/sty.rs | 19 +-- compiler/rustc_middle/src/ty/subst.rs | 10 +- compiler/rustc_middle/src/ty/visit.rs | 121 ++++++++++------ .../rustc_monomorphize/src/polymorphize.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 7 +- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- .../src/solve/project_goals.rs | 2 +- .../src/traits/coherence.rs | 2 +- .../src/traits/const_evaluatable.rs | 2 +- .../src/traits/error_reporting/mod.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 4 +- .../src/traits/object_safety.rs | 4 +- .../src/traits/project.rs | 5 +- .../src/traits/query/normalize.rs | 4 +- .../src/traits/structural_match.rs | 2 +- compiler/rustc_traits/src/chalk/lowering.rs | 6 +- .../clippy_utils/src/mir/possible_borrower.rs | 4 +- src/tools/clippy/clippy_utils/src/ty.rs | 4 +- 51 files changed, 273 insertions(+), 193 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 11b31c3f14028..1427f5cb31d9c 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, RegionVid, Ty}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt}; use crate::{ borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, nll::ToRegionVid, @@ -165,7 +165,7 @@ impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> { /// `location`. fn add_regular_live_constraint(&mut self, live_ty: T, location: Location) where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { debug!("add_regular_live_constraint(live_ty={:?}, location={:?})", live_ty, location); diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 3ff5d188a3d35..3fcca5ea8bf74 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -3,7 +3,7 @@ use rustc_index::bit_set::HybridBitSet; use rustc_index::interval::IntervalSet; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; -use rustc_middle::ty::{Ty, TypeVisitable}; +use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable}; use rustc_trait_selection::traits::query::dropck_outlives::DropckOutlivesResult; use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -477,7 +477,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { /// points `live_at`. fn add_use_live_facts_for( &mut self, - value: impl TypeVisitable<'tcx>, + value: impl TypeVisitable>, live_at: &IntervalSet, ) { debug!("add_use_live_facts_for(value={:?})", value); @@ -542,7 +542,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { fn make_all_regions_live( elements: &RegionValueElements, typeck: &mut TypeChecker<'_, 'tcx>, - value: impl TypeVisitable<'tcx>, + value: impl TypeVisitable>, live_at: &IntervalSet, ) { debug!("make_all_regions_live(value={:?})", value); diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index cabc65e2c077e..106e28fc81c12 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -9,7 +9,7 @@ use std::ops::ControlFlow; /// case these parameters are unused. pub(crate) fn ensure_monomorphic_enough<'tcx, T>(tcx: TyCtxt<'tcx>, ty: T) -> InterpResult<'tcx> where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { debug!("ensure_monomorphic_enough: ty={:?}", ty); if !ty.needs_subst() { @@ -21,7 +21,7 @@ where tcx: TyCtxt<'tcx>, } - impl<'tcx> TypeVisitor<'tcx> for UsedParamsNeedSubstVisitor<'tcx> { + impl<'tcx> TypeVisitor> for UsedParamsNeedSubstVisitor<'tcx> { type BreakTy = FoundParam; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 47eace961be55..2dba27a335f0c 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -261,7 +261,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( selftys: Vec<(Span, Option)>, } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> { + impl<'tcx> ty::visit::TypeVisitor> for ProhibitOpaqueVisitor<'tcx> { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { @@ -1447,7 +1447,7 @@ fn opaque_type_cycle_error( opaques: Vec, closures: Vec, } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for OpaqueTypeCollector { + impl<'tcx> ty::visit::TypeVisitor> for OpaqueTypeCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5b9b57da3820e..216582248c2a3 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -773,7 +773,7 @@ impl<'tcx> GATSubstCollector<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> { +impl<'tcx> TypeVisitor> for GATSubstCollector<'tcx> { type BreakTy = !; fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { @@ -1436,7 +1436,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id struct CountParams { params: FxHashSet, } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for CountParams { + impl<'tcx> ty::visit::TypeVisitor> for CountParams { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 7d381d8902ac2..205bb3d0d5e09 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -552,7 +552,7 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty: seen: FxHashSet, } - impl<'tcx> TypeVisitor<'tcx> for DisableAutoTraitVisitor<'tcx> { + impl<'tcx> TypeVisitor> for DisableAutoTraitVisitor<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { let tcx = self.tcx; diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index 3c67722b637bf..7ecf4af9bce60 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -1752,7 +1752,7 @@ fn is_late_bound_map( use std::ops::ControlFlow; use ty::Ty; - impl<'tcx> TypeVisitor<'tcx> for ConstrainedCollectorPostAstConv { + impl<'tcx> TypeVisitor> for ConstrainedCollectorPostAstConv { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Param(param_ty) => { diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 56cc1d8fadc00..e18b0f082798b 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -43,7 +43,7 @@ pub fn parameters_for_impl<'tcx>( /// of parameters whose values are needed in order to constrain `ty` - these /// differ, with the latter being a superset, in the presence of projections. pub fn parameters_for<'tcx>( - t: &impl TypeVisitable<'tcx>, + t: &impl TypeVisitable>, include_nonconstraining: bool, ) -> Vec { let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining }; @@ -56,7 +56,7 @@ struct ParameterCollector { include_nonconstraining: bool, } -impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { +impl<'tcx> TypeVisitor> for ParameterCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match *t.kind() { ty::Alias(ty::Projection, ..) if !self.include_nonconstraining => { diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 079070be27983..5d5c8ca604a04 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -99,7 +99,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc } } - impl<'tcx> ty::TypeVisitor<'tcx> for OpaqueTypeLifetimeCollector<'tcx> { + impl<'tcx> ty::TypeVisitor> for OpaqueTypeLifetimeCollector<'tcx> { #[instrument(level = "trace", skip(self), ret)] fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() { diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 90c4e5b6540b0..618488011a493 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -12,7 +12,7 @@ use rustc_infer::infer::{InferOk, InferResult}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, Ty, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Span; use rustc_span::sym; @@ -232,7 +232,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { struct MentionsTy<'tcx> { expected_ty: Ty<'tcx>, } - impl<'tcx> TypeVisitor<'tcx> for MentionsTy<'tcx> { + impl<'tcx> TypeVisitor> for MentionsTy<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 237142acca660..f83ae5639ac36 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -25,7 +25,7 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, Ty, UserType, + self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, Ty, TyCtxt, UserType, }; use rustc_middle::ty::{GenericArgKind, SubstsRef, UserSelfTy, UserSubsts}; use rustc_session::lint; @@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // sufficiently enforced with erased regions. =) fn can_contain_user_lifetime_bounds(t: T) -> bool where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { t.has_free_regions() || t.has_projections() || t.has_infer_types() } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 47ef106e75032..ad65c5c931415 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -26,7 +26,9 @@ use rustc_infer::infer::InferOk; use rustc_infer::infer::TypeTrace; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::{ + self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, +}; use rustc_session::Session; use rustc_span::symbol::{kw, Ident}; use rustc_span::{self, sym, Span}; @@ -2078,13 +2080,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { true } - fn find_ambiguous_parameter_in>( + fn find_ambiguous_parameter_in>>( &self, item_def_id: DefId, t: T, ) -> Option> { struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId); - impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> { + impl<'tcx> TypeVisitor> for FindAmbiguousParameter<'_, 'tcx> { type BreakTy = ty::GenericArg<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { if let Some(origin) = self.0.type_var_origin(ty) diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0aa34f9dd7072..1a11f64ccbd32 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -561,7 +561,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { struct RecursionChecker { def_id: LocalDefId, } - impl<'tcx> ty::TypeVisitor<'tcx> for RecursionChecker { + impl<'tcx> ty::TypeVisitor> for RecursionChecker { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *t.kind() { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b5c2d14e8d15b..431d420b6e2eb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1435,8 +1435,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'tcx> OpaqueTypesVisitor<'tcx> { fn visit_expected_found( tcx: TyCtxt<'tcx>, - expected: impl TypeVisitable<'tcx>, - found: impl TypeVisitable<'tcx>, + expected: impl TypeVisitable>, + found: impl TypeVisitable>, ignore_span: Span, ) -> Self { let mut types_visitor = OpaqueTypesVisitor { @@ -1486,7 +1486,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> { + impl<'tcx> ty::visit::TypeVisitor> for OpaqueTypesVisitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) { let span = self.tcx.def_span(def_id); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 6a463583dfb0f..b06ff10d86eb0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -539,7 +539,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Collect all the trait objects in a type that could have received an implicit `'static` lifetime. pub struct TraitObjectVisitor(pub FxIndexSet); -impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor { +impl<'tcx> TypeVisitor> for TraitObjectVisitor { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Dynamic(preds, re, _) if re.is_static() => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 40c0c806e1ff8..2875448ee157c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for HighlightBuilder<'tcx> { + impl<'tcx> ty::visit::TypeVisitor> for HighlightBuilder<'tcx> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { if !r.has_name() && self.counter <= 3 { self.highlight.highlighting_region(r, self.counter); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 4c0f457b46a7c..825aaf3afb597 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -145,7 +145,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { fn includes_region( &self, - ty: Binder<'tcx, impl TypeVisitable<'tcx>>, + ty: Binder<'tcx, impl TypeVisitable>>, region: ty::BoundRegionKind, ) -> bool { let late_bound_regions = self.tcx().collect_referenced_late_bound_regions(&ty); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f39170bb2916d..8ea4feae6460e 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1413,7 +1413,7 @@ impl<'tcx> InferCtxt<'tcx> { value: &T, ) -> Option<(ty::Term<'tcx>, Option)> where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { value.visit_with(&mut resolve::UnresolvedTypeOrConstFinder::new(self)).break_value() } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index a2cfe8d88816c..77c79c2b5dfaf 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -841,8 +841,8 @@ struct ScopeInstantiator<'me, 'tcx> { bound_region_scope: &'me mut BoundRegionScope<'tcx>, } -impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> { - fn visit_binder>( +impl<'me, 'tcx> TypeVisitor> for ScopeInstantiator<'me, 'tcx> { + fn visit_binder>>( &mut self, t: &ty::Binder<'tcx, T>, ) -> ControlFlow { diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 9e6d5856e9276..90201233c823d 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -431,11 +431,11 @@ pub struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP: FnMut(ty::Region<'tcx>)> { pub op: OP, } -impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP> +impl<'tcx, OP> TypeVisitor> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP> where OP: FnMut(ty::Region<'tcx>), { - fn visit_binder>( + fn visit_binder>>( &mut self, t: &ty::Binder<'tcx, T>, ) -> ControlFlow { diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 65b90aa3d79d3..68ddbaf597031 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -121,7 +121,7 @@ impl<'a, 'tcx> UnresolvedTypeOrConstFinder<'a, 'tcx> { } } -impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeOrConstFinder<'a, 'tcx> { +impl<'a, 'tcx> TypeVisitor> for UnresolvedTypeOrConstFinder<'a, 'tcx> { type BreakTy = (ty::Term<'tcx>, Option); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { let t = self.infcx.shallow_resolve(t); diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 1c6ab6a082b99..44d4b22f65d02 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -1,8 +1,8 @@ use crate::traits; use crate::traits::project::Normalized; -use rustc_middle::ty; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable}; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{self, TyCtxt}; use std::fmt; use std::ops::ControlFlow; @@ -72,8 +72,10 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx } } -impl<'tcx, O: TypeVisitable<'tcx>> TypeVisitable<'tcx> for traits::Obligation<'tcx, O> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +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_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index b0a5d3674ad27..fe334cd982a67 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1144,7 +1144,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { struct ProhibitOpaqueTypes; - impl<'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueTypes { + impl<'tcx> ty::visit::TypeVisitor> for ProhibitOpaqueTypes { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs index 1f95661ce9d5f..f40f852cabfe1 100644 --- a/compiler/rustc_macros/src/type_visitable.rs +++ b/compiler/rustc_macros/src/type_visitable.rs @@ -19,9 +19,9 @@ pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: s.bind_with(|_| synstructure::BindStyle::Move); s.bound_impl( - quote!(::rustc_middle::ty::visit::TypeVisitable<'tcx>), + quote!(::rustc_middle::ty::visit::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>), quote! { - fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<'tcx>>( + fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>( &self, __visitor: &mut __V ) -> ::std::ops::ControlFlow<__V::BreakTy> { diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 250f3d0797eb5..104bd7a18642a 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -86,9 +86,9 @@ macro_rules! TrivialTypeTraversalImpls { } } - impl<$tcx> $crate::ty::visit::TypeVisitable<$tcx> for $ty { + impl<$tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<$tcx>> for $ty { #[inline] - fn visit_with>( + fn visit_with>>( &self, _: &mut F) -> ::std::ops::ControlFlow @@ -133,7 +133,7 @@ macro_rules! EnumTypeTraversalImpl { } }; - (impl<$($p:tt),*> TypeVisitable<$tcx:tt> for $s:path { + (impl<$($p:tt),*> TypeVisitable<$tcx:ty> for $s:path { $($variants:tt)* } $(where $($wc:tt)*)*) => { impl<$($p),*> $crate::ty::visit::TypeVisitable<$tcx> for $s diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 10ac7e0d39af6..11424b3eefd49 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2751,8 +2751,11 @@ impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { } } -impl<'tcx> TypeVisitable<'tcx> for UserTypeProjection { - fn visit_with>(&self, visitor: &mut Vs) -> ControlFlow { +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. } diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs index d44c6809bd830..55851e3f41ac7 100644 --- a/compiler/rustc_middle/src/mir/type_visitable.rs +++ b/compiler/rustc_middle/src/mir/type_visitable.rs @@ -2,8 +2,8 @@ use super::*; -impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix { - fn visit_with>(&self, _: &mut V) -> ControlFlow { +impl<'tcx, R: Idx, C: Idx> TypeVisitable> for BitMatrix { + fn visit_with>>(&self, _: &mut V) -> ControlFlow { ControlFlow::Continue(()) } } diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 63f9c32f0a74b..347b4545ed04a 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -2,7 +2,9 @@ use std::ops::ControlFlow; use rustc_data_structures::intern::Interned; -use crate::ty::{FallibleTypeFolder, Ty, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor}; +use crate::ty::{ + FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, +}; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>); @@ -43,8 +45,8 @@ impl<'tcx> TypeFoldable<'tcx> for ExternalConstraints<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for ExternalConstraints<'tcx> { - fn visit_with>( +impl<'tcx> TypeVisitable> for ExternalConstraints<'tcx> { + fn visit_with>>( &self, visitor: &mut V, ) -> std::ops::ControlFlow { diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index cd9b927014077..d074df529f773 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -94,7 +94,7 @@ pub trait IsSuggestable<'tcx>: Sized { impl<'tcx, T> IsSuggestable<'tcx> for T where - T: TypeVisitable<'tcx> + TypeFoldable<'tcx>, + T: TypeVisitable> + TypeFoldable<'tcx>, { fn is_suggestable(self, tcx: TyCtxt<'tcx>, infer_suggestable: bool) -> bool { self.visit_with(&mut IsSuggestableVisitor { tcx, infer_suggestable }).is_continue() @@ -447,7 +447,7 @@ pub struct IsSuggestableVisitor<'tcx> { infer_suggestable: bool, } -impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> { +impl<'tcx> TypeVisitor> for IsSuggestableVisitor<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 8a0019bc0127c..0fe62c78d6aa0 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -53,7 +53,7 @@ use std::collections::BTreeMap; /// /// To implement this conveniently, use the derive macro located in /// `rustc_macros`. -pub trait TypeFoldable<'tcx>: TypeVisitable<'tcx> { +pub trait TypeFoldable<'tcx>: TypeVisitable> { /// The entry point for folding. To fold a value `t` with a folder `f` /// call: `t.try_fold_with(f)`. /// diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f64c583ccebb7..a187131e5faa5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -914,8 +914,8 @@ impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for Term<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for Term<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { self.unpack().visit_with(visitor) } } @@ -1593,8 +1593,8 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +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) } @@ -1719,7 +1719,7 @@ impl<'tcx> ParamEnv<'tcx> { /// `where Box: Copy`, which are clearly never /// satisfiable. We generally want to behave as if they were true, /// although the surrounding function is never reachable. - pub fn and>(self, value: T) -> ParamEnvAnd<'tcx, T> { + pub fn and>>(self, value: T) -> ParamEnvAnd<'tcx, T> { match self.reveal() { Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index bbb4fd999bc76..fc095e9f01745 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2477,7 +2477,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { fn prepare_region_info(&mut self, value: &ty::Binder<'tcx, T>) where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { struct RegionNameCollector<'tcx> { used_region_names: FxHashSet, @@ -2493,7 +2493,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for RegionNameCollector<'tcx> { + impl<'tcx> ty::visit::TypeVisitor> for RegionNameCollector<'tcx> { type BreakTy = (); fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index d30497b39efed..aaf34e762ae73 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -8,7 +8,8 @@ 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, Flags, InferConst, Lift, OuterExclusiveBinder, Term, TermKind, Ty, TyCtxt, + self, AliasTy, Flags, InferConst, Interner, Lift, OuterExclusiveBinder, Term, TermKind, Ty, + TyCtxt, }; use rustc_data_structures::functor::IdFunctor; use rustc_hir::def::Namespace; @@ -370,8 +371,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for ty::AdtDef<'tcx> { - fn visit_with>(&self, _visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for ty::AdtDef<'tcx> { + fn visit_with>>( + &self, + _visitor: &mut V, + ) -> ControlFlow { ControlFlow::Continue(()) } } @@ -385,8 +389,8 @@ impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for } } -impl<'tcx, T: TypeVisitable<'tcx>, U: TypeVisitable<'tcx>> TypeVisitable<'tcx> for (T, U) { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl, U: TypeVisitable> TypeVisitable for (T, U) { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.0.visit_with(visitor)?; self.1.visit_with(visitor) } @@ -407,10 +411,10 @@ impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> } } -impl<'tcx, A: TypeVisitable<'tcx>, B: TypeVisitable<'tcx>, C: TypeVisitable<'tcx>> - TypeVisitable<'tcx> for (A, B, C) +impl, B: TypeVisitable, C: TypeVisitable> TypeVisitable + for (A, B, C) { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.0.visit_with(visitor)?; self.1.visit_with(visitor)?; self.2.visit_with(visitor) @@ -424,10 +428,10 @@ EnumTypeTraversalImpl! { } where T: TypeFoldable<'tcx> } EnumTypeTraversalImpl! { - impl<'tcx, T> TypeVisitable<'tcx> for Option { + impl TypeVisitable for Option { (Some)(a), (None), - } where T: TypeVisitable<'tcx> + } where I: Interner, T: TypeVisitable } EnumTypeTraversalImpl! { @@ -437,10 +441,10 @@ EnumTypeTraversalImpl! { } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>, } EnumTypeTraversalImpl! { - impl<'tcx, T, E> TypeVisitable<'tcx> for Result { + impl TypeVisitable for Result { (Ok)(a), (Err)(a), - } where T: TypeVisitable<'tcx>, E: TypeVisitable<'tcx>, + } where I: Interner, T: TypeVisitable, E: TypeVisitable, } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { @@ -483,8 +487,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Rc { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl> TypeVisitable for Rc { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } } @@ -529,8 +533,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc { } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Arc { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl> TypeVisitable for Arc { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } } @@ -541,8 +545,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl> TypeVisitable for Box { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } } @@ -553,14 +557,14 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl> TypeVisitable for Vec { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl> TypeVisitable for &[T] { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } } @@ -571,8 +575,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<[T]> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl> TypeVisitable for Box<[T]> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } } @@ -583,8 +587,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for ty::Binder<'tcx, T> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx, T: TypeVisitable>> TypeVisitable> for ty::Binder<'tcx, T> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_binder(self) } } @@ -598,8 +602,13 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<'tcx> for ty::Binder<'tcx, T> { - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx, T: TypeVisitable>> TypeSuperVisitable> + for ty::Binder<'tcx, T> +{ + fn super_visit_with>>( + &self, + visitor: &mut V, + ) -> ControlFlow { self.as_ref().skip_binder().visit_with(visitor) } } @@ -628,8 +637,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for Ty<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for Ty<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_ty(*self) } } @@ -684,8 +693,11 @@ impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> { } } -impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> { - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeSuperVisitable> for Ty<'tcx> { + fn super_visit_with>>( + &self, + visitor: &mut V, + ) -> ControlFlow { match self.kind() { ty::RawPtr(ref tm) => tm.visit_with(visitor), ty::Array(typ, sz) => { @@ -734,8 +746,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for ty::Region<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for ty::Region<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_region(*self) } } @@ -749,8 +761,11 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> { } } -impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> { - fn super_visit_with>(&self, _visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeSuperVisitable> for ty::Region<'tcx> { + fn super_visit_with>>( + &self, + _visitor: &mut V, + ) -> ControlFlow { ControlFlow::Continue(()) } } @@ -761,8 +776,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for ty::Predicate<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for ty::Predicate<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_predicate(*self) } @@ -787,8 +802,11 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ty::Predicate<'tcx> { } } -impl<'tcx> TypeSuperVisitable<'tcx> for ty::Predicate<'tcx> { - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeSuperVisitable> for ty::Predicate<'tcx> { + fn super_visit_with>>( + &self, + visitor: &mut V, + ) -> ControlFlow { self.kind().visit_with(visitor) } } @@ -805,8 +823,8 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec } } -impl<'tcx, T: TypeVisitable<'tcx>, I: Idx> TypeVisitable<'tcx> for IndexVec { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl, Ix: Idx> TypeVisitable for IndexVec { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } } @@ -817,8 +835,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for ty::Const<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for ty::Const<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { visitor.visit_const(*self) } } @@ -838,8 +856,11 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> { } } -impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> { - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { + fn super_visit_with>>( + &self, + visitor: &mut V, + ) -> ControlFlow { self.ty().visit_with(visitor)?; self.kind().visit_with(visitor) } @@ -851,20 +872,26 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for InferConst<'tcx> { - fn visit_with>(&self, _visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for InferConst<'tcx> { + fn visit_with>>( + &self, + _visitor: &mut V, + ) -> ControlFlow { ControlFlow::Continue(()) } } -impl<'tcx> TypeSuperVisitable<'tcx> for ty::UnevaluatedConst<'tcx> { - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeSuperVisitable> for ty::UnevaluatedConst<'tcx> { + fn super_visit_with>>( + &self, + visitor: &mut V, + ) -> ControlFlow { self.substs.visit_with(visitor) } } -impl<'tcx> TypeVisitable<'tcx> for TyAndLayout<'tcx, Ty<'tcx>> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +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/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ab9f4554766af..906b9265cb2e6 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -977,7 +977,7 @@ pub struct Binder<'tcx, T>(T, &'tcx List); impl<'tcx, T> Binder<'tcx, T> where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { /// Wraps `value` in a binder, asserting that `value` does not /// contain any bound vars that would be bound by the @@ -1045,14 +1045,14 @@ impl<'tcx, T> Binder<'tcx, T> { Binder(value, self.1) } - pub fn map_bound_ref>(&self, f: F) -> Binder<'tcx, U> + pub fn map_bound_ref>>(&self, f: F) -> Binder<'tcx, U> where F: FnOnce(&T) -> U, { self.as_ref().map_bound(f) } - pub fn map_bound>(self, f: F) -> Binder<'tcx, U> + pub fn map_bound>>(self, f: F) -> Binder<'tcx, U> where F: FnOnce(T) -> U, { @@ -1064,7 +1064,10 @@ impl<'tcx, T> Binder<'tcx, T> { Binder(value, self.1) } - pub fn try_map_bound, E>(self, f: F) -> Result, E> + pub fn try_map_bound>, E>( + self, + f: F, + ) -> Result, E> where F: FnOnce(T) -> Result, { @@ -1087,7 +1090,7 @@ impl<'tcx, T> Binder<'tcx, T> { /// in `bind`. This may be (debug) asserted in the future. pub fn rebind(&self, value: U) -> Binder<'tcx, U> where - U: TypeVisitable<'tcx>, + U: TypeVisitable>, { if cfg!(debug_assertions) { let mut validator = ValidateBoundVars::new(self.bound_vars()); @@ -1108,7 +1111,7 @@ impl<'tcx, T> Binder<'tcx, T> { /// would not be that useful.) pub fn no_bound_vars(self) -> Option where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) } } @@ -2030,7 +2033,7 @@ impl<'tcx> Ty<'tcx> { pub fn contains(self, other: Ty<'tcx>) -> bool { struct ContainsTyVisitor<'tcx>(Ty<'tcx>); - impl<'tcx> TypeVisitor<'tcx> for ContainsTyVisitor<'tcx> { + impl<'tcx> TypeVisitor> for ContainsTyVisitor<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { @@ -2048,7 +2051,7 @@ impl<'tcx> Ty<'tcx> { pub fn contains_closure(self) -> bool { struct ContainsClosureVisitor; - impl<'tcx> TypeVisitor<'tcx> for ContainsClosureVisitor { + impl<'tcx> TypeVisitor> for ContainsClosureVisitor { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index cf1bb5f8ac8db..5dbe215099143 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -237,8 +237,8 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for GenericArg<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { +impl<'tcx> TypeVisitable> for GenericArg<'tcx> { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), GenericArgKind::Type(ty) => ty.visit_with(visitor), @@ -535,9 +535,9 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List { +impl<'tcx, T: TypeVisitable>> TypeVisitable> for &'tcx ty::List { #[inline] - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } } @@ -554,7 +554,7 @@ pub struct EarlyBinder(pub T); /// For early binders, you should first call `subst` before using any visitors. impl<'tcx, T> !TypeFoldable<'tcx> for ty::EarlyBinder {} -impl<'tcx, T> !TypeVisitable<'tcx> for ty::EarlyBinder {} +impl<'tcx, T> !TypeVisitable> for ty::EarlyBinder {} impl EarlyBinder { pub fn as_ref(&self) -> EarlyBinder<&T> { diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 6cca4c3af9c47..8f7a13997961d 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -42,7 +42,6 @@ use crate::ty::{ self, Binder, BoundAtOrAboveBinder, BoundIndex, Flags, Interner, OuterExclusiveBinder, Ty, TyCtxt, TypeFlags, }; -use rustc_errors::ErrorGuaranteed; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; @@ -54,7 +53,7 @@ use std::ops::ControlFlow; /// /// To implement this conveniently, use the derive macro located in /// `rustc_macros`. -pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { +pub trait TypeVisitable: fmt::Debug + Clone { /// The entry point for visiting. To visit a value `t` with a visitor `v` /// call: `t.visit_with(v)`. /// @@ -65,7 +64,7 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { /// that calls a visitor method specifically for that type (such as /// `V::visit_ty`). This is where control transfers from `TypeFoldable` to /// `TypeVisitor`. - fn visit_with>(&self, visitor: &mut V) -> ControlFlow; + fn visit_with>(&self, visitor: &mut V) -> ControlFlow; /// Returns `true` if `self` has any late-bound regions that are either /// bound by `binder` or bound by some binder outside of `binder`. @@ -109,8 +108,8 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { fn references_error(&self) -> bool { self.has_type_flags(TypeFlags::HAS_ERROR) } - fn error_reported(&self) -> Result<(), ErrorGuaranteed> { - if self.references_error() { Err(TyCtxt::expect_failure()) } else { Ok(()) } + fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> { + if self.references_error() { Err(I::expect_failure()) } else { Ok(()) } } fn has_non_region_param(&self) -> bool { self.has_type_flags(TypeFlags::NEEDS_SUBST - TypeFlags::HAS_RE_PARAM) @@ -180,42 +179,54 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { } } -pub trait TypeSuperVisitable<'tcx>: TypeVisitable<'tcx> { +pub trait TypeSuperVisitable: TypeVisitable { /// Provides a default visit for a type of interest. This should only be /// called within `TypeVisitor` methods, when a non-custom traversal is /// desired for the value of the type of interest passed to that method. /// For example, in `MyVisitor::visit_ty(ty)`, it is valid to call /// `ty.super_visit_with(self)`, but any other visiting should be done /// with `xyz.visit_with(self)`. - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow; + fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow; } /// This trait is implemented for every visiting traversal. There is a visit /// method defined for every type of interest. Each such method has a default /// that recurses into the type's fields in a non-custom fashion. -pub trait TypeVisitor<'tcx>: Sized { +pub trait TypeVisitor: Sized { type BreakTy = !; - fn visit_binder>( - &mut self, - t: &Binder<'tcx, T>, - ) -> ControlFlow { + fn visit_binder>(&mut self, t: &I::Binder) -> ControlFlow + where + I::Binder: TypeSuperVisitable, + { t.super_visit_with(self) } - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow + where + I::Ty: TypeSuperVisitable, + { t.super_visit_with(self) } - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { + fn visit_region(&mut self, r: I::Region) -> ControlFlow + where + I::Region: TypeSuperVisitable, + { r.super_visit_with(self) } - fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { + fn visit_const(&mut self, c: I::Const) -> ControlFlow + where + I::Const: TypeSuperVisitable, + { c.super_visit_with(self) } - fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow { + fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow + where + I::Predicate: TypeSuperVisitable, + { p.super_visit_with(self) } } @@ -227,7 +238,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Invoke `callback` on every region appearing free in `value`. pub fn for_each_free_region( self, - value: &impl TypeVisitable<'tcx>, + value: &impl TypeVisitable>, mut callback: impl FnMut(ty::Region<'tcx>), ) { self.any_free_region_meets(value, |r| { @@ -239,7 +250,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `true` if `callback` returns true for every region appearing free in `value`. pub fn all_free_regions_meet( self, - value: &impl TypeVisitable<'tcx>, + value: &impl TypeVisitable>, mut callback: impl FnMut(ty::Region<'tcx>) -> bool, ) -> bool { !self.any_free_region_meets(value, |r| !callback(r)) @@ -248,7 +259,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `true` if `callback` returns true for some region appearing free in `value`. pub fn any_free_region_meets( self, - value: &impl TypeVisitable<'tcx>, + value: &impl TypeVisitable>, callback: impl FnMut(ty::Region<'tcx>) -> bool, ) -> bool { struct RegionVisitor { @@ -273,13 +284,13 @@ impl<'tcx> TyCtxt<'tcx> { callback: F, } - impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor + impl<'tcx, F> TypeVisitor> for RegionVisitor where F: FnMut(ty::Region<'tcx>) -> bool, { type BreakTy = (); - fn visit_binder>( + fn visit_binder>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow { @@ -326,7 +337,7 @@ impl<'tcx> TyCtxt<'tcx> { value: &Binder<'tcx, T>, ) -> FxHashSet where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { self.collect_late_bound_regions(value, true) } @@ -337,7 +348,7 @@ impl<'tcx> TyCtxt<'tcx> { value: &Binder<'tcx, T>, ) -> FxHashSet where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { self.collect_late_bound_regions(value, false) } @@ -348,7 +359,7 @@ impl<'tcx> TyCtxt<'tcx> { just_constraint: bool, ) -> FxHashSet where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { let mut collector = LateBoundRegionsCollector::new(just_constraint); let result = value.as_ref().skip_binder().visit_with(&mut collector); @@ -375,10 +386,10 @@ impl<'tcx> ValidateBoundVars<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { +impl<'tcx> TypeVisitor> for ValidateBoundVars<'tcx> { type BreakTy = (); - fn visit_binder>( + fn visit_binder>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow { @@ -487,13 +498,13 @@ struct HasEscapingVarsVisitor { outer_index: ty::DebruijnIndex, } -impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { +impl TypeVisitor for HasEscapingVarsVisitor { type BreakTy = FoundEscapingVars; - fn visit_binder>( - &mut self, - t: &Binder<'tcx, T>, - ) -> ControlFlow { + fn visit_binder>(&mut self, t: &I::Binder) -> ControlFlow + where + I::Binder: TypeSuperVisitable, + { self.outer_index.shift_in(1); let result = t.super_visit_with(self); self.outer_index.shift_out(1); @@ -501,7 +512,10 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { } #[inline] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow + where + I::Ty: TypeSuperVisitable, + { // If the outer-exclusive-binder is *strictly greater* than // `outer_index`, that means that `t` contains some content // bound at `outer_index` or above (because @@ -515,7 +529,10 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { } #[inline] - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { + fn visit_region(&mut self, r: I::Region) -> ControlFlow + where + I::Region: TypeSuperVisitable, + { // If the region is bound by `outer_index` or anything outside // of outer index, then it escapes the binders we have // visited. @@ -526,7 +543,10 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { } } - fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow { + fn visit_const(&mut self, ct: I::Const) -> ControlFlow + where + I::Const: TypeSuperVisitable, + { // we don't have a `visit_infer_const` callback, so we have to // hook in here to catch this case (annoying...), but // otherwise we do want to remember to visit the rest of the @@ -539,7 +559,10 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { } #[inline] - fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow { + fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow + where + I::Predicate: TypeSuperVisitable, + { if predicate.outer_exclusive_binder() > self.outer_index { ControlFlow::Break(FoundEscapingVars) } else { @@ -562,11 +585,14 @@ impl std::fmt::Debug for HasTypeFlagsVisitor { } } -impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { +impl TypeVisitor for HasTypeFlagsVisitor { type BreakTy = FoundFlags; #[inline] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow + where + I::Ty: TypeSuperVisitable, + { let flags = t.flags(); if flags.intersects(self.flags) { ControlFlow::Break(FoundFlags) @@ -576,7 +602,10 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { } #[inline] - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow { + fn visit_region(&mut self, r: I::Region) -> ControlFlow + where + I::Region: TypeSuperVisitable, + { let flags = r.flags(); if flags.intersects(self.flags) { ControlFlow::Break(FoundFlags) @@ -586,7 +615,10 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { } #[inline] - fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { + fn visit_const(&mut self, c: I::Const) -> ControlFlow + where + I::Const: TypeSuperVisitable, + { let flags = c.flags(); trace!(r.flags=?flags); if flags.intersects(self.flags) { @@ -597,7 +629,10 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { } #[inline] - fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow { + fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow + where + I::Predicate: TypeSuperVisitable, + { if predicate.flags().intersects(self.flags) { ControlFlow::Break(FoundFlags) } else { @@ -632,8 +667,8 @@ impl LateBoundRegionsCollector { } } -impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { - fn visit_binder>( +impl<'tcx> TypeVisitor> for LateBoundRegionsCollector { + fn visit_binder>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow { @@ -694,7 +729,7 @@ impl MaxUniverse { } } -impl<'tcx> TypeVisitor<'tcx> for MaxUniverse { +impl<'tcx> TypeVisitor> for MaxUniverse { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if let ty::Placeholder(placeholder) = t.kind() { self.max_universe = ty::UniverseIndex::from_u32( diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index cf13d4584a124..eefd4047f9560 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -296,7 +296,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } } -impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { +impl<'a, 'tcx> TypeVisitor> for MarkUsedGenericParams<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow { if !c.has_non_region_param() { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 4355286153223..f9d1d63a8cf86 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -81,7 +81,10 @@ trait DefIdVisitor<'tcx> { dummy: Default::default(), } } - fn visit(&mut self, ty_fragment: impl TypeVisitable<'tcx>) -> ControlFlow { + fn visit( + &mut self, + ty_fragment: impl TypeVisitable>, + ) -> ControlFlow { ty_fragment.visit_with(&mut self.skeleton()) } fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow { @@ -174,7 +177,7 @@ where } } -impl<'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'tcx, V> +impl<'tcx, V> TypeVisitor> for DefIdVisitorSkeleton<'_, 'tcx, V> where V: DefIdVisitor<'tcx> + ?Sized, { diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 00d1ff5ceedf7..c6698ae184904 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -204,7 +204,7 @@ impl<'tcx> SymbolMangler<'tcx> { print_value: impl FnOnce(&'a mut Self, &T) -> Result<&'a mut Self, !>, ) -> Result<&'a mut Self, !> where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { // FIXME(non-lifetime-binders): What to do here? let regions = if value.has_late_bound_regions() { diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 9f62f686af647..2e2954365e590 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -98,7 +98,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { struct ContainsTerm<'tcx> { term: ty::Term<'tcx>, } - impl<'tcx> TypeVisitor<'tcx> for ContainsTerm<'tcx> { + impl<'tcx> TypeVisitor> for ContainsTerm<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { if t.needs_infer() { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 61f508a7a0750..f13fe3eb70a89 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -627,7 +627,7 @@ enum OrphanCheckEarlyExit<'tcx> { LocalTy(Ty<'tcx>), } -impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> { +impl<'tcx> TypeVisitor> for OrphanChecker<'tcx> { type BreakTy = OrphanCheckEarlyExit<'tcx>; fn visit_region(&mut self, _r: ty::Region<'tcx>) -> ControlFlow { ControlFlow::Continue(()) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 786473457ae43..55631132568b9 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -171,7 +171,7 @@ fn satisfied_from_param_env<'tcx>( single_match: Option, ()>>, } - impl<'a, 'tcx> TypeVisitor<'tcx> for Visitor<'a, 'tcx> { + impl<'a, 'tcx> TypeVisitor> for Visitor<'a, 'tcx> { type BreakTy = (); fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow { debug!("is_const_evaluatable: candidate={:?}", c); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f6d0b9713f0d0..e5cd9f17145fc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2959,7 +2959,7 @@ impl ArgKind { struct HasNumericInferVisitor; -impl<'tcx> ty::TypeVisitor<'tcx> for HasNumericInferVisitor { +impl<'tcx> ty::TypeVisitor> for HasNumericInferVisitor { type BreakTy = (); fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 83458017e00f0..8fa533fbd325a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -141,7 +141,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( fn pred_known_to_hold_modulo_regions<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - pred: impl ToPredicate<'tcx> + TypeVisitable<'tcx>, + pred: impl ToPredicate<'tcx> + TypeVisitable>, span: Span, ) -> bool { let has_non_region_infer = pred.has_non_region_infer(); @@ -481,7 +481,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI generics: &'tcx ty::Generics, trait_item_def_id: DefId, } - impl<'tcx> ty::TypeVisitor<'tcx> for ReferencesOnlyParentGenerics<'tcx> { + impl<'tcx> ty::TypeVisitor> for ReferencesOnlyParentGenerics<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { // If this is a parameter from the trait item's own generics, then bail diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8f548acfd2eac..09fd352b0a676 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -784,7 +784,7 @@ fn receiver_is_dispatchable<'tcx>( infcx.predicate_must_hold_modulo_regions(&obligation) } -fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>( +fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable>>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, value: T, @@ -834,7 +834,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>( supertraits: Option>, } - impl<'tcx> TypeVisitor<'tcx> for IllegalSelfTypeVisitor<'tcx> { + impl<'tcx> TypeVisitor> for IllegalSelfTypeVisitor<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 53cae3e720c5a..d29692681b826 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -368,7 +368,10 @@ where result } -pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<'tcx>>(value: &T, reveal: Reveal) -> bool { +pub(crate) fn needs_normalization<'tcx, T: TypeVisitable>>( + value: &T, + reveal: Reveal, +) -> bool { match reveal { Reveal::UserFacing => value .has_type_flags(ty::TypeFlags::HAS_TY_PROJECTION | ty::TypeFlags::HAS_CT_PROJECTION), diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 17f90c1123e35..19101679360a2 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -115,8 +115,8 @@ struct MaxEscapingBoundVarVisitor { escaping: usize, } -impl<'tcx> TypeVisitor<'tcx> for MaxEscapingBoundVarVisitor { - fn visit_binder>( +impl<'tcx> TypeVisitor> for MaxEscapingBoundVarVisitor { + fn visit_binder>>( &mut self, t: &ty::Binder<'tcx, T>, ) -> ControlFlow { diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 69b965f3a389a..4ff71816e48ab 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -78,7 +78,7 @@ impl<'tcx> Search<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { +impl<'tcx> TypeVisitor> for Search<'tcx> { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 9c5db3314c5cd..fdef0a3b66306 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -918,8 +918,8 @@ impl<'tcx> BoundVarsCollector<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { - fn visit_binder>( +impl<'tcx> TypeVisitor> for BoundVarsCollector<'tcx> { + fn visit_binder>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow { @@ -1167,7 +1167,7 @@ impl PlaceholdersCollector { } } -impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { +impl<'tcx> TypeVisitor> for PlaceholdersCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Placeholder(p) if p.universe == self.universe_index => { diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs index 5836eb73bd94c..920ce8e655be0 100644 --- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs +++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::{BitSet, HybridBitSet}; use rustc_lint::LateContext; use rustc_middle::mir::{self, visit::Visitor as _, Mutability}; -use rustc_middle::ty::{self, visit::TypeVisitor}; +use rustc_middle::ty::{self, visit::TypeVisitor, TyCtxt}; use rustc_mir_dataflow::{impls::MaybeStorageLive, Analysis, ResultsCursor}; use std::borrow::Cow; use std::ops::ControlFlow; @@ -136,7 +136,7 @@ impl<'a, 'b, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'b, struct ContainsRegion; -impl TypeVisitor<'_> for ContainsRegion { +impl TypeVisitor> for ContainsRegion { type BreakTy = (); fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index c48d27b05f045..a6f14ddcc54a3 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -838,7 +838,7 @@ pub fn for_each_top_level_late_bound_region( index: u32, f: F, } - impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow> TypeVisitor<'tcx> for V { + impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow> TypeVisitor> for V { type BreakTy = B; fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { if let RegionKind::ReLateBound(idx, bound) = r.kind() && idx.as_u32() == self.index { @@ -847,7 +847,7 @@ pub fn for_each_top_level_late_bound_region( ControlFlow::Continue(()) } } - fn visit_binder>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow { + fn visit_binder>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow { self.index += 1; let res = t.super_visit_with(self); self.index -= 1; From 8754bd3114d683f441cea54096b48f9366e72d9b Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Sun, 5 Feb 2023 22:37:44 +0000 Subject: [PATCH 6/8] Make folding generic over the interner --- .../src/diagnostics/bound_region_errors.rs | 4 +- .../rustc_borrowck/src/region_infer/mod.rs | 2 +- .../src/region_infer/opaque_types.rs | 2 +- compiler/rustc_borrowck/src/renumber.rs | 4 +- .../src/type_check/canonical.rs | 4 +- .../src/type_check/constraint_conversion.rs | 2 +- .../rustc_borrowck/src/universal_regions.rs | 10 +- .../rustc_codegen_cranelift/src/common.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 4 +- .../src/interpret/eval_context.rs | 6 +- .../src/check/compare_impl_item.rs | 4 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 6 +- .../rustc_hir_analysis/src/collect/type_of.rs | 2 +- .../rustc_hir_analysis/src/hir_wf_check.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../src/mem_categorization.rs | 2 +- .../rustc_hir_typeck/src/method/confirm.rs | 4 +- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- compiler/rustc_hir_typeck/src/op.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 6 +- .../src/infer/canonical/canonicalizer.rs | 16 +- .../rustc_infer/src/infer/canonical/mod.rs | 4 +- .../src/infer/canonical/query_response.rs | 16 +- .../src/infer/canonical/substitute.rs | 10 +- compiler/rustc_infer/src/infer/combine.rs | 2 +- .../src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_infer/src/infer/freshen.rs | 2 +- compiler/rustc_infer/src/infer/fudge.rs | 4 +- .../src/infer/higher_ranked/mod.rs | 4 +- .../src/infer/lexical_region_resolve/mod.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 20 +-- .../rustc_infer/src/infer/opaque_types.rs | 2 +- compiler/rustc_infer/src/infer/resolve.rs | 8 +- .../src/traits/structural_impls.rs | 9 +- compiler/rustc_macros/src/type_foldable.rs | 4 +- compiler/rustc_middle/src/infer/canonical.rs | 4 +- compiler/rustc_middle/src/macros.rs | 8 +- compiler/rustc_middle/src/mir/mod.rs | 7 +- .../rustc_middle/src/mir/type_foldable.rs | 28 +++- compiler/rustc_middle/src/traits/query.rs | 4 +- compiler/rustc_middle/src/traits/solve.rs | 9 +- .../rustc_middle/src/ty/abstract_const.rs | 4 +- compiler/rustc_middle/src/ty/diagnostics.rs | 4 +- compiler/rustc_middle/src/ty/erase_regions.rs | 6 +- compiler/rustc_middle/src/ty/fold.rs | 142 ++++++++++------- compiler/rustc_middle/src/ty/instance.rs | 8 +- compiler/rustc_middle/src/ty/mod.rs | 11 +- .../src/ty/normalize_erasing_regions.rs | 16 +- compiler/rustc_middle/src/ty/opaque_types.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 20 +-- compiler/rustc_middle/src/ty/relate.rs | 2 +- .../rustc_middle/src/ty/structural_impls.rs | 146 ++++++++++-------- compiler/rustc_middle/src/ty/sty.rs | 4 +- compiler/rustc_middle/src/ty/subst.rs | 47 +++--- compiler/rustc_middle/src/ty/util.rs | 6 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_trait_selection/src/infer.rs | 12 +- .../src/solve/assembly.rs | 2 +- .../src/solve/infcx_ext.rs | 6 +- .../src/traits/auto_trait.rs | 2 +- .../src/traits/engine.rs | 4 +- .../src/traits/error_reporting/mod.rs | 10 +- .../src/traits/error_reporting/suggestions.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/project.rs | 35 +++-- .../src/traits/query/normalize.rs | 8 +- .../src/traits/query/type_op/mod.rs | 4 +- .../src/traits/query/type_op/normalize.rs | 2 +- .../src/traits/select/mod.rs | 2 +- compiler/rustc_traits/src/chalk/db.rs | 4 +- compiler/rustc_traits/src/chalk/lowering.rs | 18 ++- .../src/normalize_erasing_regions.rs | 2 +- compiler/rustc_traits/src/type_op.rs | 2 +- src/librustdoc/clean/auto_trait.rs | 2 +- 74 files changed, 442 insertions(+), 334 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 1550958ab8eee..245f6376f4815 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -106,7 +106,7 @@ impl<'tcx> ToUniverseInfo<'tcx> } } -impl<'tcx, T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx> ToUniverseInfo<'tcx> +impl<'tcx, T: Copy + fmt::Display + TypeFoldable> + 'tcx> ToUniverseInfo<'tcx> for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { @@ -258,7 +258,7 @@ struct NormalizeQuery<'tcx, T> { impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T> where - T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx, + T: Copy + fmt::Display + TypeFoldable> + 'tcx, { fn fallback_error( &self, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 2ae13990a4589..f104657e4ed49 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1278,7 +1278,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// we use this kind of hacky solution. fn normalize_to_scc_representatives(&self, tcx: TyCtxt<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { tcx.fold_regions(value, |r, _db| { let vid = self.to_region_vid(r); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index e0e814cfc0ac8..ef7fe192ccca7 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -179,7 +179,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// region names in error messages. pub(crate) fn name_regions(&self, tcx: TyCtxt<'tcx>, ty: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { tcx.fold_regions(ty, |region, _| match *region { ty::ReVar(vid) => { diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 084754830bdbf..0d1e349446d8f 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -32,7 +32,7 @@ pub fn renumber_mir<'tcx>( #[instrument(skip(infcx), level = "debug")] pub fn renumber_regions<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { infcx.tcx.fold_regions(value, |_region, _depth| { let origin = NllRegionVariableOrigin::Existential { from_forall: false }; @@ -47,7 +47,7 @@ struct NllVisitor<'a, 'tcx> { impl<'a, 'tcx> NllVisitor<'a, 'tcx> { fn renumber_regions(&mut self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { renumber_regions(self.infcx, value) } diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 2b81a35052d7b..1be20f1870706 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -2,7 +2,7 @@ use std::fmt; use rustc_infer::infer::{canonical::Canonical, InferOk}; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable}; +use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_span::def_id::DefId; use rustc_span::Span; use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput}; @@ -66,7 +66,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { canonical: &Canonical<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let old_universe = self.infcx.universe(); diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index e15d1b99ad205..9bc7ab7b65b9a 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -179,7 +179,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { /// /// FIXME: This should get removed once higher ranked region obligations /// are dealt with during trait solving. - fn replace_placeholders_with_nll>(&mut self, value: T) -> T { + fn replace_placeholders_with_nll>>(&mut self, value: T) -> T { if value.has_placeholders() { self.tcx.fold_regions(value, |r, _| match *r { ty::RePlaceholder(placeholder) => { diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 5380913f5c86a..c1342c01b0426 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -695,7 +695,7 @@ trait InferCtxtExt<'tcx> { value: T, ) -> T where - T: TypeFoldable<'tcx>; + T: TypeFoldable>; fn replace_bound_regions_with_nll_infer_vars( &self, @@ -705,7 +705,7 @@ trait InferCtxtExt<'tcx> { indices: &mut UniversalRegionIndices<'tcx>, ) -> T where - T: TypeFoldable<'tcx>; + T: TypeFoldable>; fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope( &self, @@ -727,7 +727,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { value: T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { self.tcx.fold_regions(value, |_region, _depth| self.next_nll_region_var(origin)) } @@ -741,7 +741,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { indices: &mut UniversalRegionIndices<'tcx>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| { debug!(?br); @@ -833,7 +833,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// returned by `to_region_vid`. pub fn fold_to_region_vids(&self, tcx: TyCtxt<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { tcx.fold_regions(value, |region, _| tcx.mk_region(ty::ReVar(self.to_region_vid(region)))) } diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index f41af3a9e6366..2df4e52f164df 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -336,7 +336,7 @@ impl<'tcx> HasTargetSpec for FunctionCx<'_, '_, 'tcx> { impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn monomorphize(&self, value: T) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable> + Copy, { self.instance.subst_mir_and_normalize_erasing_regions( self.tcx, diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index bb265b8289ed9..976b317fa1859 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -3,7 +3,7 @@ use crate::traits::*; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout}; -use rustc_middle::ty::{self, Instance, Ty, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_target::abi::call::{FnAbi, PassMode}; use std::iter; @@ -105,7 +105,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn monomorphize(&self, value: T) -> T where - T: Copy + TypeFoldable<'tcx>, + T: Copy + TypeFoldable>, { debug!("monomorphize: self.instance={:?}", self.instance); self.instance.subst_mir_and_normalize_erasing_regions( diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d13fed7a9c263..65f1ac3bfc9d7 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -489,7 +489,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Call this on things you got out of the MIR (so it is as generic as the current /// stack frame), to bring it into the proper environment for this interpreter. - pub(super) fn subst_from_current_frame_and_normalize_erasing_regions>( + pub(super) fn subst_from_current_frame_and_normalize_erasing_regions< + T: TypeFoldable>, + >( &self, value: T, ) -> Result> { @@ -498,7 +500,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Call this on things you got out of the MIR (so it is as generic as the provided /// stack frame), to bring it into the proper environment for this interpreter. - pub(super) fn subst_from_frame_and_normalize_erasing_regions>( + pub(super) fn subst_from_frame_and_normalize_erasing_regions>>( &self, frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, value: T, 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 21e7004181050..0569d3db39052 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -464,7 +464,7 @@ struct RemapLateBound<'a, 'tcx> { mapping: &'a FxHashMap, } -impl<'tcx> TypeFolder<'tcx> for RemapLateBound<'_, 'tcx> { +impl<'tcx> TypeFolder> for RemapLateBound<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -835,7 +835,7 @@ impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> { +impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { self.ocx.infcx.tcx } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 216582248c2a3..1cdc6119fe503 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -56,7 +56,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { // `ObligationCtxt::normalize`, but provides a nice `ObligationCauseCode`. fn normalize(&self, span: Span, loc: Option, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { self.ocx.normalize( &ObligationCause::new(span, self.body_def_id, ObligationCauseCode::WellFormed(loc)), @@ -560,7 +560,7 @@ fn augment_param_env<'tcx>( /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>; /// } /// ``` -fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>( +fn gather_gat_bounds<'tcx, T: TypeFoldable>>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, item_def_id: hir::OwnerId, @@ -762,7 +762,7 @@ struct GATSubstCollector<'tcx> { } impl<'tcx> GATSubstCollector<'tcx> { - fn visit>( + fn visit>>( gat: DefId, t: T, ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c5522c94874dd..6fef7acb36e0f 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -850,7 +850,7 @@ fn infer_placeholder_type<'a>( tcx: TyCtxt<'tcx>, } - impl<'tcx> TypeFolder<'tcx> for MakeNameable<'tcx> { + impl<'tcx> TypeFolder> for MakeNameable<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 9cf82b39ec947..6ee8b5f250d9d 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -189,7 +189,7 @@ struct EraseAllBoundRegions<'tcx> { // us an inaccurate span for an error message, but cannot // lead to unsoundness (we call `delay_span_bug` at the start // of `diagnostic_hir_wf_check`). -impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> { +impl<'tcx> TypeFolder> for EraseAllBoundRegions<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index f83ae5639ac36..7bc3dfdae884a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -315,7 +315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn normalize(&self, span: Span, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { self.register_infer_ok_obligations( self.at(&self.misc(span), self.param_env).normalize(value), diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 92240b66eb1d4..dd7252beae16c 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -127,7 +127,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { fn resolve_vars_if_possible(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { self.infcx.resolve_vars_if_possible(value) } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 65ca47bfe538b..c7ea8b0ba9b58 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::{self, SubstsRef}; -use rustc_middle::ty::{self, GenericParamDefKind, Ty}; +use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt}; use rustc_middle::ty::{InternalSubsts, UserSubsts, UserType}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::traits; @@ -627,7 +627,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn replace_bound_vars_with_fresh_vars(&self, value: ty::Binder<'tcx, T>) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable> + Copy, { self.fcx.replace_bound_vars_with_fresh_vars(self.span, infer::FnCall, value) } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 0b30bf957a3d3..bdb21d24aa43b 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1968,7 +1968,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// so forth. fn erase_late_bound_regions(&self, value: ty::Binder<'tcx, T>) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { self.tcx.erase_late_bound_regions(value) } diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index ba72aefe39c16..29fe9c0b40b7c 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -963,7 +963,7 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool struct TypeParamEraser<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, Span); -impl<'tcx> TypeFolder<'tcx> for TypeParamEraser<'_, 'tcx> { +impl<'tcx> TypeFolder> for TypeParamEraser<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.0.tcx } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 1a11f64ccbd32..58310504b3792 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -685,7 +685,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn resolve(&mut self, x: T, span: &dyn Locatable) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let mut resolver = Resolver::new(self.fcx, span, self.body); let x = x.fold_with(&mut resolver); @@ -763,7 +763,7 @@ struct EraseEarlyRegions<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for EraseEarlyRegions<'tcx> { +impl<'tcx> TypeFolder> for EraseEarlyRegions<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } @@ -779,7 +779,7 @@ impl<'tcx> TypeFolder<'tcx> for EraseEarlyRegions<'tcx> { } } -impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { +impl<'cx, 'tcx> TypeFolder> for Resolver<'cx, 'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 51c73adf41534..f4dc6534a0684 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -41,7 +41,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -60,7 +60,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -100,7 +100,7 @@ impl<'tcx> InferCtxt<'tcx> { /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#canonicalizing-the-query-result pub fn canonicalize_response(&self, value: V) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable>, { let mut query_state = OriginalQueryValues::default(); Canonicalizer::canonicalize( @@ -114,7 +114,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn canonicalize_user_type_annotation(&self, value: V) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable>, { let mut query_state = OriginalQueryValues::default(); Canonicalizer::canonicalize( @@ -136,7 +136,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -328,14 +328,14 @@ struct Canonicalizer<'cx, 'tcx> { binder_index: ty::DebruijnIndex, } -impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { +impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } fn fold_binder(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { self.binder_index.shift_in(1); let t = t.super_fold_with(self); @@ -526,7 +526,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable>, { let needs_canonical_flags = if canonicalize_region_mode.any() { TypeFlags::NEEDS_INFER | diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index f7e3e4a1cc09e..7c21bb641b27d 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -26,7 +26,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVari use rustc_index::vec::IndexVec; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::GenericArg; -use rustc_middle::ty::{self, List}; +use rustc_middle::ty::{self, List, TyCtxt}; use rustc_span::source_map::Span; pub use rustc_middle::infer::canonical::*; @@ -55,7 +55,7 @@ impl<'tcx> InferCtxt<'tcx> { canonical: &Canonical<'tcx, T>, ) -> (T, CanonicalVarValues<'tcx>) where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { // For each universe that is referred to in the incoming // query, create a universe in our local inference context. In diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 3e8e7734a5a5d..5dfd6186ec46b 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -59,7 +59,7 @@ impl<'tcx> InferCtxt<'tcx> { fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Fallible> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, { let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?; @@ -85,7 +85,7 @@ impl<'tcx> InferCtxt<'tcx> { answer: T, ) -> Canonical<'tcx, QueryResponse<'tcx, T>> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable>, { self.canonicalize_response(QueryResponse { var_values: inference_vars, @@ -106,7 +106,7 @@ impl<'tcx> InferCtxt<'tcx> { fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result, NoSolution> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable>, { let tcx = self.tcx; @@ -180,7 +180,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, R> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable>, { let InferOk { value: result_subst, mut obligations } = self.query_response_substitution(cause, param_env, original_values, query_response)?; @@ -242,7 +242,7 @@ impl<'tcx> InferCtxt<'tcx> { output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, ) -> InferResult<'tcx, R> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable>, { let InferOk { value: result_subst, mut obligations } = self .query_response_substitution_guess(cause, param_env, original_values, query_response)?; @@ -360,7 +360,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable>, { debug!( "query_response_substitution(original_values={:#?}, query_response={:#?})", @@ -405,7 +405,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable>, { debug!( "query_response_substitution_guess(original_values={:#?}, query_response={:#?})", @@ -527,7 +527,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, ()> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable>, { // A closure that yields the result value for the given // canonical variable; this is taken from diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs index e77f2d37b7dae..c5c6fc41b9e91 100644 --- a/compiler/rustc_infer/src/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs @@ -16,7 +16,7 @@ pub(super) trait CanonicalExt<'tcx, V> { /// with the value given in `var_values`. fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where - V: TypeFoldable<'tcx>; + V: TypeFoldable>; /// Allows one to apply a substitute to some subset of /// `self.value`. Invoke `projection_fn` with `self.value` to get @@ -31,13 +31,13 @@ pub(super) trait CanonicalExt<'tcx, V> { projection_fn: impl FnOnce(&V) -> T, ) -> T where - T: TypeFoldable<'tcx>; + T: TypeFoldable>; } impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> { fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where - V: TypeFoldable<'tcx>, + V: TypeFoldable>, { self.substitute_projected(tcx, var_values, |value| value.clone()) } @@ -49,7 +49,7 @@ impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> { projection_fn: impl FnOnce(&V) -> T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { assert_eq!(self.variables.len(), var_values.len()); let value = projection_fn(&self.value); @@ -66,7 +66,7 @@ pub(super) fn substitute_value<'tcx, T>( value: T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { if var_values.var_values.is_empty() { value diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index a567b6acdbeeb..ad75065e82843 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -811,7 +811,7 @@ struct ConstInferUnifier<'cx, 'tcx> { target_vid: ty::ConstVid<'tcx>, } -impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> { +impl<'tcx> FallibleTypeFolder> for ConstInferUnifier<'_, 'tcx> { type Error = TypeError<'tcx>; fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 431d420b6e2eb..45fa0a0611f73 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2116,7 +2116,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } /// Returns a string of the form "expected `{}`, found `{}`". - fn expected_found_str>( + fn expected_found_str>>( &self, exp_found: ty::error::ExpectedFound, ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option, Option)> diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 83d71edc2abd9..9c29296c40d1c 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -110,7 +110,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index 6dd6c4e1f5ee8..d08892d16b508 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -98,7 +98,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn fudge_inference_if_ok(&self, f: F) -> Result where F: FnOnce() -> Result, - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let variable_lengths = self.variable_lengths(); let (mut fudger, value) = self.probe(|_| { @@ -175,7 +175,7 @@ pub struct InferenceFudger<'a, 'tcx> { const_vars: (Range>, Vec), } -impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for InferenceFudger<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index 31be107b35472..96f22b334b30f 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -6,7 +6,7 @@ use super::{HigherRankedType, InferCtxt}; use crate::infer::CombinedSnapshot; use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::{self, Binder, TypeFoldable}; +use rustc_middle::ty::{self, Binder, TyCtxt, TypeFoldable}; impl<'a, 'tcx> CombineFields<'a, 'tcx> { /// Checks whether `for<..> sub <: for<..> sup` holds. @@ -72,7 +72,7 @@ impl<'tcx> InferCtxt<'tcx> { #[instrument(level = "debug", skip(self), ret)] pub fn replace_bound_vars_with_placeholders(&self, binder: ty::Binder<'tcx, T>) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable> + Copy, { if let Some(inner) = binder.no_bound_vars() { return inner; diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index ce8aec8044bae..2f633e5471d9d 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -1018,7 +1018,7 @@ impl<'tcx> fmt::Debug for RegionAndOrigin<'tcx> { impl<'tcx> LexicalRegionResolutions<'tcx> { fn normalize(&self, tcx: TyCtxt<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r)) } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 8ea4feae6460e..ec93c31e0d1c6 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -616,7 +616,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { canonical: &Canonical<'tcx, T>, ) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>) where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let infcx = self.build(); let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); @@ -696,7 +696,7 @@ impl<'tcx> InferCtxt<'tcx> { self.in_snapshot.get() } - pub fn freshen>(&self, t: T) -> T { + pub fn freshen>>(&self, t: T) -> T { t.fold_with(&mut self.freshener()) } @@ -1370,7 +1370,7 @@ impl<'tcx> InferCtxt<'tcx> { /// will be resolving them as well, e.g. in a loop). pub fn shallow_resolve(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { value.fold_with(&mut ShallowResolver { infcx: self }) } @@ -1387,7 +1387,7 @@ impl<'tcx> InferCtxt<'tcx> { /// at will. pub fn resolve_vars_if_possible(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { if !value.needs_infer() { return value; // Avoid duplicated subst-folding. @@ -1398,7 +1398,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn resolve_numeric_literals_with_default(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { if !value.needs_infer() { return value; // Avoid duplicated subst-folding. @@ -1428,7 +1428,7 @@ impl<'tcx> InferCtxt<'tcx> { } } - pub fn fully_resolve>(&self, value: T) -> FixupResult<'tcx, T> { + pub fn fully_resolve>>(&self, value: T) -> FixupResult<'tcx, T> { /*! * Attempts to resolve all type/region/const variables in * `value`. Region inference must have been run already (e.g., @@ -1454,7 +1454,7 @@ impl<'tcx> InferCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable> + Copy, { if let Some(inner) = value.no_bound_vars() { return inner; @@ -1844,7 +1844,7 @@ struct InferenceLiteralEraser<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'tcx> { +impl<'tcx> TypeFolder> for InferenceLiteralEraser<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1862,7 +1862,7 @@ struct ShallowResolver<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, } -impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for ShallowResolver<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -2047,7 +2047,7 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( idx: u32, } - impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> { + impl<'tcx> TypeFolder> for ReplaceParamAndInferWithPlaceholder<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 90201233c823d..4478b4087cebf 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -45,7 +45,7 @@ pub struct OpaqueTypeDecl<'tcx> { impl<'tcx> InferCtxt<'tcx> { /// This is a backwards compatibility hack to prevent breaking changes from /// lazy TAIT around RPIT handling. - pub fn replace_opaque_types_with_inference_vars>( + pub fn replace_opaque_types_with_inference_vars>>( &self, value: T, body_id: LocalDefId, diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 68ddbaf597031..cfe9a16e14fea 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -26,7 +26,7 @@ impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for OpportunisticVarResolver<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -67,7 +67,7 @@ impl<'a, 'tcx> OpportunisticRegionResolver<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for OpportunisticRegionResolver<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -194,7 +194,7 @@ impl<'a, 'tcx> TypeVisitor> for UnresolvedTypeOrConstFinder<'a, 'tc /// then an `Err` result is returned. pub fn fully_resolve<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> FixupResult<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { value.try_fold_with(&mut FullTypeResolver { infcx }) } @@ -205,7 +205,7 @@ struct FullTypeResolver<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, } -impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { +impl<'a, 'tcx> FallibleTypeFolder> for FullTypeResolver<'a, 'tcx> { type Error = FixupError<'tcx>; fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 44d4b22f65d02..3a5273b0359e4 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -61,8 +61,13 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { /////////////////////////////////////////////////////////////////////////// // TypeFoldable implementations. -impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> { - fn try_fold_with>(self, folder: &mut F) -> Result { +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, diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index 23e619221aab7..9e806de25e177 100644 --- a/compiler/rustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs @@ -23,9 +23,9 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:: }); s.bound_impl( - quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>), + quote!(::rustc_middle::ty::fold::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>), quote! { - fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>( + fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>( self, __folder: &mut __F ) -> Result { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 6e130bbf7d828..310b85dee50eb 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -42,8 +42,8 @@ pub struct Canonical<'tcx, V> { pub type CanonicalVarInfos<'tcx> = &'tcx List>; -impl<'tcx> ty::TypeFoldable<'tcx> for CanonicalVarInfos<'tcx> { - fn try_fold_with>( +impl<'tcx> ty::TypeFoldable> for CanonicalVarInfos<'tcx> { + fn try_fold_with>>( self, folder: &mut F, ) -> Result { diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 104bd7a18642a..19f778e0ced48 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -69,8 +69,8 @@ macro_rules! CloneLiftImpls { macro_rules! TrivialTypeTraversalImpls { (for <$tcx:lifetime> { $($ty:ty,)+ }) => { $( - impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty { - fn try_fold_with>( + impl<$tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty { + fn try_fold_with>>( self, _: &mut F, ) -> ::std::result::Result { @@ -78,7 +78,7 @@ macro_rules! TrivialTypeTraversalImpls { } #[inline] - fn fold_with>( + fn fold_with>>( self, _: &mut F, ) -> Self { @@ -118,7 +118,7 @@ macro_rules! TrivialTypeTraversalAndLiftImpls { #[macro_export] macro_rules! EnumTypeTraversalImpl { - (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { + (impl<$($p:tt),*> TypeFoldable<$tcx:ty> for $s:path { $($variants:tt)* } $(where $($wc:tt)*)*) => { impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 11424b3eefd49..29e28c0b9569d 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2742,8 +2742,11 @@ impl UserTypeProjection { } } -impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { - fn try_fold_with>(self, folder: &mut F) -> Result { +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)?, diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 0705b4cff53ad..da8744c6ebdae 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -30,26 +30,38 @@ TrivialTypeTraversalImpls! { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx [InlineAsmTemplatePiece] { - fn try_fold_with>(self, _folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for &'tcx [InlineAsmTemplatePiece] { + fn try_fold_with>>( + self, + _folder: &mut F, + ) -> Result { Ok(self) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx [Span] { - fn try_fold_with>(self, _folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for &'tcx [Span] { + fn try_fold_with>>( + self, + _folder: &mut F, + ) -> Result { Ok(self) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for &'tcx ty::List> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v)) } } -impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix { - fn try_fold_with>(self, _: &mut F) -> Result { +impl<'tcx, R: Idx, C: Idx> TypeFoldable> for BitMatrix { + fn try_fold_with>>( + self, + _: &mut F, + ) -> Result { Ok(self) } } diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 615154a55e586..c4f8718754f5f 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -14,7 +14,7 @@ use rustc_span::source_map::Span; pub mod type_op { use crate::ty::fold::TypeFoldable; - use crate::ty::{Predicate, Ty, UserType}; + use crate::ty::{Predicate, Ty, TyCtxt, UserType}; use std::fmt; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)] @@ -64,7 +64,7 @@ pub mod type_op { impl<'tcx, T> Normalize where - T: fmt::Debug + TypeFoldable<'tcx>, + T: fmt::Debug + TypeFoldable>, { pub fn new(value: T) -> Self { Self { value } diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 347b4545ed04a..62dbf27f2cdba 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -25,8 +25,11 @@ pub struct ExternalConstraintsData<'tcx> { pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, } -impl<'tcx> TypeFoldable<'tcx> for ExternalConstraints<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for ExternalConstraints<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { Ok(FallibleTypeFolder::tcx(folder).intern_external_constraints(ExternalConstraintsData { regions: (), opaque_types: self @@ -37,7 +40,7 @@ impl<'tcx> TypeFoldable<'tcx> for ExternalConstraints<'tcx> { })) } - fn fold_with>(self, folder: &mut F) -> Self { + fn fold_with>>(self, folder: &mut F) -> Self { TypeFolder::tcx(folder).intern_external_constraints(ExternalConstraintsData { regions: (), opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(), diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 5de758ad9babd..d7962fcad71c8 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -48,12 +48,12 @@ impl<'tcx> TyCtxt<'tcx> { Ok(ac?.map(|ac| EarlyBinder(ac))) } - pub fn expand_abstract_consts>(self, ac: T) -> T { + pub fn expand_abstract_consts>>(self, ac: T) -> T { struct Expander<'tcx> { tcx: TyCtxt<'tcx>, } - impl<'tcx> TypeFolder<'tcx> for Expander<'tcx> { + impl<'tcx> TypeFolder> for Expander<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index d074df529f773..a347cbda70c54 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -94,7 +94,7 @@ pub trait IsSuggestable<'tcx>: Sized { impl<'tcx, T> IsSuggestable<'tcx> for T where - T: TypeVisitable> + TypeFoldable<'tcx>, + T: TypeVisitable> + TypeFoldable>, { fn is_suggestable(self, tcx: TyCtxt<'tcx>, infer_suggestable: bool) -> bool { self.visit_with(&mut IsSuggestableVisitor { tcx, infer_suggestable }).is_continue() @@ -522,7 +522,7 @@ pub struct MakeSuggestableFolder<'tcx> { infer_suggestable: bool, } -impl<'tcx> FallibleTypeFolder<'tcx> for MakeSuggestableFolder<'tcx> { +impl<'tcx> FallibleTypeFolder> for MakeSuggestableFolder<'tcx> { type Error = (); fn tcx(&self) -> TyCtxt<'tcx> { diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 9e4f90caab0b5..b6bfb4073d9eb 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -18,7 +18,7 @@ impl<'tcx> TyCtxt<'tcx> { /// subtyping, but they are anonymized and normalized as well).. pub fn erase_regions(self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { // If there's nothing to erase avoid performing the query at all if !value.has_type_flags(TypeFlags::HAS_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { @@ -35,7 +35,7 @@ struct RegionEraserVisitor<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { +impl<'tcx> TypeFolder> for RegionEraserVisitor<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } @@ -46,7 +46,7 @@ impl<'tcx> TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { fn fold_binder(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let u = self.tcx.anonymize_bound_vars(t); u.super_fold_with(self) diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 0fe62c78d6aa0..5c3c0a3a45ffd 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -42,7 +42,7 @@ //! - ty.super_fold_with(folder) //! - u.fold_with(folder) //! ``` -use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitable}; +use crate::ty::{self, Binder, BoundTy, Interner, Ty, TyCtxt, TypeVisitable}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; @@ -53,7 +53,7 @@ use std::collections::BTreeMap; /// /// To implement this conveniently, use the derive macro located in /// `rustc_macros`. -pub trait TypeFoldable<'tcx>: TypeVisitable> { +pub trait TypeFoldable: TypeVisitable { /// The entry point for folding. To fold a value `t` with a folder `f` /// call: `t.try_fold_with(f)`. /// @@ -64,25 +64,25 @@ pub trait TypeFoldable<'tcx>: TypeVisitable> { /// calls a folder method specifically for that type (such as /// `F::try_fold_ty`). This is where control transfers from `TypeFoldable` /// to `TypeFolder`. - fn try_fold_with>(self, folder: &mut F) -> Result; + fn try_fold_with>(self, folder: &mut F) -> Result; /// A convenient alternative to `try_fold_with` for use with infallible /// folders. Do not override this method, to ensure coherence with /// `try_fold_with`. - fn fold_with>(self, folder: &mut F) -> Self { + fn fold_with>(self, folder: &mut F) -> Self { self.try_fold_with(folder).into_ok() } } // This trait is implemented for types of interest. -pub trait TypeSuperFoldable<'tcx>: TypeFoldable<'tcx> { +pub trait TypeSuperFoldable: TypeFoldable { /// Provides a default fold for a type of interest. This should only be /// called within `TypeFolder` methods, when a non-custom traversal is /// desired for the value of the type of interest passed to that method. /// For example, in `MyFolder::try_fold_ty(ty)`, it is valid to call /// `ty.try_super_fold_with(self)`, but any other folding should be done /// with `xyz.try_fold_with(self)`. - fn try_super_fold_with>( + fn try_super_fold_with>( self, folder: &mut F, ) -> Result; @@ -90,7 +90,7 @@ pub trait TypeSuperFoldable<'tcx>: TypeFoldable<'tcx> { /// A convenient alternative to `try_super_fold_with` for use with /// infallible folders. Do not override this method, to ensure coherence /// with `try_super_fold_with`. - fn super_fold_with>(self, folder: &mut F) -> Self { + fn super_fold_with>(self, folder: &mut F) -> Self { self.try_super_fold_with(folder).into_ok() } } @@ -104,29 +104,42 @@ pub trait TypeSuperFoldable<'tcx>: TypeFoldable<'tcx> { /// A blanket implementation of [`FallibleTypeFolder`] will defer to /// the infallible methods of this trait to ensure that the two APIs /// are coherent. -pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> { - fn tcx(&self) -> TyCtxt<'tcx>; +pub trait TypeFolder: FallibleTypeFolder { + fn tcx(&self) -> I; - fn fold_binder(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> + fn fold_binder(&mut self, t: I::Binder) -> I::Binder where - T: TypeFoldable<'tcx>, + T: TypeFoldable, + I::Binder: TypeSuperFoldable, { t.super_fold_with(self) } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + fn fold_ty(&mut self, t: I::Ty) -> I::Ty + where + I::Ty: TypeSuperFoldable, + { t.super_fold_with(self) } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + fn fold_region(&mut self, r: I::Region) -> I::Region + where + I::Region: TypeSuperFoldable, + { r.super_fold_with(self) } - fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { + fn fold_const(&mut self, c: I::Const) -> I::Const + where + I::Const: TypeSuperFoldable, + { c.super_fold_with(self) } - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { + fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate + where + I::Predicate: TypeSuperFoldable, + { p.super_fold_with(self) } } @@ -138,70 +151,93 @@ pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> { /// A blanket implementation of this trait (that defers to the relevant /// method of [`TypeFolder`]) is provided for all infallible folders in /// order to ensure the two APIs are coherent. -pub trait FallibleTypeFolder<'tcx>: Sized { +pub trait FallibleTypeFolder: Sized { type Error; - fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; + fn tcx(&self) -> I; - fn try_fold_binder(&mut self, t: Binder<'tcx, T>) -> Result, Self::Error> + fn try_fold_binder(&mut self, t: I::Binder) -> Result, Self::Error> where - T: TypeFoldable<'tcx>, + T: TypeFoldable, + I::Binder: TypeSuperFoldable, { t.try_super_fold_with(self) } - fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { + fn try_fold_ty(&mut self, t: I::Ty) -> Result + where + I::Ty: TypeSuperFoldable, + { t.try_super_fold_with(self) } - fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { + fn try_fold_region(&mut self, r: I::Region) -> Result + where + I::Region: TypeSuperFoldable, + { r.try_super_fold_with(self) } - fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result, Self::Error> { + fn try_fold_const(&mut self, c: I::Const) -> Result + where + I::Const: TypeSuperFoldable, + { c.try_super_fold_with(self) } - fn try_fold_predicate( - &mut self, - p: ty::Predicate<'tcx>, - ) -> Result, Self::Error> { + fn try_fold_predicate(&mut self, p: I::Predicate) -> Result + where + I::Predicate: TypeSuperFoldable, + { p.try_super_fold_with(self) } } // This blanket implementation of the fallible trait for infallible folders // delegates to infallible methods to ensure coherence. -impl<'tcx, F> FallibleTypeFolder<'tcx> for F +impl FallibleTypeFolder for F where - F: TypeFolder<'tcx>, + F: TypeFolder, { type Error = !; - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + fn tcx(&self) -> I { TypeFolder::tcx(self) } - fn try_fold_binder(&mut self, t: Binder<'tcx, T>) -> Result, !> + fn try_fold_binder(&mut self, t: I::Binder) -> Result, !> where - T: TypeFoldable<'tcx>, + T: TypeFoldable, + I::Binder: TypeSuperFoldable, { Ok(self.fold_binder(t)) } - fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result, !> { + fn try_fold_ty(&mut self, t: I::Ty) -> Result + where + I::Ty: TypeSuperFoldable, + { Ok(self.fold_ty(t)) } - fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result, !> { + fn try_fold_region(&mut self, r: I::Region) -> Result + where + I::Region: TypeSuperFoldable, + { Ok(self.fold_region(r)) } - fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result, !> { + fn try_fold_const(&mut self, c: I::Const) -> Result + where + I::Const: TypeSuperFoldable, + { Ok(self.fold_const(c)) } - fn try_fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> Result, !> { + fn try_fold_predicate(&mut self, p: I::Predicate) -> Result + where + I::Predicate: TypeSuperFoldable, + { Ok(self.fold_predicate(p)) } } @@ -221,7 +257,7 @@ where pub ct_op: H, } -impl<'tcx, F, G, H> TypeFolder<'tcx> for BottomUpFolder<'tcx, F, G, H> +impl<'tcx, F, G, H> TypeFolder> for BottomUpFolder<'tcx, F, G, H> where F: FnMut(Ty<'tcx>) -> Ty<'tcx>, G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>, @@ -260,7 +296,7 @@ impl<'tcx> TyCtxt<'tcx> { mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { value.fold_with(&mut RegionFolder::new(self, &mut f)) } @@ -271,7 +307,7 @@ impl<'tcx> TyCtxt<'tcx> { mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, ) -> T where - T: TypeSuperFoldable<'tcx>, + T: TypeSuperFoldable>, { value.super_fold_with(&mut RegionFolder::new(self, &mut f)) } @@ -311,12 +347,12 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for RegionFolder<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -385,7 +421,7 @@ impl<'tcx, D: BoundVarReplacerDelegate<'tcx>> BoundVarReplacer<'tcx, D> { } } -impl<'tcx, D> TypeFolder<'tcx> for BoundVarReplacer<'tcx, D> +impl<'tcx, D> TypeFolder> for BoundVarReplacer<'tcx, D> where D: BoundVarReplacerDelegate<'tcx>, { @@ -393,7 +429,7 @@ where self.tcx } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -471,7 +507,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> (T, BTreeMap>) where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let mut region_map = BTreeMap::new(); let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br)); @@ -486,7 +522,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> T where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let value = value.skip_binder(); if !value.has_escaping_bound_vars() { @@ -505,7 +541,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Replaces all escaping bound vars. The `fld_r` closure replaces escaping /// bound regions; the `fld_t` closure replaces escaping bound types and the `fld_c` /// closure replaces escaping bound consts. - pub fn replace_escaping_bound_vars_uncached>( + pub fn replace_escaping_bound_vars_uncached>>( self, value: T, delegate: impl BoundVarReplacerDelegate<'tcx>, @@ -521,7 +557,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Replaces all types or regions bound by the given `Binder`. The `fld_r` /// closure replaces bound regions, the `fld_t` closure replaces bound /// types, and `fld_c` replaces bound constants. - pub fn replace_bound_vars_uncached>( + pub fn replace_bound_vars_uncached>>( self, value: Binder<'tcx, T>, delegate: impl BoundVarReplacerDelegate<'tcx>, @@ -537,7 +573,7 @@ impl<'tcx> TyCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { self.replace_late_bound_regions_uncached(value, |br| { self.mk_region(ty::ReFree(ty::FreeRegion { @@ -549,7 +585,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn shift_bound_var_indices(self, bound_vars: usize, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars); self.replace_escaping_bound_vars_uncached( @@ -578,7 +614,7 @@ impl<'tcx> TyCtxt<'tcx> { /// method lookup and a few other places where precise region relationships are not required. pub fn erase_late_bound_regions(self, value: Binder<'tcx, T>) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { self.replace_late_bound_regions(value, |_| self.lifetimes.re_erased).0 } @@ -586,7 +622,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Anonymize all bound variables in `value`, this is mostly used to improve caching. pub fn anonymize_bound_vars(self, value: Binder<'tcx, T>) -> Binder<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { struct Anonymize<'a, 'tcx> { tcx: TyCtxt<'tcx>, @@ -654,12 +690,12 @@ impl<'tcx> Shifter<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> { +impl<'tcx> TypeFolder> for Shifter<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -723,7 +759,7 @@ pub fn shift_region<'tcx>( pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: T, amount: u32) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!("shift_vars(value={:?}, amount={})", value, amount); diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8b4fccc58bd44..8ce30f038f559 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -589,7 +589,7 @@ impl<'tcx> Instance<'tcx> { pub fn subst_mir(&self, tcx: TyCtxt<'tcx>, v: &T) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable> + Copy, { if let Some(substs) = self.substs_for_mir_body() { EarlyBinder(*v).subst(tcx, substs) @@ -606,7 +606,7 @@ impl<'tcx> Instance<'tcx> { v: T, ) -> T where - T: TypeFoldable<'tcx> + Clone, + T: TypeFoldable> + Clone, { if let Some(substs) = self.substs_for_mir_body() { tcx.subst_and_normalize_erasing_regions(substs, param_env, v) @@ -623,7 +623,7 @@ impl<'tcx> Instance<'tcx> { v: T, ) -> Result> where - T: TypeFoldable<'tcx> + Clone, + T: TypeFoldable> + Clone, { if let Some(substs) = self.substs_for_mir_body() { tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v) @@ -674,7 +674,7 @@ fn polymorphize<'tcx>( tcx: TyCtxt<'tcx>, } - impl<'tcx> ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> { + impl<'tcx> ty::TypeFolder> for PolymorphizationFolder<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a187131e5faa5..d372f93202bb3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -908,8 +908,11 @@ impl<'a, 'tcx> HashStable> for Term<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for Term<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { Ok(self.unpack().try_fold_with(folder)?.pack()) } } @@ -1580,8 +1583,8 @@ impl<'a, 'tcx> HashStable> for ParamEnv<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { - fn try_fold_with>( +impl<'tcx> TypeFoldable> for ParamEnv<'tcx> { + fn try_fold_with>>( self, folder: &mut F, ) -> Result { diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index ee13920d52edd..40746fc2de669 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -38,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> { #[tracing::instrument(level = "debug", skip(self, param_env))] pub fn normalize_erasing_regions(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!( "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", @@ -70,7 +70,7 @@ impl<'tcx> TyCtxt<'tcx> { value: T, ) -> Result> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!( "try_normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", @@ -107,7 +107,7 @@ impl<'tcx> TyCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let value = self.erase_late_bound_regions(value); self.normalize_erasing_regions(param_env, value) @@ -127,7 +127,7 @@ impl<'tcx> TyCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> Result> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let value = self.erase_late_bound_regions(value); self.try_normalize_erasing_regions(param_env, value) @@ -145,7 +145,7 @@ impl<'tcx> TyCtxt<'tcx> { value: T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!( "subst_and_normalize_erasing_regions(\ @@ -169,7 +169,7 @@ impl<'tcx> TyCtxt<'tcx> { value: T, ) -> Result> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!( "subst_and_normalize_erasing_regions(\ @@ -202,7 +202,7 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> { +impl<'tcx> TypeFolder> for NormalizeAfterErasingRegionsFolder<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -238,7 +238,7 @@ impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> { } } -impl<'tcx> FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> { +impl<'tcx> FallibleTypeFolder> for TryNormalizeAfterErasingRegionsFolder<'tcx> { type Error = NormalizationError<'tcx>; fn tcx(&self) -> TyCtxt<'tcx> { diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 7ff58f02623dc..8322fc1544594 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -91,7 +91,7 @@ impl<'tcx> ReverseMapper<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { +impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index fc095e9f01745..5ecb3f95238cf 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -226,7 +226,7 @@ pub trait PrettyPrinter<'tcx>: fn in_binder(self, value: &ty::Binder<'tcx, T>) -> Result where - T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable>, { value.as_ref().skip_binder().print(self) } @@ -237,7 +237,7 @@ pub trait PrettyPrinter<'tcx>: f: F, ) -> Result where - T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable>, { f(value.as_ref().skip_binder(), self) } @@ -2031,7 +2031,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { fn in_binder(self, value: &ty::Binder<'tcx, T>) -> Result where - T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable>, { self.pretty_in_binder(value) } @@ -2042,7 +2042,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { f: C, ) -> Result where - T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable>, { self.pretty_wrap_binder(value, f) } @@ -2221,12 +2221,12 @@ struct RegionFolder<'a, 'tcx> { ), } -impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { +impl<'a, 'tcx> ty::TypeFolder> for RegionFolder<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -2286,7 +2286,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { value: &ty::Binder<'tcx, T>, ) -> Result<(Self, T, BTreeMap>), fmt::Error> where - T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable>, { fn name_by_region_index( index: usize, @@ -2449,7 +2449,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { pub fn pretty_in_binder(self, value: &ty::Binder<'tcx, T>) -> Result where - T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable>, { let old_region_index = self.region_index; let (new, new_value, _) = self.name_all_regions(value)?; @@ -2465,7 +2465,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { f: C, ) -> Result where - T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable>, { let old_region_index = self.region_index; let (new, new_value, _) = self.name_all_regions(value)?; @@ -2530,7 +2530,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T> where - T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable>, { type Output = P; type Error = P::Error; diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 890dabde1f73d..0306a3f34fd61 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -106,7 +106,7 @@ pub trait TypeRelation<'tcx>: Sized { T: Relate<'tcx>; } -pub trait Relate<'tcx>: TypeFoldable<'tcx> + PartialEq + Copy { +pub trait Relate<'tcx>: TypeFoldable> + PartialEq + Copy { fn relate>( relation: &mut R, a: Self, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index aaf34e762ae73..9cbb5cd1384ba 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -365,8 +365,11 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { // TypeFoldable implementations. /// AdtDefs are basically the same as a DefId. -impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> { - fn try_fold_with>(self, _folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for ty::AdtDef<'tcx> { + fn try_fold_with>>( + self, + _folder: &mut F, + ) -> Result { Ok(self) } } @@ -380,11 +383,8 @@ impl<'tcx> TypeVisitable> for ty::AdtDef<'tcx> { } } -impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { - fn try_fold_with>( - self, - folder: &mut F, - ) -> Result<(T, U), F::Error> { +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)?)) } } @@ -396,10 +396,10 @@ impl, U: TypeVisitable> TypeVisitable for } } -impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx> +impl, B: TypeFoldable, C: TypeFoldable> TypeFoldable for (A, B, C) { - fn try_fold_with>( + fn try_fold_with>( self, folder: &mut F, ) -> Result<(A, B, C), F::Error> { @@ -422,10 +422,10 @@ impl, B: TypeVisitable, C: TypeVisitable> } EnumTypeTraversalImpl! { - impl<'tcx, T> TypeFoldable<'tcx> for Option { + impl TypeFoldable for Option { (Some)(a), (None), - } where T: TypeFoldable<'tcx> + } where I: Interner, T: TypeFoldable } EnumTypeTraversalImpl! { impl TypeVisitable for Option { @@ -435,10 +435,10 @@ EnumTypeTraversalImpl! { } EnumTypeTraversalImpl! { - impl<'tcx, T, E> TypeFoldable<'tcx> for Result { + impl TypeFoldable for Result { (Ok)(a), (Err)(a), - } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>, + } where I: Interner, T: TypeFoldable, E: TypeFoldable, } EnumTypeTraversalImpl! { impl TypeVisitable for Result { @@ -447,11 +447,8 @@ EnumTypeTraversalImpl! { } where I: Interner, T: TypeVisitable, E: TypeVisitable, } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { - fn try_fold_with>( - mut self, - folder: &mut F, - ) -> Result { +impl> TypeFoldable for Rc { + fn try_fold_with>(mut self, folder: &mut F) -> Result { // We merely want to replace the contained `T`, if at all possible, // so that we don't needlessly allocate a new `Rc` or indeed clone // the contained type. @@ -493,11 +490,8 @@ impl> TypeVisitable for Rc { } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc { - fn try_fold_with>( - mut self, - folder: &mut F, - ) -> Result { +impl> TypeFoldable for Arc { + fn try_fold_with>(mut self, folder: &mut F) -> Result { // We merely want to replace the contained `T`, if at all possible, // so that we don't needlessly allocate a new `Arc` or indeed clone // the contained type. @@ -539,8 +533,8 @@ impl> TypeVisitable for Arc { } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl> TypeFoldable for Box { + fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|value| value.try_fold_with(folder)) } } @@ -551,8 +545,8 @@ impl> TypeVisitable for Box { } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl> TypeFoldable for Vec { + fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|t| t.try_fold_with(folder)) } } @@ -569,8 +563,8 @@ impl> TypeVisitable for &[T] { } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl> TypeFoldable for Box<[T]> { + fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|t| t.try_fold_with(folder)) } } @@ -581,8 +575,11 @@ impl> TypeVisitable for Box<[T]> { } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx, T: TypeFoldable>> TypeFoldable> for ty::Binder<'tcx, T> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { folder.try_fold_binder(self) } } @@ -593,8 +590,8 @@ impl<'tcx, T: TypeVisitable>> TypeVisitable> for ty::B } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T> { - fn try_super_fold_with>( +impl<'tcx, T: TypeFoldable>> TypeSuperFoldable> for ty::Binder<'tcx, T> { + fn try_super_fold_with>>( self, folder: &mut F, ) -> Result { @@ -613,26 +610,38 @@ impl<'tcx, T: TypeVisitable>> TypeSuperVisitable> } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for &'tcx ty::List> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for &'tcx ty::List> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v.iter())) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for &'tcx ty::List { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) } } -impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for Ty<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { folder.try_fold_ty(self) } } @@ -643,8 +652,8 @@ impl<'tcx> TypeVisitable> for Ty<'tcx> { } } -impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> { - fn try_super_fold_with>( +impl<'tcx> TypeSuperFoldable> for Ty<'tcx> { + fn try_super_fold_with>>( self, folder: &mut F, ) -> Result { @@ -740,8 +749,11 @@ impl<'tcx> TypeSuperVisitable> for Ty<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for ty::Region<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { folder.try_fold_region(self) } } @@ -752,8 +764,8 @@ impl<'tcx> TypeVisitable> for ty::Region<'tcx> { } } -impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> { - fn try_super_fold_with>( +impl<'tcx> TypeSuperFoldable> for ty::Region<'tcx> { + fn try_super_fold_with>>( self, _folder: &mut F, ) -> Result { @@ -770,8 +782,11 @@ impl<'tcx> TypeSuperVisitable> for ty::Region<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for ty::Predicate<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { folder.try_fold_predicate(self) } } @@ -792,8 +807,8 @@ impl<'tcx> TypeVisitable> for ty::Predicate<'tcx> { } } -impl<'tcx> TypeSuperFoldable<'tcx> for ty::Predicate<'tcx> { - fn try_super_fold_with>( +impl<'tcx> TypeSuperFoldable> for ty::Predicate<'tcx> { + fn try_super_fold_with>>( self, folder: &mut F, ) -> Result { @@ -811,14 +826,17 @@ impl<'tcx> TypeSuperVisitable> for ty::Predicate<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for &'tcx ty::List> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v)) } } -impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl, Ix: Idx> TypeFoldable for IndexVec { + fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|x| x.try_fold_with(folder)) } } @@ -829,8 +847,11 @@ impl, Ix: Idx> TypeVisitable for IndexVec TypeFoldable<'tcx> for ty::Const<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for ty::Const<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { folder.try_fold_const(self) } } @@ -841,8 +862,8 @@ impl<'tcx> TypeVisitable> for ty::Const<'tcx> { } } -impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> { - fn try_super_fold_with>( +impl<'tcx> TypeSuperFoldable> for ty::Const<'tcx> { + fn try_super_fold_with>>( self, folder: &mut F, ) -> Result { @@ -866,8 +887,11 @@ impl<'tcx> TypeSuperVisitable> for ty::Const<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { - fn try_fold_with>(self, _folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for InferConst<'tcx> { + fn try_fold_with>>( + self, + _folder: &mut F, + ) -> Result { Ok(self) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 906b9265cb2e6..3e4e7388a2f24 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1150,7 +1150,7 @@ struct SkipBindersAt<'tcx> { index: ty::DebruijnIndex, } -impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> { +impl<'tcx> FallibleTypeFolder> for SkipBindersAt<'tcx> { type Error = (); fn tcx(&self) -> TyCtxt<'tcx> { @@ -1159,7 +1159,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> { fn try_fold_binder(&mut self, t: Binder<'tcx, T>) -> Result, Self::Error> where - T: ty::TypeFoldable<'tcx>, + T: ty::TypeFoldable>, { self.index.shift_in(1); let value = t.try_map_bound(|t| t.try_fold_with(self)); diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 5dbe215099143..cbddeea6d21bd 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -227,8 +227,11 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { } } -impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for GenericArg<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), @@ -475,8 +478,11 @@ impl<'tcx> InternalSubsts<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for SubstsRef<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // The match arms are in order of frequency. The 1, 2, and 0 cases are @@ -503,8 +509,11 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn try_fold_with>(self, folder: &mut F) -> Result { +impl<'tcx> TypeFoldable> for &'tcx ty::List> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { // This code is fairly hot, though not as hot as `SubstsRef`. // // When compiling stage 2, I get the following results: @@ -553,7 +562,7 @@ impl<'tcx, T: TypeVisitable>> TypeVisitable> for &'tcx pub struct EarlyBinder(pub T); /// For early binders, you should first call `subst` before using any visitors. -impl<'tcx, T> !TypeFoldable<'tcx> for ty::EarlyBinder {} +impl<'tcx, T> !TypeFoldable> for ty::EarlyBinder {} impl<'tcx, T> !TypeVisitable> for ty::EarlyBinder {} impl EarlyBinder { @@ -615,7 +624,7 @@ impl EarlyBinder<(T, U)> { impl<'tcx, 's, I: IntoIterator> EarlyBinder where - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable>, { pub fn subst_iter( self, @@ -634,7 +643,7 @@ pub struct SubstIter<'s, 'tcx, I: IntoIterator> { impl<'tcx, I: IntoIterator> Iterator for SubstIter<'_, 'tcx, I> where - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable>, { type Item = I::Item; @@ -650,7 +659,7 @@ where impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIter<'_, 'tcx, I> where I::IntoIter: DoubleEndedIterator, - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable>, { fn next_back(&mut self) -> Option { Some(EarlyBinder(self.it.next_back()?).subst(self.tcx, self.substs)) @@ -660,14 +669,14 @@ where impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIter<'_, 'tcx, I> where I::IntoIter: ExactSizeIterator, - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable>, { } impl<'tcx, 's, I: IntoIterator> EarlyBinder where I::Item: Deref, - ::Target: Copy + TypeFoldable<'tcx>, + ::Target: Copy + TypeFoldable>, { pub fn subst_iter_copied( self, @@ -687,7 +696,7 @@ pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> { impl<'tcx, I: IntoIterator> Iterator for SubstIterCopied<'_, 'tcx, I> where I::Item: Deref, - ::Target: Copy + TypeFoldable<'tcx>, + ::Target: Copy + TypeFoldable>, { type Item = ::Target; @@ -704,7 +713,7 @@ impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIterCopied<'_, 'tcx, I> where I::IntoIter: DoubleEndedIterator, I::Item: Deref, - ::Target: Copy + TypeFoldable<'tcx>, + ::Target: Copy + TypeFoldable>, { fn next_back(&mut self) -> Option { Some(EarlyBinder(*self.it.next_back()?).subst(self.tcx, self.substs)) @@ -715,7 +724,7 @@ impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIterCopied<'_, 'tcx, I> where I::IntoIter: ExactSizeIterator, I::Item: Deref, - ::Target: Copy + TypeFoldable<'tcx>, + ::Target: Copy + TypeFoldable>, { } @@ -741,7 +750,7 @@ impl Iterator for EarlyBinderIter { } } -impl<'tcx, T: TypeFoldable<'tcx>> ty::EarlyBinder { +impl<'tcx, T: TypeFoldable>> ty::EarlyBinder { pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T { let mut folder = SubstFolder { tcx, substs, binders_passed: 0 }; self.0.fold_with(&mut folder) @@ -776,13 +785,13 @@ struct SubstFolder<'a, 'tcx> { binders_passed: u32, } -impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for SubstFolder<'a, 'tcx> { #[inline] fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -975,7 +984,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the /// first case we do not increase the De Bruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. - fn shift_vars_through_binders>(&self, val: T) -> T { + fn shift_vars_through_binders>>(&self, val: T) -> T { debug!( "shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})", val, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 54d954a40f7b4..9e0ea77f001a4 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -842,7 +842,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { +impl<'tcx> TypeFolder> for OpaqueTypeExpander<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1328,8 +1328,8 @@ pub fn fold_list<'tcx, F, T>( intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List, ) -> Result<&'tcx ty::List, F::Error> where - F: FallibleTypeFolder<'tcx>, - T: TypeFoldable<'tcx> + PartialEq + Copy, + F: FallibleTypeFolder>, + T: TypeFoldable> + PartialEq + Copy, { let mut iter = list.iter(); // Look for the first element that changed diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 31a3ffbb1d891..b6e1266ff50cf 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -660,7 +660,7 @@ struct MirNeighborCollector<'a, 'tcx> { impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> { pub fn monomorphize(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!("monomorphize: self.instance={:?}", self.instance); self.instance.subst_mir_and_normalize_erasing_regions( diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 50c1787ef8c3d..289f1b662eed5 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -7,7 +7,7 @@ use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse}; use rustc_middle::traits::query::Fallible; use rustc_middle::ty::{self, Ty, TypeFoldable, TypeVisitable}; -use rustc_middle::ty::{GenericArg, ToPredicate}; +use rustc_middle::ty::{GenericArg, ToPredicate, TyCtxt}; use rustc_span::{Span, DUMMY_SP}; use std::fmt::Debug; @@ -104,8 +104,8 @@ pub trait InferCtxtBuilderExt<'tcx> { operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible, ) -> Fallible> where - K: TypeFoldable<'tcx>, - R: Debug + TypeFoldable<'tcx>, + K: TypeFoldable>, + R: Debug + TypeFoldable>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>; } @@ -125,15 +125,15 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> { /// In part because we would need a `for<'tcx>` sort of /// bound for the closure and in part because it is convenient to /// have `'tcx` be free on this function so that we can talk about - /// `K: TypeFoldable<'tcx>`.) + /// `K: TypeFoldable>`.) fn enter_canonical_trait_query( &mut self, canonical_key: &Canonical<'tcx, K>, operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible, ) -> Fallible> where - K: TypeFoldable<'tcx>, - R: Debug + TypeFoldable<'tcx>, + K: TypeFoldable>, + R: Debug + TypeFoldable>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>, { let (infcx, key, canonical_inference_vars) = diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index ccdf6246083cc..dd709ec76eaf6 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -82,7 +82,7 @@ pub(super) enum CandidateSource { } /// Methods used to assemble candidates for either trait or projection goals. -pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq { +pub(super) trait GoalKind<'tcx>: TypeFoldable> + Copy + Eq { fn self_ty(self) -> Ty<'tcx>; fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self; diff --git a/compiler/rustc_trait_selection/src/solve/infcx_ext.rs b/compiler/rustc_trait_selection/src/solve/infcx_ext.rs index 42f597c781d25..7ffeb05f1fc8f 100644 --- a/compiler/rustc_trait_selection/src/solve/infcx_ext.rs +++ b/compiler/rustc_trait_selection/src/solve/infcx_ext.rs @@ -4,7 +4,7 @@ use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::ObligationCause; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::ty::{self, Ty, TypeFoldable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::DUMMY_SP; use super::Goal; @@ -26,7 +26,7 @@ pub(super) trait InferCtxtExt<'tcx> { rhs: T, ) -> Result>>, NoSolution>; - fn instantiate_bound_vars_with_infer + Copy>( + fn instantiate_bound_vars_with_infer> + Copy>( &self, value: ty::Binder<'tcx, T>, ) -> T; @@ -65,7 +65,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { }) } - fn instantiate_bound_vars_with_infer + Copy>( + fn instantiate_bound_vars_with_infer> + Copy>( &self, value: ty::Binder<'tcx, T>, ) -> T { diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 948632ccc6c40..fd017110d87d1 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -855,7 +855,7 @@ pub struct RegionReplacer<'a, 'tcx> { tcx: TyCtxt<'tcx>, } -impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for RegionReplacer<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index a2ddd91546c18..47c33d27a2ec5 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -104,7 +104,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { }); } - pub fn normalize>( + pub fn normalize>>( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -216,7 +216,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { answer: T, ) -> Fallible> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, { self.infcx.make_canonicalized_query_response( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index e5cd9f17145fc..d5f049d2dcca0 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -109,7 +109,7 @@ pub trait TypeErrCtxtExt<'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> where T: fmt::Display - + TypeFoldable<'tcx> + + TypeFoldable> + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, >>::Error: std::fmt::Debug; @@ -122,7 +122,7 @@ pub trait TypeErrCtxtExt<'tcx> { ) -> ! where T: fmt::Display - + TypeFoldable<'tcx> + + TypeFoldable> + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, >>::Error: std::fmt::Debug; @@ -492,7 +492,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) -> ! where T: fmt::Display - + TypeFoldable<'tcx> + + TypeFoldable> + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, >>::Error: std::fmt::Debug, { @@ -512,7 +512,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> where T: fmt::Display - + TypeFoldable<'tcx> + + TypeFoldable> + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, >>::Error: std::fmt::Debug, { @@ -2670,7 +2670,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { var_map: FxHashMap, Ty<'tcx>>, } - impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> { + impl<'a, 'tcx> TypeFolder> for ParamToVarFolder<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } 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 87dbf7c3fd699..42e47ccbcc256 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4052,7 +4052,7 @@ struct ReplaceImplTraitFolder<'tcx> { replace_ty: Ty<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for ReplaceImplTraitFolder<'tcx> { +impl<'tcx> TypeFolder> for ReplaceImplTraitFolder<'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if let ty::Param(ty::ParamTy { index, .. }) = t.kind() { if self.param.index == *index { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 8fa533fbd325a..3f450503357f2 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -371,7 +371,7 @@ pub fn fully_normalize<'tcx, T>( value: T, ) -> Result>> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let ocx = ObligationCtxt::new(infcx); debug!(?value); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index d29692681b826..1503b442ac33e 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -53,11 +53,11 @@ pub trait NormalizeExt<'tcx> { /// /// This normalization should be used when the type contains inference variables or the /// projection may be fallible. - fn normalize>(&self, t: T) -> InferOk<'tcx, T>; + fn normalize>>(&self, t: T) -> InferOk<'tcx, T>; } impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> { - fn normalize>(&self, value: T) -> InferOk<'tcx, T> { + fn normalize>>(&self, value: T) -> InferOk<'tcx, T> { let mut selcx = SelectionContext::new(self.infcx); let Normalized { value, obligations } = normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value); @@ -315,7 +315,7 @@ pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>( value: T, ) -> Normalized<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let mut obligations = Vec::new(); let value = normalize_with_depth_to(selcx, param_env, cause, depth, value, &mut obligations); @@ -332,7 +332,7 @@ pub(crate) fn normalize_with_depth_to<'a, 'b, 'tcx, T>( obligations: &mut Vec>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!(obligations.len = obligations.len()); let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations); @@ -352,7 +352,7 @@ pub(crate) fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>( obligations: &mut Vec>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!(obligations.len = obligations.len()); let mut normalizer = AssocTypeNormalizer::new_without_eager_inference_replacement( @@ -433,7 +433,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { } } - fn fold>(&mut self, value: T) -> T { + fn fold>>(&mut self, value: T) -> T { let value = self.selcx.infcx.resolve_vars_if_possible(value); debug!(?value); @@ -451,12 +451,12 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { } } -impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { +impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx> { fn tcx<'c>(&'c self) -> TyCtxt<'tcx> { self.selcx.tcx() } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -675,7 +675,12 @@ pub struct BoundVarReplacer<'me, 'tcx> { /// /// FIXME(@lcnr): We may even consider experimenting with eagerly replacing bound vars during /// normalization as well, at which point this function will be unnecessary and can be removed. -pub fn with_replaced_escaping_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>, R: TypeFoldable<'tcx>>( +pub fn with_replaced_escaping_bound_vars< + 'a, + 'tcx, + T: TypeFoldable>, + R: TypeFoldable>, +>( infcx: &'a InferCtxt<'tcx>, universe_indices: &'a mut Vec>, value: T, @@ -701,7 +706,7 @@ pub fn with_replaced_escaping_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>, R: Typ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { /// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that /// use a binding level above `universe_indices.len()`, we fail. - pub fn replace_bound_vars>( + pub fn replace_bound_vars>>( infcx: &'me InferCtxt<'tcx>, universe_indices: &'me mut Vec>, value: T, @@ -743,12 +748,12 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { +impl<'tcx> TypeFolder> for BoundVarReplacer<'_, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -829,7 +834,7 @@ pub struct PlaceholderReplacer<'me, 'tcx> { } impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { - pub fn replace_placeholders>( + pub fn replace_placeholders>>( infcx: &'me InferCtxt<'tcx>, mapped_regions: BTreeMap, mapped_types: BTreeMap, @@ -849,12 +854,12 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { +impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 19101679360a2..716433dc883f0 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -32,7 +32,7 @@ pub trait QueryNormalizeExt<'tcx> { /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure. fn query_normalize(&self, value: T) -> Result, NoSolution> where - T: TypeFoldable<'tcx>; + T: TypeFoldable>; } impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> { @@ -51,7 +51,7 @@ impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> { /// and other details are still "under development". fn query_normalize(&self, value: T) -> Result, NoSolution> where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { debug!( "normalize::<{}>(value={:?}, param_env={:?}, cause={:?})", @@ -170,14 +170,14 @@ struct QueryNormalizer<'cx, 'tcx> { universes: Vec>, } -impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { +impl<'cx, 'tcx> FallibleTypeFolder> for QueryNormalizer<'cx, 'tcx> { type Error = NoSolution; fn tcx<'c>(&'c self) -> TyCtxt<'tcx> { self.infcx.tcx } - fn try_fold_binder>( + fn try_fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> Result, Self::Error> { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 97002b461aa9b..9e8bc8bce9a8f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -54,8 +54,8 @@ pub struct TypeOpOutput<'tcx, Op: TypeOp<'tcx>> { /// which produces the resulting query region constraints. /// /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html -pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<'tcx> + 'tcx { - type QueryResponse: TypeFoldable<'tcx>; +pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 'tcx { + type QueryResponse: TypeFoldable>; /// Give query the option for a simple fast path that never /// actually hits the tcx cache lookup etc. Return `Some(r)` with diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index 8f0b4de31e6cf..ffaf610909da8 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs @@ -24,7 +24,7 @@ where } } -pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx> + Copy { +pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable> + Lift<'tcx> + Copy { fn type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ad7d479896fd0..9e32485ac1deb 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1352,7 +1352,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// The weird return type of this function allows it to be used with the `try` (`?`) /// operator within certain functions. #[inline(always)] - fn check_recursion_limit, V>( + fn check_recursion_limit>, V>( &self, obligation: &Obligation<'tcx, T>, error_obligation: &Obligation<'tcx, V>, diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index dbd5f13fe4e8b..8348c6bd79efb 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -772,12 +772,12 @@ struct ReplaceOpaqueTyFolder<'tcx> { binder_index: ty::DebruijnIndex, } -impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> { +impl<'tcx> ty::TypeFolder> for ReplaceOpaqueTyFolder<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder>( + fn fold_binder>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index fdef0a3b66306..1331b0bedf2da 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -868,7 +868,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound /// It's important to note that because of prior substitution, we may have /// late-bound regions, even outside of fn contexts, since this is the best way /// to prep types for chalk lowering. -pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>( +pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable>>( interner: RustInterner<'tcx>, tcx: TyCtxt<'tcx>, ty: Binder<'tcx, T>, @@ -999,12 +999,15 @@ impl<'a, 'tcx> NamedBoundVarSubstitutor<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for NamedBoundVarSubstitutor<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { + fn fold_binder>>( + &mut self, + t: Binder<'tcx, T>, + ) -> Binder<'tcx, T> { self.binder_index.shift_in(1); let result = t.super_fold_with(self); self.binder_index.shift_out(1); @@ -1055,12 +1058,15 @@ impl<'tcx> ParamsSubstitutor<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { +impl<'tcx> TypeFolder> for ParamsSubstitutor<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { + fn fold_binder>>( + &mut self, + t: Binder<'tcx, T>, + ) -> Binder<'tcx, T> { self.binder_index.shift_in(1); let result = t.super_fold_with(self); self.binder_index.shift_out(1); @@ -1131,7 +1137,7 @@ impl<'tcx> ReverseParamsSubstitutor<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> { +impl<'tcx> TypeFolder> for ReverseParamsSubstitutor<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 5cad2c2ccb0f7..67cb7f7656fa8 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -22,7 +22,7 @@ pub(crate) fn provide(p: &mut Providers) { }; } -fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Copy>( +fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable> + PartialEq + Copy>( tcx: TyCtxt<'tcx>, goal: ParamEnvAnd<'tcx, T>, ) -> Result { diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 27dc16259926b..7e80a390067f2 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -161,7 +161,7 @@ fn type_op_normalize<'tcx, T>( key: ParamEnvAnd<'tcx, Normalize>, ) -> Fallible where - T: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx>, + T: fmt::Debug + TypeFoldable> + Lift<'tcx>, { let (param_env, Normalize { value }) = key.into_parts(); let Normalized { value, obligations } = diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index a302750aa1aea..c86971aefbe60 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -734,7 +734,7 @@ struct RegionReplacer<'a, 'tcx> { tcx: TyCtxt<'tcx>, } -impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder> for RegionReplacer<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } From 59ee434c81388706e28ed20e0536aad0bad7dc76 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Mon, 6 Feb 2023 00:35:37 +0000 Subject: [PATCH 7/8] Move visiting traits to type library --- Cargo.lock | 1 + compiler/rustc_middle/src/macros.rs | 105 ++--- .../rustc_middle/src/ty/structural_impls.rs | 80 +--- compiler/rustc_middle/src/ty/visit.rs | 405 +----------------- compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/lib.rs | 39 +- compiler/rustc_type_ir/src/macros.rs | 98 +++++ .../rustc_type_ir/src/structural_impls.rs | 106 +++++ compiler/rustc_type_ir/src/visit.rs | 370 ++++++++++++++++ 9 files changed, 648 insertions(+), 557 deletions(-) create mode 100644 compiler/rustc_type_ir/src/macros.rs create mode 100644 compiler/rustc_type_ir/src/structural_impls.rs create mode 100644 compiler/rustc_type_ir/src/visit.rs diff --git a/Cargo.lock b/Cargo.lock index 705210e44b24c..136e7f3ec4237 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4868,6 +4868,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "smallvec", + "tracing", ] [[package]] diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 19f778e0ced48..b90c4225353bc 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -66,7 +66,7 @@ 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 { +macro_rules! TrivialTypeFoldableImpls { (for <$tcx:lifetime> { $($ty:ty,)+ }) => { $( impl<$tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty { @@ -85,18 +85,25 @@ macro_rules! TrivialTypeTraversalImpls { 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,)+) => { + TrivialTypeFoldableImpls! { + for <'tcx> { + $($ty,)+ } - )+ + } + }; +} + +/// 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,)+ }) => { + TrivialTypeFoldableImpls!(for <$tcx> { $($ty,)+ }); + rustc_type_ir::TrivialTypeVisitableImpls!($(<$tcx> $crate::ty::TyCtxt<$tcx> { $ty })+); }; ($($ty:ty,)+) => { @@ -108,6 +115,14 @@ macro_rules! TrivialTypeTraversalImpls { }; } +#[macro_export] +macro_rules! TrivialTypeFoldableAndLiftImpls { + ($($t:tt)*) => { + TrivialTypeFoldableImpls! { $($t)* } + CloneLiftImpls! { $($t)* } + } +} + #[macro_export] macro_rules! TrivialTypeTraversalAndLiftImpls { ($($t:tt)*) => { @@ -136,15 +151,10 @@ macro_rules! EnumTypeTraversalImpl { (impl<$($p:tt),*> TypeVisitable<$tcx:ty> for $s:path { $($variants:tt)* } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::visit::TypeVisitable<$tcx> for $s - $(where $($wc)*)* - { - fn visit_with>( - &self, - visitor: &mut V, - ) -> ::std::ops::ControlFlow { - EnumTypeTraversalImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) - } + rustc_type_ir::EnumTypeVisitableImpl! { + impl<$($p),*> TypeVisitable<$tcx> for $s { + $($variants)* + } $(where $($wc)*)* } }; @@ -201,59 +211,4 @@ macro_rules! EnumTypeTraversalImpl { ) ) }; - - (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => { - match $this { - $($output)* - } - }; - - (@VisitVariants($this:expr, $visitor:expr) - input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @VisitVariants($this, $visitor) - input($($input)*) - output( - $variant ( $($variant_arg),* ) => { - $($crate::ty::visit::TypeVisitable::visit_with( - $variant_arg, $visitor - )?;)* - ::std::ops::ControlFlow::Continue(()) - } - $($output)* - ) - ) - }; - - (@VisitVariants($this:expr, $visitor:expr) - input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @VisitVariants($this, $visitor) - input($($input)*) - output( - $variant { $($variant_arg),* } => { - $($crate::ty::visit::TypeVisitable::visit_with( - $variant_arg, $visitor - )?;)* - ::std::ops::ControlFlow::Continue(()) - } - $($output)* - ) - ) - }; - - (@VisitVariants($this:expr, $visitor:expr) - input( ($variant:path), $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @VisitVariants($this, $visitor) - input($($input)*) - output( - $variant => { ::std::ops::ControlFlow::Continue(()) } - $($output)* - ) - ) - }; } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 9cbb5cd1384ba..a4b52ca21f083 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -199,15 +199,19 @@ impl<'tcx> fmt::Debug for AliasTy<'tcx> { // For things that don't carry any arena-allocated data (and are // copy...), just add them to this list. -TrivialTypeTraversalAndLiftImpls! { +TrivialTypeFoldableAndLiftImpls! { (), bool, usize, - ::rustc_target::abi::VariantIdx, u16, u32, u64, String, + rustc_type_ir::DebruijnIndex, +} + +TrivialTypeTraversalAndLiftImpls! { + ::rustc_target::abi::VariantIdx, crate::middle::region::Scope, crate::ty::FloatTy, ::rustc_ast::InlineAsmOptions, @@ -259,7 +263,6 @@ TrivialTypeTraversalAndLiftImpls! { Field, interpret::Scalar, rustc_target::abi::Size, - rustc_type_ir::DebruijnIndex, ty::BoundVar, ty::Placeholder, } @@ -389,13 +392,6 @@ impl, U: TypeFoldable> TypeFoldable for (T } } -impl, U: TypeVisitable> TypeVisitable for (T, U) { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.0.visit_with(visitor)?; - self.1.visit_with(visitor) - } -} - impl, B: TypeFoldable, C: TypeFoldable> TypeFoldable for (A, B, C) { @@ -411,28 +407,12 @@ impl, B: TypeFoldable, C: TypeFoldable> Ty } } -impl, B: TypeVisitable, C: TypeVisitable> TypeVisitable - for (A, B, C) -{ - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.0.visit_with(visitor)?; - self.1.visit_with(visitor)?; - self.2.visit_with(visitor) - } -} - 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 -} EnumTypeTraversalImpl! { impl TypeFoldable for Result { @@ -440,12 +420,6 @@ EnumTypeTraversalImpl! { (Err)(a), } where I: Interner, T: TypeFoldable, E: TypeFoldable, } -EnumTypeTraversalImpl! { - impl TypeVisitable for Result { - (Ok)(a), - (Err)(a), - } where I: Interner, T: TypeVisitable, E: TypeVisitable, -} impl> TypeFoldable for Rc { fn try_fold_with>(mut self, folder: &mut F) -> Result { @@ -484,12 +458,6 @@ impl> TypeFoldable for Rc { } } -impl> TypeVisitable for Rc { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - (**self).visit_with(visitor) - } -} - impl> TypeFoldable for Arc { fn try_fold_with>(mut self, folder: &mut F) -> Result { // We merely want to replace the contained `T`, if at all possible, @@ -527,54 +495,24 @@ impl> TypeFoldable for Arc { } } -impl> TypeVisitable for Arc { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - (**self).visit_with(visitor) - } -} - impl> TypeFoldable for Box { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|value| value.try_fold_with(folder)) } } -impl> TypeVisitable for Box { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - (**self).visit_with(visitor) - } -} - impl> TypeFoldable for Vec { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|t| t.try_fold_with(folder)) } } -impl> TypeVisitable for Vec { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - -impl> TypeVisitable for &[T] { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - impl> TypeFoldable for Box<[T]> { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|t| t.try_fold_with(folder)) } } -impl> TypeVisitable for Box<[T]> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - impl<'tcx, T: TypeFoldable>> TypeFoldable> for ty::Binder<'tcx, T> { fn try_fold_with>>( self, @@ -841,12 +779,6 @@ impl, Ix: Idx> TypeFoldable for IndexVec, Ix: Idx> TypeVisitable for IndexVec { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - impl<'tcx> TypeFoldable> for ty::Const<'tcx> { fn try_fold_with>>( self, diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 8f7a13997961d..119ad49a1a830 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -1,235 +1,10 @@ -//! A visiting traversal mechanism for complex data structures that contain type -//! information. -//! -//! This is a read-only traversal of the data structure. -//! -//! This traversal has limited flexibility. Only a small number of "types of -//! interest" within the complex data structures can receive custom -//! visitation. These are the ones containing the most important type-related -//! information, such as `Ty`, `Predicate`, `Region`, and `Const`. -//! -//! There are three groups of traits involved in each traversal. -//! - `TypeVisitable`. This is implemented once for many types, including: -//! - Types of interest, for which the methods delegate to the visitor. -//! - All other types, including generic containers like `Vec` and `Option`. -//! It defines a "skeleton" of how they should be visited. -//! - `TypeSuperVisitable`. This is implemented only for each type of interest, -//! and defines the visiting "skeleton" for these types. -//! - `TypeVisitor`. This is implemented for each visitor. This defines how -//! types of interest are visited. -//! -//! This means each visit is a mixture of (a) generic visiting operations, and (b) -//! custom visit operations that are specific to the visitor. -//! - The `TypeVisitable` impls handle most of the traversal, and call into -//! `TypeVisitor` when they encounter a type of interest. -//! - A `TypeVisitor` may call into another `TypeVisitable` impl, because some of -//! the types of interest are recursive and can contain other types of interest. -//! - A `TypeVisitor` may also call into a `TypeSuperVisitable` impl, because each -//! visitor might provide custom handling only for some types of interest, or -//! only for some variants of each type of interest, and then use default -//! traversal for the remaining cases. -//! -//! For example, if you have `struct S(Ty, U)` where `S: TypeVisitable` and `U: -//! TypeVisitable`, and an instance `s = S(ty, u)`, it would be visited like so: -//! ```text -//! s.visit_with(visitor) calls -//! - ty.visit_with(visitor) calls -//! - visitor.visit_ty(ty) may call -//! - ty.super_visit_with(visitor) -//! - u.visit_with(visitor) -//! ``` -use crate::ty::{ - self, Binder, BoundAtOrAboveBinder, BoundIndex, Flags, Interner, OuterExclusiveBinder, Ty, - TyCtxt, TypeFlags, -}; +use crate::ty::{self, Binder, Flags, OuterExclusiveBinder, Ty, TyCtxt, TypeFlags}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; -use std::fmt; use std::ops::ControlFlow; -/// This trait is implemented for every type that can be visited, -/// providing the skeleton of the traversal. -/// -/// To implement this conveniently, use the derive macro located in -/// `rustc_macros`. -pub trait TypeVisitable: fmt::Debug + Clone { - /// The entry point for visiting. To visit a value `t` with a visitor `v` - /// call: `t.visit_with(v)`. - /// - /// For most types, this just traverses the value, calling `visit_with` on - /// each field/element. - /// - /// For types of interest (such as `Ty`), the implementation of this method - /// that calls a visitor method specifically for that type (such as - /// `V::visit_ty`). This is where control transfers from `TypeFoldable` to - /// `TypeVisitor`. - fn visit_with>(&self, visitor: &mut V) -> ControlFlow; - - /// Returns `true` if `self` has any late-bound regions that are either - /// bound by `binder` or bound by some binder outside of `binder`. - /// If `binder` is `ty::INNERMOST`, this indicates whether - /// there are any late-bound regions that appear free. - fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { - self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break() - } - - /// Returns `true` if this type has any regions that escape `binder` (and - /// hence are not bound by it). - fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool { - self.has_vars_bound_at_or_above(binder.shifted_in(1)) - } - - /// Return `true` if this type has regions that are not a part of the type. - /// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)` - /// would return `true`. The latter can occur when traversing through the - /// former. - /// - /// See [`HasEscapingVarsVisitor`] for more information. - fn has_escaping_bound_vars(&self) -> bool { - self.has_vars_bound_at_or_above(ty::INNERMOST) - } - - fn has_type_flags(&self, flags: TypeFlags) -> bool { - let res = - self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags); - trace!(?self, ?flags, ?res, "has_type_flags"); - res - } - fn has_projections(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_PROJECTION) - } - fn has_opaque_types(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) - } - fn has_generators(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_GENERATOR) - } - fn references_error(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_ERROR) - } - fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> { - if self.references_error() { Err(I::expect_failure()) } else { Ok(()) } - } - fn has_non_region_param(&self) -> bool { - self.has_type_flags(TypeFlags::NEEDS_SUBST - TypeFlags::HAS_RE_PARAM) - } - fn has_infer_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_INFER) - } - fn has_infer_types(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_INFER) - } - fn has_non_region_infer(&self) -> bool { - self.has_type_flags(TypeFlags::NEEDS_INFER - TypeFlags::HAS_RE_INFER) - } - fn needs_infer(&self) -> bool { - self.has_type_flags(TypeFlags::NEEDS_INFER) - } - fn has_placeholders(&self) -> bool { - self.has_type_flags( - TypeFlags::HAS_RE_PLACEHOLDER - | TypeFlags::HAS_TY_PLACEHOLDER - | TypeFlags::HAS_CT_PLACEHOLDER, - ) - } - fn needs_subst(&self) -> bool { - self.has_type_flags(TypeFlags::NEEDS_SUBST) - } - /// "Free" regions in this context means that it has any region - /// that is not (a) erased or (b) late-bound. - fn has_free_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) - } - - fn has_erased_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_ERASED) - } - - /// True if there are any un-erased free regions. - fn has_erasable_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) - } - - /// Indicates whether this value references only 'global' - /// generic parameters that are the same regardless of what fn we are - /// in. This is used for caching. - fn is_global(&self) -> bool { - !self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES) - } - - /// True if there are any late-bound regions - fn has_late_bound_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND) - } - /// True if there are any late-bound non-region variables - fn has_non_region_late_bound(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_LATE_BOUND - TypeFlags::HAS_RE_LATE_BOUND) - } - /// True if there are any late-bound variables - fn has_late_bound_vars(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_LATE_BOUND) - } - - /// Indicates whether this value still has parameters/placeholders/inference variables - /// which could be replaced later, in a way that would change the results of `impl` - /// specialization. - fn still_further_specializable(&self) -> bool { - self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE) - } -} - -pub trait TypeSuperVisitable: TypeVisitable { - /// Provides a default visit for a type of interest. This should only be - /// called within `TypeVisitor` methods, when a non-custom traversal is - /// desired for the value of the type of interest passed to that method. - /// For example, in `MyVisitor::visit_ty(ty)`, it is valid to call - /// `ty.super_visit_with(self)`, but any other visiting should be done - /// with `xyz.visit_with(self)`. - fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow; -} - -/// This trait is implemented for every visiting traversal. There is a visit -/// method defined for every type of interest. Each such method has a default -/// that recurses into the type's fields in a non-custom fashion. -pub trait TypeVisitor: Sized { - type BreakTy = !; - - fn visit_binder>(&mut self, t: &I::Binder) -> ControlFlow - where - I::Binder: TypeSuperVisitable, - { - t.super_visit_with(self) - } - - fn visit_ty(&mut self, t: I::Ty) -> ControlFlow - where - I::Ty: TypeSuperVisitable, - { - t.super_visit_with(self) - } - - fn visit_region(&mut self, r: I::Region) -> ControlFlow - where - I::Region: TypeSuperVisitable, - { - r.super_visit_with(self) - } - - fn visit_const(&mut self, c: I::Const) -> ControlFlow - where - I::Const: TypeSuperVisitable, - { - c.super_visit_with(self) - } - - fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow - where - I::Predicate: TypeSuperVisitable, - { - p.super_visit_with(self) - } -} +pub use rustc_type_ir::visit::*; /////////////////////////////////////////////////////////////////////////// // Region folder @@ -465,182 +240,6 @@ impl<'tcx> TypeVisitor> for ValidateBoundVars<'tcx> { } } -#[derive(Debug, PartialEq, Eq, Copy, Clone)] -struct FoundEscapingVars; - -/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a -/// bound region or a bound type. -/// -/// So, for example, consider a type like the following, which has two binders: -/// -/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize)) -/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope -/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope -/// -/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the -/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner -/// fn type*, that type has an escaping region: `'a`. -/// -/// Note that what I'm calling an "escaping var" is often just called a "free var". However, -/// we already use the term "free var". It refers to the regions or types that we use to represent -/// bound regions or type params on a fn definition while we are type checking its body. -/// -/// To clarify, conceptually there is no particular difference between -/// an "escaping" var and a "free" var. However, there is a big -/// difference in practice. Basically, when "entering" a binding -/// level, one is generally required to do some sort of processing to -/// a bound var, such as replacing it with a fresh/placeholder -/// var, or making an entry in the environment to represent the -/// scope to which it is attached, etc. An escaping var represents -/// a bound var for which this processing has not yet been done. -struct HasEscapingVarsVisitor { - /// Anything bound by `outer_index` or "above" is escaping. - outer_index: ty::DebruijnIndex, -} - -impl TypeVisitor for HasEscapingVarsVisitor { - type BreakTy = FoundEscapingVars; - - fn visit_binder>(&mut self, t: &I::Binder) -> ControlFlow - where - I::Binder: TypeSuperVisitable, - { - self.outer_index.shift_in(1); - let result = t.super_visit_with(self); - self.outer_index.shift_out(1); - result - } - - #[inline] - fn visit_ty(&mut self, t: I::Ty) -> ControlFlow - where - I::Ty: TypeSuperVisitable, - { - // If the outer-exclusive-binder is *strictly greater* than - // `outer_index`, that means that `t` contains some content - // bound at `outer_index` or above (because - // `outer_exclusive_binder` is always 1 higher than the - // content in `t`). Therefore, `t` has some escaping vars. - if t.outer_exclusive_binder() > self.outer_index { - ControlFlow::Break(FoundEscapingVars) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_region(&mut self, r: I::Region) -> ControlFlow - where - I::Region: TypeSuperVisitable, - { - // If the region is bound by `outer_index` or anything outside - // of outer index, then it escapes the binders we have - // visited. - if r.bound_at_or_above_binder(self.outer_index) { - ControlFlow::Break(FoundEscapingVars) - } else { - ControlFlow::Continue(()) - } - } - - fn visit_const(&mut self, ct: I::Const) -> ControlFlow - where - I::Const: TypeSuperVisitable, - { - // we don't have a `visit_infer_const` callback, so we have to - // hook in here to catch this case (annoying...), but - // otherwise we do want to remember to visit the rest of the - // const, as it has types/regions embedded in a lot of other - // places. - match ct.bound_index() { - Some(debruijn) if debruijn >= self.outer_index => ControlFlow::Break(FoundEscapingVars), - _ => ct.super_visit_with(self), - } - } - - #[inline] - fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow - where - I::Predicate: TypeSuperVisitable, - { - if predicate.outer_exclusive_binder() > self.outer_index { - ControlFlow::Break(FoundEscapingVars) - } else { - ControlFlow::Continue(()) - } - } -} - -#[derive(Debug, PartialEq, Eq, Copy, Clone)] -struct FoundFlags; - -// FIXME: Optimize for checking for infer flags -struct HasTypeFlagsVisitor { - flags: ty::TypeFlags, -} - -impl std::fmt::Debug for HasTypeFlagsVisitor { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.flags.fmt(fmt) - } -} - -impl TypeVisitor for HasTypeFlagsVisitor { - type BreakTy = FoundFlags; - - #[inline] - fn visit_ty(&mut self, t: I::Ty) -> ControlFlow - where - I::Ty: TypeSuperVisitable, - { - let flags = t.flags(); - if flags.intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_region(&mut self, r: I::Region) -> ControlFlow - where - I::Region: TypeSuperVisitable, - { - let flags = r.flags(); - if flags.intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_const(&mut self, c: I::Const) -> ControlFlow - where - I::Const: TypeSuperVisitable, - { - let flags = c.flags(); - trace!(r.flags=?flags); - if flags.intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::Continue(()) - } - } - - #[inline] - fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow - where - I::Predicate: TypeSuperVisitable, - { - if predicate.flags().intersects(self.flags) { - ControlFlow::Break(FoundFlags) - } else { - ControlFlow::Continue(()) - } - } -} - /// Collects all the late-bound regions at the innermost binding level /// into a hash set. struct LateBoundRegionsCollector { diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index c4008e9b61296..f7b12a2790b24 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -12,3 +12,4 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_macros = { path = "../rustc_macros" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +tracing = "0.1" diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 9cea9acc4d9da..c37fb9af47fd1 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,5 +1,8 @@ #![feature(fmt_helpers_for_derive)] +#![feature(associated_type_defaults)] +#![feature(control_flow_enum)] #![feature(min_specialization)] +#![feature(never_type)] #![feature(rustc_attrs)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -20,6 +23,13 @@ use std::mem::discriminant; pub mod codec; pub mod sty; pub mod ty_info; +pub mod visit; + +#[macro_use] +mod macros; +mod structural_impls; + +use visit::TypeSuperVisitable; pub use codec::*; pub use sty::*; @@ -28,12 +38,30 @@ pub use ty_info::*; /// Needed so we can use #[derive(HashStable_Generic)] pub trait HashStableContext {} -pub trait Interner { +pub trait Interner: Sized { type AdtDef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type SubstsRef: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type DefId: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; - type Ty: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + OuterExclusiveBinder + Flags; - type Const: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + BoundIndex + Flags; + type Ty: Clone + + Debug + + Hash + + PartialEq + + Eq + + PartialOrd + + Ord + + OuterExclusiveBinder + + Flags + + TypeSuperVisitable; + type Const: Clone + + Debug + + Hash + + PartialEq + + Eq + + PartialOrd + + Ord + + BoundIndex + + Flags + + TypeSuperVisitable; type Region: Clone + Debug + Hash @@ -42,9 +70,10 @@ pub trait Interner { + PartialOrd + Ord + BoundAtOrAboveBinder - + Flags; + + Flags + + TypeSuperVisitable; type Binder; - type Predicate: OuterExclusiveBinder + Flags; + type Predicate: OuterExclusiveBinder + Flags + TypeSuperVisitable; type TypeAndMut: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Mutability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Movability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs new file mode 100644 index 0000000000000..a1ed369768870 --- /dev/null +++ b/compiler/rustc_type_ir/src/macros.rs @@ -0,0 +1,98 @@ +/// 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! TrivialTypeVisitableImpls { + ($(<$($p:tt),+> $i:ty { $ty:ty } $({where $($wc:tt)+})?)+) => { + $( + impl<$($p),+> $crate::visit::TypeVisitable<$i> for $ty $(where $($wc)+)? { + #[inline] + fn visit_with>( + &self, + _: &mut F) + -> ::std::ops::ControlFlow + { + ::std::ops::ControlFlow::Continue(()) + } + } + )+ + }; + + ($($ty:ty,)+) => { + TrivialTypeVisitableImpls! {$( + I { $ty } {where I: $crate::Interner} + )+} + }; +} + +#[macro_export] +macro_rules! EnumTypeVisitableImpl { + (impl<$($p:tt),*> TypeVisitable<$tcx:ty> for $s:path { + $($variants:tt)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::visit::TypeVisitable<$tcx> for $s + $(where $($wc)*)* + { + fn visit_with>( + &self, + visitor: &mut V, + ) -> ::std::ops::ControlFlow { + EnumTypeVisitableImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) + } + } + }; + + (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => { + match $this { + $($output)* + } + }; + + (@VisitVariants($this:expr, $visitor:expr) + input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeVisitableImpl!( + @VisitVariants($this, $visitor) + input($($input)*) + output( + $variant ( $($variant_arg),* ) => { + $($crate::visit::TypeVisitable::visit_with( + $variant_arg, $visitor + )?;)* + ::std::ops::ControlFlow::Continue(()) + } + $($output)* + ) + ) + }; + + (@VisitVariants($this:expr, $visitor:expr) + input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeVisitableImpl!( + @VisitVariants($this, $visitor) + input($($input)*) + output( + $variant { $($variant_arg),* } => { + $($crate::visit::TypeVisitable::visit_with( + $variant_arg, $visitor + )?;)* + ::std::ops::ControlFlow::Continue(()) + } + $($output)* + ) + ) + }; + + (@VisitVariants($this:expr, $visitor:expr) + input( ($variant:path), $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeVisitableImpl!( + @VisitVariants($this, $visitor) + input($($input)*) + output( + $variant => { ::std::ops::ControlFlow::Continue(()) } + $($output)* + ) + ) + }; +} diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs new file mode 100644 index 0000000000000..428a4effe13bd --- /dev/null +++ b/compiler/rustc_type_ir/src/structural_impls.rs @@ -0,0 +1,106 @@ +//! This module contains implementations of the `TypeVisitable` +//! trait for various types in the Rust compiler. Most are written by +//! hand, though we've recently added some macros and proc-macros to help with the tedium. + +use crate::{ + visit::{TypeVisitable, TypeVisitor}, + DebruijnIndex, Interner, +}; +use rustc_index::vec::{Idx, IndexVec}; + +use std::ops::ControlFlow; +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. + +TrivialTypeVisitableImpls! { + (), + bool, + usize, + u16, + u32, + u64, + String, + DebruijnIndex, +} + +/////////////////////////////////////////////////////////////////////////// +// TypeVisitable implementations. + +impl, U: TypeVisitable> TypeVisitable for (T, U) { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.0.visit_with(visitor)?; + self.1.visit_with(visitor) + } +} + +impl, B: TypeVisitable, C: TypeVisitable> TypeVisitable + for (A, B, C) +{ + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.0.visit_with(visitor)?; + self.1.visit_with(visitor)?; + self.2.visit_with(visitor) + } +} + +EnumTypeVisitableImpl! { + impl TypeVisitable for Option { + (Some)(a), + (None), + } where I: Interner, T: TypeVisitable +} + +EnumTypeVisitableImpl! { + impl TypeVisitable for Result { + (Ok)(a), + (Err)(a), + } where I: Interner, T: TypeVisitable, E: TypeVisitable, +} + +impl> TypeVisitable for Rc { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + (**self).visit_with(visitor) + } +} + +impl> TypeVisitable for Arc { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + (**self).visit_with(visitor) + } +} + +impl> TypeVisitable for Box { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + (**self).visit_with(visitor) + } +} + +impl> TypeVisitable for Vec { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl> TypeVisitable for &[T] { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl> TypeVisitable for Box<[T]> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl, Ix: Idx> TypeVisitable for IndexVec { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs new file mode 100644 index 0000000000000..bfdbea070e359 --- /dev/null +++ b/compiler/rustc_type_ir/src/visit.rs @@ -0,0 +1,370 @@ +//! A visiting traversal mechanism for complex data structures that contain type +//! information. +//! +//! This is a read-only traversal of the data structure. +//! +//! This traversal has limited flexibility. Only a small number of "types of +//! interest" within the complex data structures can receive custom +//! visitation. These are the ones containing the most important type-related +//! information, such as `Ty`, `Predicate`, `Region`, and `Const`. +//! +//! There are three groups of traits involved in each traversal. +//! - `TypeVisitable`. This is implemented once for many types, including: +//! - Types of interest, for which the methods delegate to the visitor. +//! - All other types, including generic containers like `Vec` and `Option`. +//! It defines a "skeleton" of how they should be visited. +//! - `TypeSuperVisitable`. This is implemented only for each type of interest, +//! and defines the visiting "skeleton" for these types. +//! - `TypeVisitor`. This is implemented for each visitor. This defines how +//! types of interest are visited. +//! +//! This means each visit is a mixture of (a) generic visiting operations, and (b) +//! custom visit operations that are specific to the visitor. +//! - The `TypeVisitable` impls handle most of the traversal, and call into +//! `TypeVisitor` when they encounter a type of interest. +//! - A `TypeVisitor` may call into another `TypeVisitable` impl, because some of +//! the types of interest are recursive and can contain other types of interest. +//! - A `TypeVisitor` may also call into a `TypeSuperVisitable` impl, because each +//! visitor might provide custom handling only for some types of interest, or +//! only for some variants of each type of interest, and then use default +//! traversal for the remaining cases. +//! +//! For example, if you have `struct S(Ty, U)` where `S: TypeVisitable` and `U: +//! TypeVisitable`, and an instance `s = S(ty, u)`, it would be visited like so: +//! ```text +//! s.visit_with(visitor) calls +//! - ty.visit_with(visitor) calls +//! - visitor.visit_ty(ty) may call +//! - ty.super_visit_with(visitor) +//! - u.visit_with(visitor) +//! ``` + +use crate::{ + BoundAtOrAboveBinder, BoundIndex, DebruijnIndex, Flags, Interner, OuterExclusiveBinder, + TypeFlags, INNERMOST, +}; +use std::{fmt, ops::ControlFlow}; +use tracing::trace; + +/// This trait is implemented for every type that can be visited, +/// providing the skeleton of the traversal. +/// +/// To implement this conveniently, use the derive macro located in +/// `rustc_macros`. +pub trait TypeVisitable: fmt::Debug + Clone { + /// The entry point for visiting. To visit a value `t` with a visitor `v` + /// call: `t.visit_with(v)`. + /// + /// For most types, this just traverses the value, calling `visit_with` on + /// each field/element. + /// + /// For types of interest (such as `Ty`), the implementation of this method + /// that calls a visitor method specifically for that type (such as + /// `V::visit_ty`). This is where control transfers from `TypeFoldable` to + /// `TypeVisitor`. + fn visit_with>(&self, visitor: &mut V) -> ControlFlow; + + /// Returns `true` if `self` has any late-bound regions that are either + /// bound by `binder` or bound by some binder outside of `binder`. + /// If `binder` is `ty::INNERMOST`, this indicates whether + /// there are any late-bound regions that appear free. + fn has_vars_bound_at_or_above(&self, binder: DebruijnIndex) -> bool { + self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break() + } + + /// Returns `true` if this type has any regions that escape `binder` (and + /// hence are not bound by it). + fn has_vars_bound_above(&self, binder: DebruijnIndex) -> bool { + self.has_vars_bound_at_or_above(binder.shifted_in(1)) + } + + /// Return `true` if this type has regions that are not a part of the type. + /// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)` + /// would return `true`. The latter can occur when traversing through the + /// former. + /// + /// See [`HasEscapingVarsVisitor`] for more information. + fn has_escaping_bound_vars(&self) -> bool { + self.has_vars_bound_at_or_above(INNERMOST) + } + + fn has_type_flags(&self, flags: TypeFlags) -> bool { + let res = + self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags); + trace!(?self, ?flags, ?res, "has_type_flags"); + res + } + fn has_projections(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PROJECTION) + } + fn has_opaque_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) + } + fn has_generators(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_GENERATOR) + } + fn references_error(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_ERROR) + } + fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> { + if self.references_error() { Err(I::expect_failure()) } else { Ok(()) } + } + fn has_non_region_param(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_SUBST - TypeFlags::HAS_RE_PARAM) + } + fn has_infer_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_INFER) + } + fn has_infer_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_INFER) + } + fn has_non_region_infer(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_INFER - TypeFlags::HAS_RE_INFER) + } + fn needs_infer(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_INFER) + } + fn has_placeholders(&self) -> bool { + self.has_type_flags( + TypeFlags::HAS_RE_PLACEHOLDER + | TypeFlags::HAS_TY_PLACEHOLDER + | TypeFlags::HAS_CT_PLACEHOLDER, + ) + } + fn needs_subst(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_SUBST) + } + /// "Free" regions in this context means that it has any region + /// that is not (a) erased or (b) late-bound. + fn has_free_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) + } + + fn has_erased_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_ERASED) + } + + /// True if there are any un-erased free regions. + fn has_erasable_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_FREE_REGIONS) + } + + /// Indicates whether this value references only 'global' + /// generic parameters that are the same regardless of what fn we are + /// in. This is used for caching. + fn is_global(&self) -> bool { + !self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES) + } + + /// True if there are any late-bound regions + fn has_late_bound_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND) + } + /// True if there are any late-bound non-region variables + fn has_non_region_late_bound(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_LATE_BOUND - TypeFlags::HAS_RE_LATE_BOUND) + } + /// True if there are any late-bound variables + fn has_late_bound_vars(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_LATE_BOUND) + } + + /// Indicates whether this value still has parameters/placeholders/inference variables + /// which could be replaced later, in a way that would change the results of `impl` + /// specialization. + fn still_further_specializable(&self) -> bool { + self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE) + } +} + +pub trait TypeSuperVisitable: TypeVisitable { + /// Provides a default visit for a type of interest. This should only be + /// called within `TypeVisitor` methods, when a non-custom traversal is + /// desired for the value of the type of interest passed to that method. + /// For example, in `MyVisitor::visit_ty(ty)`, it is valid to call + /// `ty.super_visit_with(self)`, but any other visiting should be done + /// with `xyz.visit_with(self)`. + fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow; +} + +/// This trait is implemented for every visiting traversal. There is a visit +/// method defined for every type of interest. Each such method has a default +/// that recurses into the type's fields in a non-custom fashion. +pub trait TypeVisitor: Sized { + type BreakTy = !; + + fn visit_binder>(&mut self, t: &I::Binder) -> ControlFlow + where + I::Binder: TypeSuperVisitable, + { + t.super_visit_with(self) + } + + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow { + t.super_visit_with(self) + } + + fn visit_region(&mut self, r: I::Region) -> ControlFlow { + r.super_visit_with(self) + } + + fn visit_const(&mut self, c: I::Const) -> ControlFlow { + c.super_visit_with(self) + } + + fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow { + p.super_visit_with(self) + } +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +struct FoundEscapingVars; + +/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a +/// bound region or a bound type. +/// +/// So, for example, consider a type like the following, which has two binders: +/// +/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize)) +/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope +/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope +/// +/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the +/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner +/// fn type*, that type has an escaping region: `'a`. +/// +/// Note that what I'm calling an "escaping var" is often just called a "free var". However, +/// we already use the term "free var". It refers to the regions or types that we use to represent +/// bound regions or type params on a fn definition while we are type checking its body. +/// +/// To clarify, conceptually there is no particular difference between +/// an "escaping" var and a "free" var. However, there is a big +/// difference in practice. Basically, when "entering" a binding +/// level, one is generally required to do some sort of processing to +/// a bound var, such as replacing it with a fresh/placeholder +/// var, or making an entry in the environment to represent the +/// scope to which it is attached, etc. An escaping var represents +/// a bound var for which this processing has not yet been done. +struct HasEscapingVarsVisitor { + /// Anything bound by `outer_index` or "above" is escaping. + outer_index: DebruijnIndex, +} + +impl TypeVisitor for HasEscapingVarsVisitor { + type BreakTy = FoundEscapingVars; + + fn visit_binder>(&mut self, t: &I::Binder) -> ControlFlow + where + I::Binder: TypeSuperVisitable, + { + self.outer_index.shift_in(1); + let result = t.super_visit_with(self); + self.outer_index.shift_out(1); + result + } + + #[inline] + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow { + // If the outer-exclusive-binder is *strictly greater* than + // `outer_index`, that means that `t` contains some content + // bound at `outer_index` or above (because + // `outer_exclusive_binder` is always 1 higher than the + // content in `t`). Therefore, `t` has some escaping vars. + if t.outer_exclusive_binder() > self.outer_index { + ControlFlow::Break(FoundEscapingVars) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_region(&mut self, r: I::Region) -> ControlFlow { + // If the region is bound by `outer_index` or anything outside + // of outer index, then it escapes the binders we have + // visited. + if r.bound_at_or_above_binder(self.outer_index) { + ControlFlow::Break(FoundEscapingVars) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_const(&mut self, ct: I::Const) -> ControlFlow { + // we don't have a `visit_infer_const` callback, so we have to + // hook in here to catch this case (annoying...), but + // otherwise we do want to remember to visit the rest of the + // const, as it has types/regions embedded in a lot of other + // places. + match ct.bound_index() { + Some(debruijn) if debruijn >= self.outer_index => ControlFlow::Break(FoundEscapingVars), + _ => ct.super_visit_with(self), + } + } + + #[inline] + fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow { + if predicate.outer_exclusive_binder() > self.outer_index { + ControlFlow::Break(FoundEscapingVars) + } else { + ControlFlow::Continue(()) + } + } +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +struct FoundFlags; + +// FIXME: Optimize for checking for infer flags +struct HasTypeFlagsVisitor { + flags: TypeFlags, +} + +impl std::fmt::Debug for HasTypeFlagsVisitor { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.flags.fmt(fmt) + } +} + +impl TypeVisitor for HasTypeFlagsVisitor { + type BreakTy = FoundFlags; + + #[inline] + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow { + let flags = t.flags(); + if flags.intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_region(&mut self, r: I::Region) -> ControlFlow { + let flags = r.flags(); + if flags.intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_const(&mut self, c: I::Const) -> ControlFlow { + let flags = c.flags(); + trace!(r.flags=?flags); + if flags.intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } + + #[inline] + fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow { + if predicate.flags().intersects(self.flags) { + ControlFlow::Break(FoundFlags) + } else { + ControlFlow::Continue(()) + } + } +} From ff87b7ab1f1c6230d5f70748a5a2e04e4c51525c Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Mon, 6 Feb 2023 00:49:25 +0000 Subject: [PATCH 8/8] Move folding traits to type library --- compiler/rustc_middle/src/macros.rs | 127 +-------- compiler/rustc_middle/src/ty/fold.rs | 240 +----------------- .../rustc_middle/src/ty/structural_impls.rs | 140 +--------- compiler/rustc_type_ir/src/fold.rs | 205 +++++++++++++++ compiler/rustc_type_ir/src/lib.rs | 18 +- compiler/rustc_type_ir/src/macros.rs | 100 +++++++- .../rustc_type_ir/src/structural_impls.rs | 146 ++++++++++- 7 files changed, 457 insertions(+), 519 deletions(-) create mode 100644 compiler/rustc_type_ir/src/fold.rs diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index b90c4225353bc..085dc8e949983 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -63,47 +63,12 @@ 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! TrivialTypeFoldableImpls { - (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 - } - } - )+ - }; - - ($($ty:ty,)+) => { - TrivialTypeFoldableImpls! { - for <'tcx> { - $($ty,)+ - } - } - }; -} - /// 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,)+ }) => { - TrivialTypeFoldableImpls!(for <$tcx> { $($ty,)+ }); - rustc_type_ir::TrivialTypeVisitableImpls!($(<$tcx> $crate::ty::TyCtxt<$tcx> { $ty })+); + rustc_type_ir::TrivialTypeTraversalImpls!($(<$tcx> $crate::ty::TyCtxt<$tcx> { $ty })+); }; ($($ty:ty,)+) => { @@ -115,14 +80,6 @@ macro_rules! TrivialTypeTraversalImpls { }; } -#[macro_export] -macro_rules! TrivialTypeFoldableAndLiftImpls { - ($($t:tt)*) => { - TrivialTypeFoldableImpls! { $($t)* } - CloneLiftImpls! { $($t)* } - } -} - #[macro_export] macro_rules! TrivialTypeTraversalAndLiftImpls { ($($t:tt)*) => { @@ -130,85 +87,3 @@ macro_rules! TrivialTypeTraversalAndLiftImpls { CloneLiftImpls! { $($t)* } } } - -#[macro_export] -macro_rules! EnumTypeTraversalImpl { - (impl<$($p:tt),*> TypeFoldable<$tcx:ty> for $s:path { - $($variants:tt)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s - $(where $($wc)*)* - { - fn try_fold_with>( - self, - folder: &mut V, - ) -> ::std::result::Result { - EnumTypeTraversalImpl!(@FoldVariants(self, folder) input($($variants)*) output()) - } - } - }; - - (impl<$($p:tt),*> TypeVisitable<$tcx:ty> for $s:path { - $($variants:tt)* - } $(where $($wc:tt)*)*) => { - rustc_type_ir::EnumTypeVisitableImpl! { - impl<$($p),*> TypeVisitable<$tcx> for $s { - $($variants)* - } $(where $($wc)*)* - } - }; - - (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => { - Ok(match $this { - $($output)* - }) - }; - - (@FoldVariants($this:expr, $folder:expr) - input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @FoldVariants($this, $folder) - input($($input)*) - output( - $variant ( $($variant_arg),* ) => { - $variant ( - $($crate::ty::fold::TypeFoldable::try_fold_with($variant_arg, $folder)?),* - ) - } - $($output)* - ) - ) - }; - - (@FoldVariants($this:expr, $folder:expr) - input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @FoldVariants($this, $folder) - input($($input)*) - output( - $variant { $($variant_arg),* } => { - $variant { - $($variant_arg: $crate::ty::fold::TypeFoldable::fold_with( - $variant_arg, $folder - )?),* } - } - $($output)* - ) - ) - }; - - (@FoldVariants($this:expr, $folder:expr) - input( ($variant:path), $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @FoldVariants($this, $folder) - input($($input)*) - output( - $variant => { $variant } - $($output)* - ) - ) - }; -} diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 5c3c0a3a45ffd..8cd83f84230b4 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -1,246 +1,10 @@ -//! A folding traversal mechanism for complex data structures that contain type -//! information. -//! -//! This is a modifying traversal. It consumes the data structure, producing a -//! (possibly) modified version of it. Both fallible and infallible versions are -//! available. The name is potentially confusing, because this traversal is more -//! like `Iterator::map` than `Iterator::fold`. -//! -//! This traversal has limited flexibility. Only a small number of "types of -//! interest" within the complex data structures can receive custom -//! modification. These are the ones containing the most important type-related -//! information, such as `Ty`, `Predicate`, `Region`, and `Const`. -//! -//! There are three groups of traits involved in each traversal. -//! - `TypeFoldable`. This is implemented once for many types, including: -//! - Types of interest, for which the methods delegate to the folder. -//! - All other types, including generic containers like `Vec` and `Option`. -//! It defines a "skeleton" of how they should be folded. -//! - `TypeSuperFoldable`. This is implemented only for each type of interest, -//! and defines the folding "skeleton" for these types. -//! - `TypeFolder`/`FallibleTypeFolder. One of these is implemented for each -//! folder. This defines how types of interest are folded. -//! -//! This means each fold is a mixture of (a) generic folding operations, and (b) -//! custom fold operations that are specific to the folder. -//! - The `TypeFoldable` impls handle most of the traversal, and call into -//! `TypeFolder`/`FallibleTypeFolder` when they encounter a type of interest. -//! - A `TypeFolder`/`FallibleTypeFolder` may call into another `TypeFoldable` -//! impl, because some of the types of interest are recursive and can contain -//! other types of interest. -//! - A `TypeFolder`/`FallibleTypeFolder` may also call into a `TypeSuperFoldable` -//! impl, because each folder might provide custom handling only for some types -//! of interest, or only for some variants of each type of interest, and then -//! use default traversal for the remaining cases. -//! -//! For example, if you have `struct S(Ty, U)` where `S: TypeFoldable` and `U: -//! TypeFoldable`, and an instance `s = S(ty, u)`, it would be folded like so: -//! ```text -//! s.fold_with(folder) calls -//! - ty.fold_with(folder) calls -//! - folder.fold_ty(ty) may call -//! - ty.super_fold_with(folder) -//! - u.fold_with(folder) -//! ``` -use crate::ty::{self, Binder, BoundTy, Interner, Ty, TyCtxt, TypeVisitable}; +use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitable}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; use std::collections::BTreeMap; -/// This trait is implemented for every type that can be folded, -/// providing the skeleton of the traversal. -/// -/// To implement this conveniently, use the derive macro located in -/// `rustc_macros`. -pub trait TypeFoldable: TypeVisitable { - /// The entry point for folding. To fold a value `t` with a folder `f` - /// call: `t.try_fold_with(f)`. - /// - /// For most types, this just traverses the value, calling `try_fold_with` - /// on each field/element. - /// - /// For types of interest (such as `Ty`), the implementation of method - /// calls a folder method specifically for that type (such as - /// `F::try_fold_ty`). This is where control transfers from `TypeFoldable` - /// to `TypeFolder`. - fn try_fold_with>(self, folder: &mut F) -> Result; - - /// A convenient alternative to `try_fold_with` for use with infallible - /// folders. Do not override this method, to ensure coherence with - /// `try_fold_with`. - fn fold_with>(self, folder: &mut F) -> Self { - self.try_fold_with(folder).into_ok() - } -} - -// This trait is implemented for types of interest. -pub trait TypeSuperFoldable: TypeFoldable { - /// Provides a default fold for a type of interest. This should only be - /// called within `TypeFolder` methods, when a non-custom traversal is - /// desired for the value of the type of interest passed to that method. - /// For example, in `MyFolder::try_fold_ty(ty)`, it is valid to call - /// `ty.try_super_fold_with(self)`, but any other folding should be done - /// with `xyz.try_fold_with(self)`. - fn try_super_fold_with>( - self, - folder: &mut F, - ) -> Result; - - /// A convenient alternative to `try_super_fold_with` for use with - /// infallible folders. Do not override this method, to ensure coherence - /// with `try_super_fold_with`. - fn super_fold_with>(self, folder: &mut F) -> Self { - self.try_super_fold_with(folder).into_ok() - } -} - -/// This trait is implemented for every infallible folding traversal. There is -/// a fold method defined for every type of interest. Each such method has a -/// default that does an "identity" fold. Implementations of these methods -/// often fall back to a `super_fold_with` method if the primary argument -/// doesn't satisfy a particular condition. -/// -/// A blanket implementation of [`FallibleTypeFolder`] will defer to -/// the infallible methods of this trait to ensure that the two APIs -/// are coherent. -pub trait TypeFolder: FallibleTypeFolder { - fn tcx(&self) -> I; - - fn fold_binder(&mut self, t: I::Binder) -> I::Binder - where - T: TypeFoldable, - I::Binder: TypeSuperFoldable, - { - t.super_fold_with(self) - } - - fn fold_ty(&mut self, t: I::Ty) -> I::Ty - where - I::Ty: TypeSuperFoldable, - { - t.super_fold_with(self) - } - - fn fold_region(&mut self, r: I::Region) -> I::Region - where - I::Region: TypeSuperFoldable, - { - r.super_fold_with(self) - } - - fn fold_const(&mut self, c: I::Const) -> I::Const - where - I::Const: TypeSuperFoldable, - { - c.super_fold_with(self) - } - - fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate - where - I::Predicate: TypeSuperFoldable, - { - p.super_fold_with(self) - } -} - -/// This trait is implemented for every folding traversal. There is a fold -/// method defined for every type of interest. Each such method has a default -/// that does an "identity" fold. -/// -/// A blanket implementation of this trait (that defers to the relevant -/// method of [`TypeFolder`]) is provided for all infallible folders in -/// order to ensure the two APIs are coherent. -pub trait FallibleTypeFolder: Sized { - type Error; - - fn tcx(&self) -> I; - - fn try_fold_binder(&mut self, t: I::Binder) -> Result, Self::Error> - where - T: TypeFoldable, - I::Binder: TypeSuperFoldable, - { - t.try_super_fold_with(self) - } - - fn try_fold_ty(&mut self, t: I::Ty) -> Result - where - I::Ty: TypeSuperFoldable, - { - t.try_super_fold_with(self) - } - - fn try_fold_region(&mut self, r: I::Region) -> Result - where - I::Region: TypeSuperFoldable, - { - r.try_super_fold_with(self) - } - - fn try_fold_const(&mut self, c: I::Const) -> Result - where - I::Const: TypeSuperFoldable, - { - c.try_super_fold_with(self) - } - - fn try_fold_predicate(&mut self, p: I::Predicate) -> Result - where - I::Predicate: TypeSuperFoldable, - { - p.try_super_fold_with(self) - } -} - -// This blanket implementation of the fallible trait for infallible folders -// delegates to infallible methods to ensure coherence. -impl FallibleTypeFolder for F -where - F: TypeFolder, -{ - type Error = !; - - fn tcx(&self) -> I { - TypeFolder::tcx(self) - } - - fn try_fold_binder(&mut self, t: I::Binder) -> Result, !> - where - T: TypeFoldable, - I::Binder: TypeSuperFoldable, - { - Ok(self.fold_binder(t)) - } - - fn try_fold_ty(&mut self, t: I::Ty) -> Result - where - I::Ty: TypeSuperFoldable, - { - Ok(self.fold_ty(t)) - } - - fn try_fold_region(&mut self, r: I::Region) -> Result - where - I::Region: TypeSuperFoldable, - { - Ok(self.fold_region(r)) - } - - fn try_fold_const(&mut self, c: I::Const) -> Result - where - I::Const: TypeSuperFoldable, - { - Ok(self.fold_const(c)) - } - - fn try_fold_predicate(&mut self, p: I::Predicate) -> Result - where - I::Predicate: TypeSuperFoldable, - { - Ok(self.fold_predicate(p)) - } -} +pub use rustc_type_ir::fold::*; /////////////////////////////////////////////////////////////////////////// // Some sample folders diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index a4b52ca21f083..1823db5c08e9e 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -8,16 +8,13 @@ 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, Flags, InferConst, Interner, Lift, OuterExclusiveBinder, Term, TermKind, Ty, - TyCtxt, + self, AliasTy, Flags, InferConst, Lift, OuterExclusiveBinder, Term, TermKind, Ty, TyCtxt, }; -use rustc_data_structures::functor::IdFunctor; use rustc_hir::def::Namespace; use rustc_index::vec::{Idx, IndexVec}; use rustc_target::abi::TyAndLayout; use std::fmt; -use std::mem::ManuallyDrop; use std::ops::ControlFlow; use std::rc::Rc; use std::sync::Arc; @@ -199,7 +196,7 @@ impl<'tcx> fmt::Debug for AliasTy<'tcx> { // For things that don't carry any arena-allocated data (and are // copy...), just add them to this list. -TrivialTypeFoldableAndLiftImpls! { +CloneLiftImpls! { (), bool, usize, @@ -386,133 +383,6 @@ impl<'tcx> TypeVisitable> for ty::AdtDef<'tcx> { } } -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)?)) - } -} - -impl, B: TypeFoldable, C: TypeFoldable> TypeFoldable - for (A, B, C) -{ - fn try_fold_with>( - self, - folder: &mut F, - ) -> Result<(A, B, C), F::Error> { - Ok(( - self.0.try_fold_with(folder)?, - self.1.try_fold_with(folder)?, - self.2.try_fold_with(folder)?, - )) - } -} - -EnumTypeTraversalImpl! { - impl TypeFoldable for Option { - (Some)(a), - (None), - } where I: Interner, T: TypeFoldable -} - -EnumTypeTraversalImpl! { - impl TypeFoldable for Result { - (Ok)(a), - (Err)(a), - } where I: Interner, T: TypeFoldable, E: TypeFoldable, -} - -impl> TypeFoldable for Rc { - fn try_fold_with>(mut self, folder: &mut F) -> Result { - // We merely want to replace the contained `T`, if at all possible, - // so that we don't needlessly allocate a new `Rc` or indeed clone - // the contained type. - unsafe { - // First step is to ensure that we have a unique reference to - // the contained type, which `Rc::make_mut` will accomplish (by - // allocating a new `Rc` and cloning the `T` only if required). - // This is done *before* casting to `Rc>` so that - // panicking during `make_mut` does not leak the `T`. - Rc::make_mut(&mut self); - - // Casting to `Rc>` is safe because `ManuallyDrop` - // is `repr(transparent)`. - let ptr = Rc::into_raw(self).cast::>(); - let mut unique = Rc::from_raw(ptr); - - // Call to `Rc::make_mut` above guarantees that `unique` is the - // sole reference to the contained value, so we can avoid doing - // a checked `get_mut` here. - let slot = Rc::get_mut_unchecked(&mut unique); - - // Semantically move the contained type out from `unique`, fold - // it, then move the folded value back into `unique`. Should - // folding fail, `ManuallyDrop` ensures that the "moved-out" - // value is not re-dropped. - let owned = ManuallyDrop::take(slot); - let folded = owned.try_fold_with(folder)?; - *slot = ManuallyDrop::new(folded); - - // Cast back to `Rc`. - Ok(Rc::from_raw(Rc::into_raw(unique).cast())) - } - } -} - -impl> TypeFoldable for Arc { - fn try_fold_with>(mut self, folder: &mut F) -> Result { - // We merely want to replace the contained `T`, if at all possible, - // so that we don't needlessly allocate a new `Arc` or indeed clone - // the contained type. - unsafe { - // First step is to ensure that we have a unique reference to - // the contained type, which `Arc::make_mut` will accomplish (by - // allocating a new `Arc` and cloning the `T` only if required). - // This is done *before* casting to `Arc>` so that - // panicking during `make_mut` does not leak the `T`. - Arc::make_mut(&mut self); - - // Casting to `Arc>` is safe because `ManuallyDrop` - // is `repr(transparent)`. - let ptr = Arc::into_raw(self).cast::>(); - let mut unique = Arc::from_raw(ptr); - - // Call to `Arc::make_mut` above guarantees that `unique` is the - // sole reference to the contained value, so we can avoid doing - // a checked `get_mut` here. - let slot = Arc::get_mut_unchecked(&mut unique); - - // Semantically move the contained type out from `unique`, fold - // it, then move the folded value back into `unique`. Should - // folding fail, `ManuallyDrop` ensures that the "moved-out" - // value is not re-dropped. - let owned = ManuallyDrop::take(slot); - let folded = owned.try_fold_with(folder)?; - *slot = ManuallyDrop::new(folded); - - // Cast back to `Arc`. - Ok(Arc::from_raw(Arc::into_raw(unique).cast())) - } - } -} - -impl> TypeFoldable for Box { - fn try_fold_with>(self, folder: &mut F) -> Result { - self.try_map_id(|value| value.try_fold_with(folder)) - } -} - -impl> TypeFoldable for Vec { - fn try_fold_with>(self, folder: &mut F) -> Result { - self.try_map_id(|t| t.try_fold_with(folder)) - } -} - -impl> TypeFoldable for Box<[T]> { - fn try_fold_with>(self, folder: &mut F) -> Result { - self.try_map_id(|t| t.try_fold_with(folder)) - } -} - impl<'tcx, T: TypeFoldable>> TypeFoldable> for ty::Binder<'tcx, T> { fn try_fold_with>>( self, @@ -773,12 +643,6 @@ impl<'tcx> TypeFoldable> for &'tcx ty::List> { } } -impl, Ix: Idx> TypeFoldable for IndexVec { - fn try_fold_with>(self, folder: &mut F) -> Result { - self.try_map_id(|x| x.try_fold_with(folder)) - } -} - impl<'tcx> TypeFoldable> for ty::Const<'tcx> { fn try_fold_with>>( self, diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs new file mode 100644 index 0000000000000..4526ef09ed112 --- /dev/null +++ b/compiler/rustc_type_ir/src/fold.rs @@ -0,0 +1,205 @@ +//! A folding traversal mechanism for complex data structures that contain type +//! information. +//! +//! This is a modifying traversal. It consumes the data structure, producing a +//! (possibly) modified version of it. Both fallible and infallible versions are +//! available. The name is potentially confusing, because this traversal is more +//! like `Iterator::map` than `Iterator::fold`. +//! +//! This traversal has limited flexibility. Only a small number of "types of +//! interest" within the complex data structures can receive custom +//! modification. These are the ones containing the most important type-related +//! information, such as `Ty`, `Predicate`, `Region`, and `Const`. +//! +//! There are three groups of traits involved in each traversal. +//! - `TypeFoldable`. This is implemented once for many types, including: +//! - Types of interest, for which the methods delegate to the folder. +//! - All other types, including generic containers like `Vec` and `Option`. +//! It defines a "skeleton" of how they should be folded. +//! - `TypeSuperFoldable`. This is implemented only for each type of interest, +//! and defines the folding "skeleton" for these types. +//! - `TypeFolder`/`FallibleTypeFolder. One of these is implemented for each +//! folder. This defines how types of interest are folded. +//! +//! This means each fold is a mixture of (a) generic folding operations, and (b) +//! custom fold operations that are specific to the folder. +//! - The `TypeFoldable` impls handle most of the traversal, and call into +//! `TypeFolder`/`FallibleTypeFolder` when they encounter a type of interest. +//! - A `TypeFolder`/`FallibleTypeFolder` may call into another `TypeFoldable` +//! impl, because some of the types of interest are recursive and can contain +//! other types of interest. +//! - A `TypeFolder`/`FallibleTypeFolder` may also call into a `TypeSuperFoldable` +//! impl, because each folder might provide custom handling only for some types +//! of interest, or only for some variants of each type of interest, and then +//! use default traversal for the remaining cases. +//! +//! For example, if you have `struct S(Ty, U)` where `S: TypeFoldable` and `U: +//! TypeFoldable`, and an instance `s = S(ty, u)`, it would be folded like so: +//! ```text +//! s.fold_with(folder) calls +//! - ty.fold_with(folder) calls +//! - folder.fold_ty(ty) may call +//! - ty.super_fold_with(folder) +//! - u.fold_with(folder) +//! ``` + +use crate::{visit::TypeVisitable, Interner}; + +/// This trait is implemented for every type that can be folded, +/// providing the skeleton of the traversal. +/// +/// To implement this conveniently, use the derive macro located in +/// `rustc_macros`. +pub trait TypeFoldable: TypeVisitable { + /// The entry point for folding. To fold a value `t` with a folder `f` + /// call: `t.try_fold_with(f)`. + /// + /// For most types, this just traverses the value, calling `try_fold_with` + /// on each field/element. + /// + /// For types of interest (such as `Ty`), the implementation of method + /// calls a folder method specifically for that type (such as + /// `F::try_fold_ty`). This is where control transfers from `TypeFoldable` + /// to `TypeFolder`. + fn try_fold_with>(self, folder: &mut F) -> Result; + + /// A convenient alternative to `try_fold_with` for use with infallible + /// folders. Do not override this method, to ensure coherence with + /// `try_fold_with`. + fn fold_with>(self, folder: &mut F) -> Self { + self.try_fold_with(folder).into_ok() + } +} + +// This trait is implemented for types of interest. +pub trait TypeSuperFoldable: TypeFoldable { + /// Provides a default fold for a type of interest. This should only be + /// called within `TypeFolder` methods, when a non-custom traversal is + /// desired for the value of the type of interest passed to that method. + /// For example, in `MyFolder::try_fold_ty(ty)`, it is valid to call + /// `ty.try_super_fold_with(self)`, but any other folding should be done + /// with `xyz.try_fold_with(self)`. + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result; + + /// A convenient alternative to `try_super_fold_with` for use with + /// infallible folders. Do not override this method, to ensure coherence + /// with `try_super_fold_with`. + fn super_fold_with>(self, folder: &mut F) -> Self { + self.try_super_fold_with(folder).into_ok() + } +} + +/// This trait is implemented for every infallible folding traversal. There is +/// a fold method defined for every type of interest. Each such method has a +/// default that does an "identity" fold. Implementations of these methods +/// often fall back to a `super_fold_with` method if the primary argument +/// doesn't satisfy a particular condition. +/// +/// A blanket implementation of [`FallibleTypeFolder`] will defer to +/// the infallible methods of this trait to ensure that the two APIs +/// are coherent. +pub trait TypeFolder: FallibleTypeFolder { + fn tcx(&self) -> I; + + fn fold_binder(&mut self, t: I::Binder) -> I::Binder + where + T: TypeFoldable, + I::Binder: TypeSuperFoldable, + { + t.super_fold_with(self) + } + + fn fold_ty(&mut self, t: I::Ty) -> I::Ty { + t.super_fold_with(self) + } + + fn fold_region(&mut self, r: I::Region) -> I::Region { + r.super_fold_with(self) + } + + fn fold_const(&mut self, c: I::Const) -> I::Const { + c.super_fold_with(self) + } + + fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate { + p.super_fold_with(self) + } +} + +/// This trait is implemented for every folding traversal. There is a fold +/// method defined for every type of interest. Each such method has a default +/// that does an "identity" fold. +/// +/// A blanket implementation of this trait (that defers to the relevant +/// method of [`TypeFolder`]) is provided for all infallible folders in +/// order to ensure the two APIs are coherent. +pub trait FallibleTypeFolder: Sized { + type Error; + + fn tcx(&self) -> I; + + fn try_fold_binder(&mut self, t: I::Binder) -> Result, Self::Error> + where + T: TypeFoldable, + I::Binder: TypeSuperFoldable, + { + t.try_super_fold_with(self) + } + + fn try_fold_ty(&mut self, t: I::Ty) -> Result { + t.try_super_fold_with(self) + } + + fn try_fold_region(&mut self, r: I::Region) -> Result { + r.try_super_fold_with(self) + } + + fn try_fold_const(&mut self, c: I::Const) -> Result { + c.try_super_fold_with(self) + } + + fn try_fold_predicate(&mut self, p: I::Predicate) -> Result { + p.try_super_fold_with(self) + } +} + +// This blanket implementation of the fallible trait for infallible folders +// delegates to infallible methods to ensure coherence. +impl FallibleTypeFolder for F +where + I: Interner, + F: TypeFolder, +{ + type Error = !; + + fn tcx(&self) -> I { + TypeFolder::tcx(self) + } + + fn try_fold_binder(&mut self, t: I::Binder) -> Result, !> + where + T: TypeFoldable, + I::Binder: TypeSuperFoldable, + { + Ok(self.fold_binder(t)) + } + + fn try_fold_ty(&mut self, t: I::Ty) -> Result { + Ok(self.fold_ty(t)) + } + + fn try_fold_region(&mut self, r: I::Region) -> Result { + Ok(self.fold_region(r)) + } + + fn try_fold_const(&mut self, c: I::Const) -> Result { + Ok(self.fold_const(c)) + } + + fn try_fold_predicate(&mut self, p: I::Predicate) -> Result { + Ok(self.fold_predicate(p)) + } +} diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index c37fb9af47fd1..03a10af3a1786 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,9 +1,11 @@ #![feature(fmt_helpers_for_derive)] #![feature(associated_type_defaults)] #![feature(control_flow_enum)] +#![feature(get_mut_unchecked)] #![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] +#![feature(unwrap_infallible)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -21,6 +23,7 @@ use std::hash::Hash; use std::mem::discriminant; pub mod codec; +pub mod fold; pub mod sty; pub mod ty_info; pub mod visit; @@ -29,6 +32,7 @@ pub mod visit; mod macros; mod structural_impls; +use fold::TypeSuperFoldable; use visit::TypeSuperVisitable; pub use codec::*; @@ -51,7 +55,8 @@ pub trait Interner: Sized { + Ord + OuterExclusiveBinder + Flags - + TypeSuperVisitable; + + TypeSuperVisitable + + TypeSuperFoldable; type Const: Clone + Debug + Hash @@ -61,7 +66,8 @@ pub trait Interner: Sized { + Ord + BoundIndex + Flags - + TypeSuperVisitable; + + TypeSuperVisitable + + TypeSuperFoldable; type Region: Clone + Debug + Hash @@ -71,9 +77,13 @@ pub trait Interner: Sized { + Ord + BoundAtOrAboveBinder + Flags - + TypeSuperVisitable; + + TypeSuperVisitable + + TypeSuperFoldable; type Binder; - type Predicate: OuterExclusiveBinder + Flags + TypeSuperVisitable; + type Predicate: OuterExclusiveBinder + + Flags + + TypeSuperVisitable + + TypeSuperFoldable; type TypeAndMut: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Mutability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; type Movability: Clone + Debug + Hash + PartialEq + Eq + PartialOrd + Ord; diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index a1ed369768870..4924644ee955d 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -1,9 +1,26 @@ /// 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! TrivialTypeVisitableImpls { +macro_rules! TrivialTypeTraversalImpls { ($(<$($p:tt),+> $i:ty { $ty:ty } $({where $($wc:tt)+})?)+) => { $( + impl<$($p),+> $crate::fold::TypeFoldable<$i> for $ty $(where $($wc)+)? { + fn try_fold_with>( + self, + _: &mut F, + ) -> ::std::result::Result { + Ok(self) + } + + #[inline] + fn fold_with>( + self, + _: &mut F, + ) -> Self { + self + } + } + impl<$($p),+> $crate::visit::TypeVisitable<$i> for $ty $(where $($wc)+)? { #[inline] fn visit_with>( @@ -18,14 +35,29 @@ macro_rules! TrivialTypeVisitableImpls { }; ($($ty:ty,)+) => { - TrivialTypeVisitableImpls! {$( + TrivialTypeTraversalImpls! {$( I { $ty } {where I: $crate::Interner} )+} }; } #[macro_export] -macro_rules! EnumTypeVisitableImpl { +macro_rules! EnumTypeTraversalImpl { + (impl<$($p:tt),*> TypeFoldable<$tcx:ty> for $s:path { + $($variants:tt)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::fold::TypeFoldable<$tcx> for $s + $(where $($wc)*)* + { + fn try_fold_with>( + self, + folder: &mut V, + ) -> ::std::result::Result { + EnumTypeTraversalImpl!(@FoldVariants(self, folder) input($($variants)*) output()) + } + } + }; + (impl<$($p:tt),*> TypeVisitable<$tcx:ty> for $s:path { $($variants:tt)* } $(where $($wc:tt)*)*) => { @@ -36,11 +68,65 @@ macro_rules! EnumTypeVisitableImpl { &self, visitor: &mut V, ) -> ::std::ops::ControlFlow { - EnumTypeVisitableImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) + EnumTypeTraversalImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) } } }; + (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => { + Ok(match $this { + $($output)* + }) + }; + + (@FoldVariants($this:expr, $folder:expr) + input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeTraversalImpl!( + @FoldVariants($this, $folder) + input($($input)*) + output( + $variant ( $($variant_arg),* ) => { + $variant ( + $($crate::fold::TypeFoldable::try_fold_with($variant_arg, $folder)?),* + ) + } + $($output)* + ) + ) + }; + + (@FoldVariants($this:expr, $folder:expr) + input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeTraversalImpl!( + @FoldVariants($this, $folder) + input($($input)*) + output( + $variant { $($variant_arg),* } => { + $variant { + $($variant_arg: $crate::fold::TypeFoldable::fold_with( + $variant_arg, $folder + )?),* } + } + $($output)* + ) + ) + }; + + (@FoldVariants($this:expr, $folder:expr) + input( ($variant:path), $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeTraversalImpl!( + @FoldVariants($this, $folder) + input($($input)*) + output( + $variant => { $variant } + $($output)* + ) + ) + }; + (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => { match $this { $($output)* @@ -50,7 +136,7 @@ macro_rules! EnumTypeVisitableImpl { (@VisitVariants($this:expr, $visitor:expr) input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) output( $($output:tt)*) ) => { - EnumTypeVisitableImpl!( + EnumTypeTraversalImpl!( @VisitVariants($this, $visitor) input($($input)*) output( @@ -68,7 +154,7 @@ macro_rules! EnumTypeVisitableImpl { (@VisitVariants($this:expr, $visitor:expr) input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) output( $($output:tt)*) ) => { - EnumTypeVisitableImpl!( + EnumTypeTraversalImpl!( @VisitVariants($this, $visitor) input($($input)*) output( @@ -86,7 +172,7 @@ macro_rules! EnumTypeVisitableImpl { (@VisitVariants($this:expr, $visitor:expr) input( ($variant:path), $($input:tt)*) output( $($output:tt)*) ) => { - EnumTypeVisitableImpl!( + EnumTypeTraversalImpl!( @VisitVariants($this, $visitor) input($($input)*) output( diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs index 428a4effe13bd..779896da7dd94 100644 --- a/compiler/rustc_type_ir/src/structural_impls.rs +++ b/compiler/rustc_type_ir/src/structural_impls.rs @@ -1,13 +1,16 @@ -//! This module contains implementations of the `TypeVisitable` -//! trait for various types in the Rust compiler. Most are written by +//! This module contains implementations of the `TypeVisitable` and `TypeFoldable` +//! traits for various types in the Rust compiler. Most are written by //! hand, though we've recently added some macros and proc-macros to help with the tedium. use crate::{ + fold::{FallibleTypeFolder, TypeFoldable}, visit::{TypeVisitable, TypeVisitor}, DebruijnIndex, Interner, }; +use rustc_data_structures::functor::IdFunctor; use rustc_index::vec::{Idx, IndexVec}; +use std::mem::ManuallyDrop; use std::ops::ControlFlow; use std::rc::Rc; use std::sync::Arc; @@ -18,7 +21,7 @@ use std::sync::Arc; // For things that don't carry any arena-allocated data (and are // copy...), just add them to this list. -TrivialTypeVisitableImpls! { +TrivialTypeTraversalImpls! { (), bool, usize, @@ -30,7 +33,13 @@ TrivialTypeVisitableImpls! { } /////////////////////////////////////////////////////////////////////////// -// TypeVisitable implementations. +// TypeVisitable and TypeFoldable implementations. + +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)?)) + } +} impl, U: TypeVisitable> TypeVisitable for (T, U) { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -39,6 +48,21 @@ impl, U: TypeVisitable> TypeVisitable for } } +impl, B: TypeFoldable, C: TypeFoldable> TypeFoldable + for (A, B, C) +{ + fn try_fold_with>( + self, + folder: &mut F, + ) -> Result<(A, B, C), F::Error> { + Ok(( + self.0.try_fold_with(folder)?, + self.1.try_fold_with(folder)?, + self.2.try_fold_with(folder)?, + )) + } +} + impl, B: TypeVisitable, C: TypeVisitable> TypeVisitable for (A, B, C) { @@ -49,38 +73,136 @@ impl, B: TypeVisitable, C: TypeVisitable> } } -EnumTypeVisitableImpl! { +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 } -EnumTypeVisitableImpl! { +EnumTypeTraversalImpl! { + impl TypeFoldable for Result { + (Ok)(a), + (Err)(a), + } where I: Interner, T: TypeFoldable, E: TypeFoldable, +} +EnumTypeTraversalImpl! { impl TypeVisitable for Result { (Ok)(a), (Err)(a), } where I: Interner, T: TypeVisitable, E: TypeVisitable, } +impl> TypeFoldable for Rc { + fn try_fold_with>(mut self, folder: &mut F) -> Result { + // We merely want to replace the contained `T`, if at all possible, + // so that we don't needlessly allocate a new `Rc` or indeed clone + // the contained type. + unsafe { + // First step is to ensure that we have a unique reference to + // the contained type, which `Rc::make_mut` will accomplish (by + // allocating a new `Rc` and cloning the `T` only if required). + // This is done *before* casting to `Rc>` so that + // panicking during `make_mut` does not leak the `T`. + Rc::make_mut(&mut self); + + // Casting to `Rc>` is safe because `ManuallyDrop` + // is `repr(transparent)`. + let ptr = Rc::into_raw(self).cast::>(); + let mut unique = Rc::from_raw(ptr); + + // Call to `Rc::make_mut` above guarantees that `unique` is the + // sole reference to the contained value, so we can avoid doing + // a checked `get_mut` here. + let slot = Rc::get_mut_unchecked(&mut unique); + + // Semantically move the contained type out from `unique`, fold + // it, then move the folded value back into `unique`. Should + // folding fail, `ManuallyDrop` ensures that the "moved-out" + // value is not re-dropped. + let owned = ManuallyDrop::take(slot); + let folded = owned.try_fold_with(folder)?; + *slot = ManuallyDrop::new(folded); + + // Cast back to `Rc`. + Ok(Rc::from_raw(Rc::into_raw(unique).cast())) + } + } +} + impl> TypeVisitable for Rc { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } } +impl> TypeFoldable for Arc { + fn try_fold_with>(mut self, folder: &mut F) -> Result { + // We merely want to replace the contained `T`, if at all possible, + // so that we don't needlessly allocate a new `Arc` or indeed clone + // the contained type. + unsafe { + // First step is to ensure that we have a unique reference to + // the contained type, which `Arc::make_mut` will accomplish (by + // allocating a new `Arc` and cloning the `T` only if required). + // This is done *before* casting to `Arc>` so that + // panicking during `make_mut` does not leak the `T`. + Arc::make_mut(&mut self); + + // Casting to `Arc>` is safe because `ManuallyDrop` + // is `repr(transparent)`. + let ptr = Arc::into_raw(self).cast::>(); + let mut unique = Arc::from_raw(ptr); + + // Call to `Arc::make_mut` above guarantees that `unique` is the + // sole reference to the contained value, so we can avoid doing + // a checked `get_mut` here. + let slot = Arc::get_mut_unchecked(&mut unique); + + // Semantically move the contained type out from `unique`, fold + // it, then move the folded value back into `unique`. Should + // folding fail, `ManuallyDrop` ensures that the "moved-out" + // value is not re-dropped. + let owned = ManuallyDrop::take(slot); + let folded = owned.try_fold_with(folder)?; + *slot = ManuallyDrop::new(folded); + + // Cast back to `Arc`. + Ok(Arc::from_raw(Arc::into_raw(unique).cast())) + } + } +} + impl> TypeVisitable for Arc { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } } +impl> TypeFoldable for Box { + fn try_fold_with>(self, folder: &mut F) -> Result { + self.try_map_id(|value| value.try_fold_with(folder)) + } +} + impl> TypeVisitable for Box { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { (**self).visit_with(visitor) } } +impl> TypeFoldable for Vec { + fn try_fold_with>(self, folder: &mut F) -> Result { + self.try_map_id(|t| t.try_fold_with(folder)) + } +} + impl> TypeVisitable for Vec { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) @@ -93,12 +215,24 @@ impl> TypeVisitable for &[T] { } } +impl> TypeFoldable for Box<[T]> { + fn try_fold_with>(self, folder: &mut F) -> Result { + self.try_map_id(|t| t.try_fold_with(folder)) + } +} + impl> TypeVisitable for Box<[T]> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor)) } } +impl, Ix: Idx> TypeFoldable for IndexVec { + fn try_fold_with>(self, folder: &mut F) -> Result { + self.try_map_id(|x| x.try_fold_with(folder)) + } +} + impl, Ix: Idx> TypeVisitable for IndexVec { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { self.iter().try_for_each(|t| t.visit_with(visitor))