diff options
133 files changed, 1482 insertions, 1257 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 2ae13990a45..70124dba809 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::{ }; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCauseCode; -use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use crate::{ diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index d3868730557..c7fe382bac4 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -86,7 +86,7 @@ mod prelude { pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, - TypeFoldable, TypeVisitable, UintTy, + TypeFoldable, UintTy, }; pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx}; diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index bb265b8289e..de1734332d4 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, TypeFoldable}; use rustc_target::abi::call::{FnAbi, PassMode}; use std::iter; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index cabc65e2c07..581cb6421f7 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,5 +1,5 @@ use rustc_middle::mir::interpret::InterpResult; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use std::ops::ControlFlow; /// Checks whether a type contains generic parameters which require substitution. @@ -21,7 +21,7 @@ where tcx: TyCtxt<'tcx>, } - impl<'tcx> TypeVisitor<'tcx> for UsedParamsNeedSubstVisitor<'tcx> { + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedSubstVisitor<'tcx> { type BreakTy = FoundParam; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 5e3601efbbe..15a66ccc0f4 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<String>)>, } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> { + impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueVisitor<'tcx> { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { @@ -1447,7 +1447,7 @@ fn opaque_type_cycle_error( opaques: Vec<DefId>, closures: Vec<DefId>, } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for OpaqueTypeCollector { + impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { match *t.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { 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 c86af6a379b..a926deb2393 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -16,7 +16,7 @@ use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::util::ExplicitSelf; use rustc_middle::ty::{ - self, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, + self, ir::TypeFolder, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeSuperFoldable, }; use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt}; use rustc_span::Span; @@ -464,8 +464,8 @@ struct RemapLateBound<'a, 'tcx> { mapping: &'a FxHashMap<ty::BoundRegionKind, ty::BoundRegionKind>, } -impl<'tcx> TypeFolder<'tcx> for RemapLateBound<'_, 'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -829,14 +829,14 @@ impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.ocx.infcx.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if let ty::Alias(ty::Projection, proj) = ty.kind() - && self.tcx().def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder + && self.interner().def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder { if let Some((ty, _)) = self.types.get(&proj.def_id) { return *ty; @@ -852,7 +852,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> { }); self.types.insert(proj.def_id, (infer_ty, proj.substs)); // Recurse into bounds - for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.def_id).subst_iter_copied(self.tcx(), proj.substs) { + for (pred, pred_span) in self.interner().bound_explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( &ObligationCause::misc(self.span, self.body_id), @@ -861,7 +861,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> { ); self.ocx.register_obligation(traits::Obligation::new( - self.tcx(), + self.interner(), ObligationCause::new( self.span, self.body_id, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5f95622883b..16e7dcd0060 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -16,8 +16,8 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::query::Providers; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ - self, AdtKind, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitor, + self, ir::TypeVisitor, AdtKind, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, + TypeSuperVisitable, }; use rustc_middle::ty::{GenericArgKind, InternalSubsts}; use rustc_session::parse::feature_err; @@ -772,7 +772,7 @@ impl<'tcx> GATSubstCollector<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATSubstCollector<'tcx> { type BreakTy = !; fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { @@ -1435,7 +1435,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id struct CountParams { params: FxHashSet<u32>, } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for CountParams { + impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for CountParams { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index c1b0237b2d1..940a450101c 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -57,7 +57,7 @@ const ADD_ATTR: &str = "alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items"; impl<'tcx> InherentCollect<'tcx> { - fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId) { + fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId, span: Span) { let impl_def_id = item.owner_id; if let Some(def_id) = def_id.as_local() { // Add the implementation to the mapping from implementation to base @@ -76,12 +76,12 @@ impl<'tcx> InherentCollect<'tcx> { if !self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) { struct_span_err!( self.tcx.sess, - item.span, + span, E0390, "cannot define inherent `impl` for a type outside of the crate where the type is defined", ) .help(INTO_DEFINING_CRATE) - .span_help(item.span, ADD_ATTR_TO_TY) + .span_help(span, ADD_ATTR_TO_TY) .emit(); return; } @@ -93,12 +93,12 @@ impl<'tcx> InherentCollect<'tcx> { { struct_span_err!( self.tcx.sess, - item.span, + span, E0390, "cannot define inherent `impl` for a type outside of the crate where the type is defined", ) .help(INTO_DEFINING_CRATE) - .span_help(impl_item.span, ADD_ATTR) + .span_help(self.tcx.hir().span(impl_item.id.hir_id()), ADD_ATTR) .emit(); return; } @@ -112,12 +112,12 @@ impl<'tcx> InherentCollect<'tcx> { } else { struct_span_err!( self.tcx.sess, - item.span, + span, E0116, "cannot define inherent `impl` for a type outside of the crate \ where the type is defined" ) - .span_label(item.span, "impl for type defined outside of crate.") + .span_label(span, "impl for type defined outside of crate.") .note("define and implement a trait or new type instead") .emit(); } @@ -182,29 +182,30 @@ impl<'tcx> InherentCollect<'tcx> { } let item = self.tcx.hir().item(id); - let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, items, .. }) = item.kind else { + let impl_span = self.tcx.hir().span(id.hir_id()); + let hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) = item.kind else { return; }; let self_ty = self.tcx.type_of(item.owner_id); match *self_ty.kind() { ty::Adt(def, _) => { - self.check_def_id(item, self_ty, def.did()); + self.check_def_id(item, self_ty, def.did(), impl_span); } ty::Foreign(did) => { - self.check_def_id(item, self_ty, did); + self.check_def_id(item, self_ty, did, impl_span); } ty::Dynamic(data, ..) if data.principal_def_id().is_some() => { - self.check_def_id(item, self_ty, data.principal_def_id().unwrap()); + self.check_def_id(item, self_ty, data.principal_def_id().unwrap(), impl_span); } ty::Dynamic(..) => { struct_span_err!( self.tcx.sess, - ty.span, + impl_span, E0785, "cannot define inherent `impl` for a dyn auto trait" ) - .span_label(ty.span, "impl requires at least one non-auto trait") + .span_label(impl_span, "impl requires at least one non-auto trait") .note("define and implement a new trait or type instead") .emit(); } @@ -221,17 +222,17 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Never | ty::FnPtr(_) | ty::Tuple(..) => { - self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span) + self.check_primitive_impl(item.owner_id.def_id, self_ty, items, impl_span) } ty::Alias(..) | ty::Param(_) => { let mut err = struct_span_err!( self.tcx.sess, - ty.span, + impl_span, E0118, "no nominal type found for inherent implementation" ); - err.span_label(ty.span, "impl requires a nominal type") + err.span_label(impl_span, "impl requires a nominal type") .note("either implement a trait on it or create a newtype to wrap it instead"); err.emit(); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 7d381d8902a..d0db8cabfdd 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -8,7 +8,7 @@ use rustc_hir as hir; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IgnoreRegions; use rustc_middle::ty::{ - self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, ir::TypeVisitor, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, }; use rustc_session::lint; use rustc_span::def_id::{DefId, LocalDefId}; @@ -552,7 +552,7 @@ fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty: seen: FxHashSet<DefId>, } - impl<'tcx> TypeVisitor<'tcx> for DisableAutoTraitVisitor<'tcx> { + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for DisableAutoTraitVisitor<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { 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 3c67722b637..3f8d620fe69 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -17,7 +17,7 @@ use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeNa use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime::*; -use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::{self, ir::TypeVisitor, DefIdTree, TyCtxt, TypeSuperVisitable}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -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<TyCtxt<'tcx>> 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/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c5522c94874..54fcccb0c11 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{ - self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable, + self, ir::TypeFolder, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeSuperFoldable, TypeVisitable, }; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; @@ -850,8 +850,8 @@ fn infer_placeholder_type<'a>( tcx: TyCtxt<'tcx>, } - impl<'tcx> TypeFolder<'tcx> for MakeNameable<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { + impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MakeNameable<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 56cc1d8fadc..072676c400d 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -1,5 +1,5 @@ use rustc_data_structures::fx::FxHashSet; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::source_map::Span; use std::ops::ControlFlow; @@ -56,7 +56,7 @@ struct ParameterCollector { include_nonconstraining: bool, } -impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { match *t.kind() { ty::Alias(ty::Projection, ..) if !self.include_nonconstraining => { diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 9cf82b39ec9..8fc4610ae85 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -5,7 +5,7 @@ use rustc_hir::{ForeignItem, ForeignItemKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder}; +use rustc_middle::ty::{self, ir::TypeFolder, Region, TyCtxt, TypeFoldable}; use rustc_span::def_id::LocalDefId; use rustc_trait_selection::traits; @@ -189,8 +189,8 @@ 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> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseAllBoundRegions<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 079070be279..fb63bf22474 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -7,8 +7,10 @@ use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; +#[cfg(not(bootstrap))] +use rustc_middle::ty::TypeVisitable; use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt}; -use rustc_middle::ty::{DefIdTree, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{DefIdTree, TypeSuperVisitable}; use std::ops::ControlFlow; /// Defines the `TermsContext` basically houses an arena where we can @@ -99,7 +101,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc } } - impl<'tcx> ty::TypeVisitor<'tcx> for OpaqueTypeLifetimeCollector<'tcx> { + impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> { #[instrument(level = "trace", skip(self), ret)] fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { 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 211fe477a2d..b1268c5f792 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, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable}; 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<TyCtxt<'tcx>> for MentionsTy<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index b220a87bc65..f434fb92289 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -3,7 +3,9 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; use rustc_infer::traits::ObligationCauseCode; -use rustc_middle::ty::{self, DefIdTree, Ty, TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{ + self, ir::TypeVisitor, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, +}; use rustc_span::{self, Span}; use rustc_trait_selection::traits; @@ -247,7 +249,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { t: T, ) -> Option<ty::GenericArg<'tcx>> { struct FindAmbiguousParameter<'a, 'tcx>(&'a FnCtxt<'a, 'tcx>, DefId); - impl<'tcx> TypeVisitor<'tcx> for FindAmbiguousParameter<'_, 'tcx> { + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindAmbiguousParameter<'_, 'tcx> { type BreakTy = ty::GenericArg<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> { if let Some(origin) = self.0.type_var_origin(ty) diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 92240b66eb1..60e0ce3494d 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -51,7 +51,6 @@ use rustc_middle::hir::place::*; use rustc_middle::ty::adjustment; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 16b0d48002e..b5e6727bfba 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::AssocItem; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::ToPredicate; -use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_session::lint; use rustc_span::def_id::DefId; diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index ba72aefe39c..c8256e7ec08 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable, + self, ir::TypeFolder, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeSuperFoldable, TypeVisitable, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -963,8 +963,8 @@ 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> { - fn tcx(&self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TypeParamEraser<'_, 'tcx> { + fn interner(&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 0aa34f9dd70..b6c9a88c82d 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -13,8 +13,8 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::Place as HirPlace; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; -use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::visit::TypeSuperVisitable; use rustc_middle::ty::TypeckResults; use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt}; use rustc_span::symbol::sym; @@ -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::ir::TypeVisitor<TyCtxt<'tcx>> for RecursionChecker { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *t.kind() { @@ -763,8 +763,8 @@ struct EraseEarlyRegions<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for EraseEarlyRegions<'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEarlyRegions<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { @@ -779,8 +779,8 @@ impl<'tcx> TypeFolder<'tcx> for EraseEarlyRegions<'tcx> { } } -impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { +impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -797,7 +797,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t); let e = self.report_error(t); self.replaced_with_error = Some(e); - self.tcx().ty_error_with_guaranteed(e) + self.interner().ty_error_with_guaranteed(e) } } } @@ -814,7 +814,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct); let e = self.report_error(ct); self.replaced_with_error = Some(e); - self.tcx().const_error_with_guaranteed(ct.ty(), e) + self.interner().const_error_with_guaranteed(ct.ty(), e) } } } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index c11dcc8587b..6bfdeda3a24 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -10,7 +10,7 @@ use crate::infer::canonical::{ }; use crate::infer::InferCtxt; use rustc_middle::ty::flags::FlagComputation; -use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::subst::GenericArg; use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags}; use std::sync::atomic::Ordering; @@ -326,8 +326,8 @@ struct Canonicalizer<'cx, 'tcx> { binder_index: ty::DebruijnIndex, } -impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -738,7 +738,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { let var = self.canonical_var(info, r.into()); let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32(), None) }; let region = ty::ReLateBound(self.binder_index, br); - self.tcx().mk_region(region) + self.interner().mk_region(region) } /// Given a type variable `ty_var` of the given kind, first check @@ -752,7 +752,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { self.fold_ty(bound_to) } else { let var = self.canonical_var(info, ty_var.into()); - self.tcx().mk_bound(self.binder_index, var.into()) + self.interner().mk_bound(self.binder_index, var.into()) } } @@ -771,7 +771,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { self.fold_const(bound_to) } else { let var = self.canonical_var(info, const_var.into()); - self.tcx().mk_const( + self.interner().mk_const( ty::ConstKind::Bound(self.binder_index, var), self.fold_ty(const_var.ty()), ) diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 4da2a674144..c2bf075444f 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -38,8 +38,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{ - self, AliasKind, FallibleTypeFolder, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable, - TypeSuperFoldable, TypeVisitable, + self, ir::FallibleTypeFolder, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable, + TypeSuperFoldable, }; use rustc_middle::ty::{IntType, UintType}; use rustc_span::{Span, DUMMY_SP}; @@ -844,10 +844,10 @@ struct ConstInferUnifier<'cx, 'tcx> { target_vid: ty::ConstVid<'tcx>, } -impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> { +impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ConstInferUnifier<'_, 'tcx> { type Error = TypeError<'tcx>; - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -875,7 +875,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> { .borrow_mut() .type_variables() .new_var(self.for_universe, origin); - Ok(self.tcx().mk_ty_var(new_var_id)) + Ok(self.interner().mk_ty_var(new_var_id)) } } } @@ -953,7 +953,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for ConstInferUnifier<'_, 'tcx> { }, }, ); - Ok(self.tcx().mk_const(new_var_id, c.ty())) + Ok(self.interner().mk_const(new_var_id, c.ty())) } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 88a0d6def5e..c56149c1149 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1491,7 +1491,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> { + impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypesVisitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) { let span = self.tcx.def_span(def_id); @@ -1783,14 +1783,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } })) { - diag.note_expected_found_extra( - &expected_label, - expected, - &found_label, - found, - &sort_string(values.expected, exp_p), - &sort_string(values.found, found_p), - ); + if let Some(ExpectedFound { found: found_ty, .. }) = exp_found { + // `Future` is a special opaque type that the compiler + // will try to hide in some case such as `async fn`, so + // to make an error more use friendly we will + // avoid to suggest a mismatch type with a + // type that the user usually are not usign + // directly such as `impl Future<Output = u8>`. + if !self.tcx.ty_is_opaque_future(found_ty) { + diag.note_expected_found_extra( + &expected_label, + expected, + &found_label, + found, + &sort_string(values.expected, exp_p), + &sort_string(values.found, found_p), + ); + } + } } } _ => { @@ -2854,6 +2864,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> { pub enum TyCategory { Closure, Opaque, + OpaqueFuture, Generator(hir::GeneratorKind), Foreign, } @@ -2863,6 +2874,7 @@ impl TyCategory { match self { Self::Closure => "closure", Self::Opaque => "opaque type", + Self::OpaqueFuture => "future", Self::Generator(gk) => gk.descr(), Self::Foreign => "foreign type", } @@ -2871,7 +2883,11 @@ impl TyCategory { pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> { match *ty.kind() { ty::Closure(def_id, _) => Some((Self::Closure, def_id)), - ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => Some((Self::Opaque, def_id)), + ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { + let kind = + if tcx.ty_is_opaque_future(ty) { Self::OpaqueFuture } else { Self::Opaque }; + Some((kind, def_id)) + } ty::Generator(def_id, ..) => { Some((Self::Generator(tcx.generator_kind(def_id).unwrap()), 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 6a463583dfb..641477e907d 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 @@ -17,7 +17,8 @@ use rustc_hir::{ TyKind, }; use rustc_middle::ty::{ - self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, + self, ir::TypeVisitor, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, + TypeSuperVisitable, }; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -539,7 +540,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<DefId>); -impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for TraitObjectVisitor { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { 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 40c0c806e1f..d295881d5d7 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::ir::TypeVisitor<TyCtxt<'tcx>> for HighlightBuilder<'tcx> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { if !r.has_name() && self.counter <= 3 { self.highlight.highlighting_region(r, self.counter); diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 73859aca424..7d9a53d1c02 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -238,31 +238,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } }, (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { - diag.span_suggestion_verbose( - exp_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); + self.suggest_await_on_future(diag, exp_span); + diag.span_note(exp_span, "calling an async function returns a future"); } (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() { ObligationCauseCode::Pattern { span: Some(then_span), .. } => { - diag.span_suggestion_verbose( - then_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); + self.suggest_await_on_future(diag, then_span.shrink_to_hi()); } ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { let then_span = self.find_block_span_from_hir_id(*then_id); - diag.span_suggestion_verbose( - then_span.shrink_to_hi(), - "consider `await`ing on the `Future`", - ".await", - Applicability::MaybeIncorrect, - ); + self.suggest_await_on_future(diag, then_span.shrink_to_hi()); } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { ref prior_arms, @@ -283,6 +269,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } + pub fn suggest_await_on_future(&self, diag: &mut Diagnostic, sp: Span) { + diag.span_suggestion_verbose( + sp.shrink_to_hi(), + "consider `await`ing on the `Future`", + ".await", + Applicability::MaybeIncorrect, + ); + } + pub(super) fn suggest_accessing_field_where_appropriate( &self, cause: &ObligationCause<'tcx>, diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 073a2b0753d..41bffdc684d 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -33,8 +33,8 @@ use super::InferCtxt; use rustc_data_structures::fx::FxHashMap; use rustc_middle::infer::unify_key::ToType; -use rustc_middle::ty::fold::TypeFolder; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitable}; +use rustc_middle::ty::fold::ir::TypeFolder; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; use std::collections::hash_map::Entry; pub struct TypeFreshener<'a, 'tcx> { @@ -105,8 +105,8 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -124,13 +124,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { | ty::ReError(_) | ty::ReErased => { // replace all free regions with 'erased - self.tcx().lifetimes.re_erased + self.interner().lifetimes.re_erased } ty::ReStatic => { if self.keep_static { r } else { - self.tcx().lifetimes.re_erased + self.interner().lifetimes.re_erased } } } diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index 6dd6c4e1f5e..cc2f19a5704 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -1,4 +1,4 @@ -use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; use super::type_variable::TypeVariableOrigin; @@ -175,8 +175,8 @@ pub struct InferenceFudger<'a, 'tcx> { const_vars: (Range<ConstVid<'tcx>>, Vec<ConstVariableOrigin>), } -impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index ae196a7133c..b5a10ea6590 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::select; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BoundVarReplacerDelegate; -use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::visit::TypeVisitable; @@ -1852,8 +1852,8 @@ struct InferenceLiteralEraser<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceLiteralEraser<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1870,8 +1870,8 @@ struct ShallowResolver<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, } -impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ShallowResolver<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -2064,8 +2064,8 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( idx: u32, } - impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { + impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceParamAndInferWithPlaceholder<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 1dd5062acaf..644774c93c2 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -29,7 +29,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt}; use rustc_span::Span; use std::fmt::Debug; @@ -792,7 +792,7 @@ struct ScopeInstantiator<'me, 'tcx> { bound_region_scope: &'me mut BoundRegionScope<'tcx>, } -impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> { +impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> { fn visit_binder<T: TypeVisitable<'tcx>>( &mut self, t: &ty::Binder<'tcx, T>, diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index b68b0baaa40..5635e8adf34 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -12,8 +12,8 @@ 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, - TypeVisitable, TypeVisitor, + self, ir::TypeVisitor, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, + TypeSuperVisitable, TypeVisitable, }; use rustc_span::Span; @@ -431,7 +431,7 @@ 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<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP> where OP: FnMut(ty::Region<'tcx>), { diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index a39a40cf9ab..008bf1e9c5d 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,9 +1,12 @@ use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::{FixupError, FixupResult, InferCtxt, Span}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitor}; -use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::fold::{ + ir::{FallibleTypeFolder, TypeFolder}, + TypeSuperFoldable, +}; +use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable}; +use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; use std::ops::ControlFlow; @@ -28,9 +31,9 @@ impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { - TypeFolder::tcx(&self.shallow_resolver) +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticVarResolver<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + TypeFolder::interner(&self.shallow_resolver) } #[inline] @@ -70,8 +73,8 @@ impl<'a, 'tcx> OpportunisticRegionResolver<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticRegionResolver<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -92,7 +95,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> { .borrow_mut() .unwrap_region_constraints() .opportunistic_resolve_var(rid); - TypeFolder::tcx(self).reuse_or_mk_region(r, ty::ReVar(resolved)) + TypeFolder::interner(self).reuse_or_mk_region(r, ty::ReVar(resolved)) } _ => r, } @@ -124,7 +127,7 @@ impl<'a, 'tcx> UnresolvedTypeOrConstFinder<'a, 'tcx> { } } -impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeOrConstFinder<'a, 'tcx> { +impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for UnresolvedTypeOrConstFinder<'a, 'tcx> { type BreakTy = (ty::Term<'tcx>, Option<Span>); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { let t = self.infcx.shallow_resolve(t); @@ -208,10 +211,10 @@ struct FullTypeResolver<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, } -impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { +impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> { type Error = FixupError<'tcx>; - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 1c6ab6a082b..95df6cd62b9 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, ir, TyCtxt}; use std::fmt; use std::ops::ControlFlow; @@ -61,7 +61,7 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { /////////////////////////////////////////////////////////////////////////// // TypeFoldable implementations. -impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> { +impl<'tcx, O: TypeFoldable<'tcx>> ir::TypeFoldable<TyCtxt<'tcx>> for traits::Obligation<'tcx, O> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { Ok(traits::Obligation { cause: self.cause, @@ -72,7 +72,7 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx } } -impl<'tcx, O: TypeVisitable<'tcx>> TypeVisitable<'tcx> for traits::Obligation<'tcx, O> { +impl<'tcx, O: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for traits::Obligation<'tcx, O> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { 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 b0a5d3674ad..88c6ea7efb2 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::ir::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueTypes { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index 23e619221aa..95bb27ef4f4 100644 --- a/compiler/rustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs @@ -17,13 +17,13 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:: vi.construct(|_, index| { let bind = &bindings[index]; quote! { - ::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)? + ::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)? } }) }); s.bound_impl( - quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>), + quote!(::rustc_middle::ty::fold::ir::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>), quote! { fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>( self, diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs index 1f95661ce9d..67057e1a97c 100644 --- a/compiler/rustc_macros/src/type_visitable.rs +++ b/compiler/rustc_macros/src/type_visitable.rs @@ -13,13 +13,13 @@ pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: s.add_bounds(synstructure::AddBounds::Generics); let body_visit = s.each(|bind| { quote! { - ::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor)?; + ::rustc_middle::ty::visit::ir::TypeVisitable::visit_with(#bind, __visitor)?; } }); s.bind_with(|_| synstructure::BindStyle::Move); s.bound_impl( - quote!(::rustc_middle::ty::visit::TypeVisitable<'tcx>), + quote!(::rustc_middle::ty::visit::ir::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>), quote! { fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<'tcx>>( &self, diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index e6e4545d9c3..ada516aa032 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -42,7 +42,7 @@ pub struct Canonical<'tcx, V> { pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>; -impl<'tcx> ty::TypeFoldable<'tcx> for CanonicalVarInfos<'tcx> { +impl<'tcx> ty::ir::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> { fn try_fold_with<F: ty::FallibleTypeFolder<'tcx>>( self, folder: &mut F, diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 56df1a66f9d..e6cd38c0f15 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -48,18 +48,17 @@ #![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(control_flow_enum)] -#![feature(associated_type_defaults)] #![feature(trusted_step)] #![feature(try_blocks)] #![feature(try_reserve_kind)] #![feature(nonzero_ops)] -#![feature(unwrap_infallible)] #![feature(decl_macro)] #![feature(drain_filter)] #![feature(intra_doc_pointers)] #![feature(yeet_expr)] #![feature(result_option_inspect)] #![feature(const_option)] +#![feature(trait_alias)] #![recursion_limit = "512"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 250f3d0797e..57d66ac6a03 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -69,7 +69,7 @@ macro_rules! CloneLiftImpls { macro_rules! TrivialTypeTraversalImpls { (for <$tcx:lifetime> { $($ty:ty,)+ }) => { $( - impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty { + impl<$tcx> $crate::ty::fold::ir::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty { fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$tcx>>( self, _: &mut F, @@ -86,7 +86,7 @@ macro_rules! TrivialTypeTraversalImpls { } } - impl<$tcx> $crate::ty::visit::TypeVisitable<$tcx> for $ty { + impl<$tcx> $crate::ty::visit::ir::TypeVisitable<$crate::ty::TyCtxt<$tcx>> for $ty { #[inline] fn visit_with<F: $crate::ty::visit::TypeVisitor<$tcx>>( &self, @@ -101,7 +101,7 @@ macro_rules! TrivialTypeTraversalImpls { ($($ty:ty,)+) => { TrivialTypeTraversalImpls! { - for <'tcx> { + for<'tcx> { $($ty,)+ } } @@ -115,145 +115,3 @@ macro_rules! TrivialTypeTraversalAndLiftImpls { CloneLiftImpls! { $($t)* } } } - -#[macro_export] -macro_rules! EnumTypeTraversalImpl { - (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { - $($variants:tt)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s - $(where $($wc)*)* - { - fn try_fold_with<V: $crate::ty::fold::FallibleTypeFolder<$tcx>>( - self, - folder: &mut V, - ) -> ::std::result::Result<Self, V::Error> { - EnumTypeTraversalImpl!(@FoldVariants(self, folder) input($($variants)*) output()) - } - } - }; - - (impl<$($p:tt),*> TypeVisitable<$tcx:tt> for $s:path { - $($variants:tt)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::visit::TypeVisitable<$tcx> for $s - $(where $($wc)*)* - { - fn visit_with<V: $crate::ty::visit::TypeVisitor<$tcx>>( - &self, - visitor: &mut V, - ) -> ::std::ops::ControlFlow<V::BreakTy> { - 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::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)* - ) - ) - }; - - (@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/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 10ac7e0d39a..6f42b69633c 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -7,10 +7,10 @@ use crate::mir::interpret::{ }; use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; +use crate::ty::fold::{ir::TypeFoldable, FallibleTypeFolder}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::visit::{TypeVisitable, TypeVisitor}; -use crate::ty::{self, DefIdTree, List, Ty, TyCtxt}; +use crate::ty::{self, ir, DefIdTree, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, ScalarInt, UserTypeAnnotationIndex}; use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; @@ -705,7 +705,11 @@ pub enum BindingForm<'tcx> { RefForGuard, } -TrivialTypeTraversalAndLiftImpls! { BindingForm<'tcx>, } +TrivialTypeTraversalAndLiftImpls! { + for<'tcx> { + BindingForm<'tcx>, + } +} mod binding_form_impl { use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -2742,7 +2746,7 @@ impl UserTypeProjection { } } -impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for UserTypeProjection { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { Ok(UserTypeProjection { base: self.base.try_fold_with(folder)?, @@ -2751,7 +2755,7 @@ impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { } } -impl<'tcx> TypeVisitable<'tcx> for UserTypeProjection { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for UserTypeProjection { fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> { self.base.visit_with(visitor) // Note: there's nothing in `self.proj` to visit. diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 0705b4cff53..006085c0ef5 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -30,25 +30,25 @@ TrivialTypeTraversalImpls! { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx [InlineAsmTemplatePiece] { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { Ok(self) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx [Span] { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [Span] { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { Ok(self) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<PlaceElem<'tcx>> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v)) } } -impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> { +impl<'tcx, R: Idx, C: Idx> TypeFoldable<TyCtxt<'tcx>> for BitMatrix<R, C> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { Ok(self) } diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs index d44c6809bd8..e7c5d44b22e 100644 --- a/compiler/rustc_middle/src/mir/type_visitable.rs +++ b/compiler/rustc_middle/src/mir/type_visitable.rs @@ -2,7 +2,7 @@ use super::*; -impl<'tcx, R: Idx, C: Idx> TypeVisitable<'tcx> for BitMatrix<R, C> { +impl<'tcx, R: Idx, C: Idx> ir::TypeVisitable<TyCtxt<'tcx>> for BitMatrix<R, C> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { ControlFlow::Continue(()) } diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 63f9c32f0a7..bddf84880d2 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -2,7 +2,10 @@ use std::ops::ControlFlow; use rustc_data_structures::intern::Interned; -use crate::ty::{FallibleTypeFolder, Ty, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor}; +use crate::ty::{ + ir::{self, TypeFoldable, TypeVisitable}, + FallibleTypeFolder, Ty, TyCtxt, TypeFolder, TypeVisitor, +}; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>); @@ -23,27 +26,29 @@ pub struct ExternalConstraintsData<'tcx> { pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, } -impl<'tcx> TypeFoldable<'tcx> for ExternalConstraints<'tcx> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - Ok(FallibleTypeFolder::tcx(folder).intern_external_constraints(ExternalConstraintsData { - regions: (), - opaque_types: self - .opaque_types - .iter() - .map(|opaque| opaque.try_fold_with(folder)) - .collect::<Result<_, F::Error>>()?, - })) + Ok(ir::FallibleTypeFolder::interner(folder).intern_external_constraints( + ExternalConstraintsData { + regions: (), + opaque_types: self + .opaque_types + .iter() + .map(|opaque| opaque.try_fold_with(folder)) + .collect::<Result<_, F::Error>>()?, + }, + )) } fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self { - TypeFolder::tcx(folder).intern_external_constraints(ExternalConstraintsData { + ir::TypeFolder::interner(folder).intern_external_constraints(ExternalConstraintsData { regions: (), opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(), }) } } -impl<'tcx> TypeVisitable<'tcx> for ExternalConstraints<'tcx> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>( &self, visitor: &mut V, diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 5de758ad9ba..b7f0a0be75e 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -1,7 +1,6 @@ //! A subset of a mir body used for const evaluatability checking. use crate::ty::{ - self, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitable, + self, ir::TypeFolder, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, }; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; @@ -53,8 +52,8 @@ impl<'tcx> TyCtxt<'tcx> { tcx: TyCtxt<'tcx>, } - impl<'tcx> TypeFolder<'tcx> for Expander<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { + impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Expander<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5962384241e..02088fffeb6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -100,9 +100,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type AdtDef = ty::AdtDef<'tcx>; type SubstsRef = ty::SubstsRef<'tcx>; type DefId = DefId; + type Binder<T> = Binder<'tcx, T>; type Ty = Ty<'tcx>; type Const = ty::Const<'tcx>; type Region = Region<'tcx>; + type Predicate = Predicate<'tcx>; type TypeAndMut = TypeAndMut<'tcx>; type Mutability = hir::Mutability; type Movability = hir::Movability; diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 0a30ae9d0aa..fc529f5d1d0 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -3,9 +3,10 @@ use std::ops::ControlFlow; use crate::ty::{ - visit::TypeVisitable, AliasTy, Const, ConstKind, DefIdTree, FallibleTypeFolder, InferConst, - InferTy, Opaque, PolyTraitPredicate, Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, - TypeSuperVisitable, TypeVisitor, + ir::{FallibleTypeFolder, TypeVisitor}, + visit::TypeVisitable, + AliasTy, Const, ConstKind, DefIdTree, InferConst, InferTy, Opaque, PolyTraitPredicate, + Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, }; use rustc_data_structures::fx::FxHashMap; @@ -460,7 +461,7 @@ pub struct IsSuggestableVisitor<'tcx> { infer_suggestable: bool, } -impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { @@ -535,10 +536,10 @@ pub struct MakeSuggestableFolder<'tcx> { infer_suggestable: bool, } -impl<'tcx> FallibleTypeFolder<'tcx> for MakeSuggestableFolder<'tcx> { +impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> { type Error = (); - fn tcx(&self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 9e4f90caab0..d3b031bf875 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -1,5 +1,4 @@ -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; -use crate::ty::visit::TypeVisitable; +use crate::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; use crate::ty::{self, Ty, TyCtxt, TypeFlags}; pub(super) fn provide(providers: &mut ty::query::Providers) { @@ -35,8 +34,8 @@ struct RegionEraserVisitor<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index bd78705cdb5..9c171a69d06 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -271,7 +271,7 @@ impl<'tcx> Ty<'tcx> { ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), ty::Alias(ty::Projection, _) => "associated type".into(), ty::Param(p) => format!("type parameter `{p}`").into(), - ty::Alias(ty::Opaque, ..) => "opaque type".into(), + ty::Alias(ty::Opaque, ..) => if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() }, ty::Error(_) => "type error".into(), _ => { let width = tcx.sess.diagnostic_width(); diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index c0d319edf76..352daa8fc29 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -1,209 +1,18 @@ -//! 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, 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<'tcx>: TypeVisitable<'tcx> { - /// 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<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error>; - - /// 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<F: TypeFolder<'tcx>>(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> { - /// 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<F: FallibleTypeFolder<'tcx>>( - self, - folder: &mut F, - ) -> Result<Self, F::Error>; - - /// 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<F: TypeFolder<'tcx>>(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<'tcx>: FallibleTypeFolder<'tcx, Error = !> { - fn tcx(&self) -> TyCtxt<'tcx>; - - fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> - where - T: TypeFoldable<'tcx>, - { - t.super_fold_with(self) - } - - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - t.super_fold_with(self) - } - - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - r.super_fold_with(self) - } - - fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { - c.super_fold_with(self) - } - - fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { - 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<'tcx>: Sized { - type Error; - - fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; +pub trait TypeFoldable<'tcx> = ir::TypeFoldable<TyCtxt<'tcx>> + TypeVisitable<'tcx>; +pub trait TypeSuperFoldable<'tcx> = ir::TypeSuperFoldable<TyCtxt<'tcx>>; +pub trait TypeFolder<'tcx> = ir::TypeFolder<TyCtxt<'tcx>>; +pub trait FallibleTypeFolder<'tcx> = ir::FallibleTypeFolder<TyCtxt<'tcx>>; - fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error> - where - T: TypeFoldable<'tcx>, - { - t.try_super_fold_with(self) - } - - fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { - t.try_super_fold_with(self) - } - - fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { - r.try_super_fold_with(self) - } - - fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> { - c.try_super_fold_with(self) - } - - fn try_fold_predicate( - &mut self, - p: ty::Predicate<'tcx>, - ) -> Result<ty::Predicate<'tcx>, Self::Error> { - 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 -where - F: TypeFolder<'tcx>, -{ - type Error = !; - - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { - TypeFolder::tcx(self) - } - - fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, !> - where - T: TypeFoldable<'tcx>, - { - Ok(self.fold_binder(t)) - } - - fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, !> { - Ok(self.fold_ty(t)) - } - - fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> { - Ok(self.fold_region(r)) - } - - fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, !> { - Ok(self.fold_const(c)) - } - - fn try_fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> Result<ty::Predicate<'tcx>, !> { - Ok(self.fold_predicate(p)) - } +pub mod ir { + pub use rustc_type_ir::fold::{ + FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, + }; } /////////////////////////////////////////////////////////////////////////// @@ -221,13 +30,13 @@ where pub ct_op: H, } -impl<'tcx, F, G, H> TypeFolder<'tcx> for BottomUpFolder<'tcx, F, G, H> +impl<'tcx, F, G, H> ir::TypeFolder<TyCtxt<'tcx>> for BottomUpFolder<'tcx, F, G, H> where F: FnMut(Ty<'tcx>) -> Ty<'tcx>, G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>, H: FnMut(ty::Const<'tcx>) -> ty::Const<'tcx>, { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -311,8 +120,8 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> ir::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -385,11 +194,11 @@ impl<'tcx, D: BoundVarReplacerDelegate<'tcx>> BoundVarReplacer<'tcx, D> { } } -impl<'tcx, D> TypeFolder<'tcx> for BoundVarReplacer<'tcx, D> +impl<'tcx, D> ir::TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'tcx, D> where D: BoundVarReplacerDelegate<'tcx>, { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -651,8 +460,8 @@ impl<'tcx> Shifter<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'tcx> ir::TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8b4fccc58bd..55f2395e531 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -1,6 +1,6 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitable}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; use crate::ty::{EarlyBinder, InternalSubsts, SubstsRef}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::Namespace; @@ -674,8 +674,8 @@ fn polymorphize<'tcx>( tcx: TyCtxt<'tcx>, } - impl<'tcx> ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + impl<'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for PolymorphizationFolder<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 4c285582138..1d76f435e26 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1120,6 +1120,13 @@ impl From<call::AdjustForForeignAbiError> for FnAbiError<'_> { impl<'tcx> fmt::Display for FnAbiError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(bootstrap)] + match self { + Self::Layout(err) => fmt::Display::fmt(err, f), + Self::AdjustForForeignAbi(err) => fmt::Display::fmt(err, f), + } + + #[cfg(not(bootstrap))] match self { Self::Layout(err) => err.fmt(f), Self::AdjustForForeignAbi(err) => err.fmt(f), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index fa2d3b89cf4..4ed0484438f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -146,6 +146,10 @@ mod structural_impls; mod sty; mod typeck_results; +pub mod ir { + pub use super::{fold::ir::*, visit::ir::*}; +} + // Data types pub type RegisteredTools = FxHashSet<Ident>; @@ -913,13 +917,13 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for Term<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { Ok(self.unpack().try_fold_with(folder)?.pack()) } } -impl<'tcx> TypeVisitable<'tcx> for Term<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.unpack().visit_with(visitor) } @@ -1615,7 +1619,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> { fn try_fold_with<F: ty::fold::FallibleTypeFolder<'tcx>>( self, folder: &mut F, @@ -1628,7 +1632,7 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for ParamEnv<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.caller_bounds().visit_with(visitor)?; self.reveal().visit_with(visitor) diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index ee13920d52e..825e5fbe232 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -9,7 +9,10 @@ use crate::mir; use crate::traits::query::NoSolution; -use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; +use crate::ty::fold::{ + ir::{FallibleTypeFolder, TypeFolder}, + TypeFoldable, +}; use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt}; #[derive(Debug, Copy, Clone, HashStable, TyEncodable, TyDecodable)] @@ -202,8 +205,8 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for NormalizeAfterErasingRegionsFolder<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -238,10 +241,10 @@ impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> { } } -impl<'tcx> FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> { +impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for TryNormalizeAfterErasingRegionsFolder<'tcx> { type Error = NormalizationError<'tcx>; - fn tcx(&self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index a5ebdbc8792..66c878c8b63 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -1,7 +1,9 @@ use crate::error::ConstNotUsedTraitAlias; -use crate::ty::fold::{TypeFolder, TypeSuperFoldable}; +use crate::ty::fold::{ir::TypeFolder, TypeSuperFoldable}; use crate::ty::subst::{GenericArg, GenericArgKind}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; +#[cfg(not(bootstrap))] +use crate::ty::TypeFoldable; +use crate::ty::{self, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_span::def_id::DefId; use rustc_span::Span; @@ -91,8 +93,8 @@ impl<'tcx> ReverseMapper<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -141,7 +143,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().re_error(e) + self.interner().re_error(e) } } } @@ -186,7 +188,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { .emit(); } - self.tcx().ty_error() + self.interner().ty_error() } } } @@ -214,7 +216,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { }); } - self.tcx().const_error(ct.ty()) + self.interner().const_error(ct.ty()) } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c4a95ddacbf..f50a5d89d3d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2221,8 +2221,8 @@ struct RegionFolder<'a, 'tcx> { ), } -impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -2493,7 +2493,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } } - impl<'tcx> ty::visit::TypeVisitor<'tcx> for RegionNameCollector<'tcx> { + impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for RegionNameCollector<'tcx> { type BreakTy = (); fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 1ef66b01ea0..97ee2b1fc5d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -1,20 +1,19 @@ -//! This module contains implements of the `Lift` 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. +//! This module contains implementations of the `Lift`, `TypeFoldable` and +//! `TypeVisitable` 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::mir::interpret; use crate::mir::{Field, ProjectionKind}; -use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; +use crate::ty::fold::{ir::TypeSuperFoldable, FallibleTypeFolder, TypeFoldable}; 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 rustc_data_structures::functor::IdFunctor; +use crate::ty::visit::{ir::TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use crate::ty::{self, ir, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; 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; @@ -195,17 +194,27 @@ impl<'tcx> fmt::Debug for AliasTy<'tcx> { // Atomic structs // // For things that don't carry any arena-allocated data (and are -// copy...), just add them to this list. +// copy...), just add them to one of these lists as appropriat. -TrivialTypeTraversalAndLiftImpls! { +// For things for which the type library provides traversal implementations +// for all Interners, we only need to provide a Lift implementation: +CloneLiftImpls! { (), bool, usize, - ::rustc_target::abi::VariantIdx, u16, u32, u64, String, + rustc_type_ir::DebruijnIndex, +} + +// For things about which the type library does not know, or does not +// provide any traversal implementations, we need to provide both a Lift +// implementation and traversal implementations (the latter only for +// TyCtxt<'_> interners). +TrivialTypeTraversalAndLiftImpls! { + ::rustc_target::abi::VariantIdx, crate::middle::region::Scope, crate::ty::FloatTy, ::rustc_ast::InlineAsmOptions, @@ -257,7 +266,6 @@ TrivialTypeTraversalAndLiftImpls! { Field, interpret::Scalar, rustc_target::abi::Size, - rustc_type_ir::DebruijnIndex, ty::BoundVar, ty::Placeholder<ty::BoundVar>, } @@ -360,235 +368,34 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { } /////////////////////////////////////////////////////////////////////////// -// TypeFoldable implementations. +// Traversal implementations. /// AdtDefs are basically the same as a DefId. -impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { Ok(self) } } -impl<'tcx> TypeVisitable<'tcx> for ty::AdtDef<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { ControlFlow::Continue(()) } } -impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>( - self, - folder: &mut F, - ) -> Result<(T, U), F::Error> { - Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?)) - } -} - -impl<'tcx, T: TypeVisitable<'tcx>, U: TypeVisitable<'tcx>> TypeVisitable<'tcx> for (T, U) { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - self.0.visit_with(visitor)?; - self.1.visit_with(visitor) - } -} - -impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx> - for (A, B, C) -{ - fn try_fold_with<F: FallibleTypeFolder<'tcx>>( - 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<'tcx, A: TypeVisitable<'tcx>, B: TypeVisitable<'tcx>, C: TypeVisitable<'tcx>> - TypeVisitable<'tcx> for (A, B, C) -{ - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - self.0.visit_with(visitor)?; - self.1.visit_with(visitor)?; - self.2.visit_with(visitor) - } -} - -EnumTypeTraversalImpl! { - impl<'tcx, T> TypeFoldable<'tcx> for Option<T> { - (Some)(a), - (None), - } where T: TypeFoldable<'tcx> -} -EnumTypeTraversalImpl! { - impl<'tcx, T> TypeVisitable<'tcx> for Option<T> { - (Some)(a), - (None), - } where T: TypeVisitable<'tcx> -} - -EnumTypeTraversalImpl! { - impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> { - (Ok)(a), - (Err)(a), - } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>, -} -EnumTypeTraversalImpl! { - impl<'tcx, T, E> TypeVisitable<'tcx> for Result<T, E> { - (Ok)(a), - (Err)(a), - } where T: TypeVisitable<'tcx>, E: TypeVisitable<'tcx>, -} - -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>( - mut self, - folder: &mut F, - ) -> Result<Self, F::Error> { - // 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<ManuallyDrop<T>>` so that - // panicking during `make_mut` does not leak the `T`. - Rc::make_mut(&mut self); - - // Casting to `Rc<ManuallyDrop<T>>` is safe because `ManuallyDrop` - // is `repr(transparent)`. - let ptr = Rc::into_raw(self).cast::<ManuallyDrop<T>>(); - 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<T>`. - Ok(Rc::from_raw(Rc::into_raw(unique).cast())) - } - } -} - -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Rc<T> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - (**self).visit_with(visitor) - } -} - -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>( - mut self, - folder: &mut F, - ) -> Result<Self, F::Error> { - // 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<ManuallyDrop<T>>` so that - // panicking during `make_mut` does not leak the `T`. - Arc::make_mut(&mut self); - - // Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop` - // is `repr(transparent)`. - let ptr = Arc::into_raw(self).cast::<ManuallyDrop<T>>(); - 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<T>`. - Ok(Arc::from_raw(Arc::into_raw(unique).cast())) - } - } -} - -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Arc<T> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - (**self).visit_with(visitor) - } -} - -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_id(|value| value.try_fold_with(folder)) - } -} - -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<T> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - (**self).visit_with(visitor) - } -} - -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_id(|t| t.try_fold_with(folder)) - } -} - -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec<T> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_id(|t| t.try_fold_with(folder)) - } -} - -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<[T]> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { +impl<'tcx, T: TypeFoldable<'tcx>> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { folder.try_fold_binder(self) } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for ty::Binder<'tcx, T> { +impl<'tcx, T: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_binder(self) } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T> { +impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( self, folder: &mut F, @@ -597,43 +404,43 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<'tcx> for ty::Binder<'tcx, T> { +impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.as_ref().skip_binder().visit_with(visitor) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Const<'tcx>> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Const<'tcx>> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v.iter())) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ProjectionKind> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) } } -impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for Ty<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { folder.try_fold_ty(self) } } -impl<'tcx> TypeVisitable<'tcx> for Ty<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_ty(*self) } } -impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> { +impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> { fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( self, folder: &mut F, @@ -679,11 +486,11 @@ impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> { | ty::Foreign(..) => return Ok(self), }; - Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) }) + Ok(if *self.kind() == kind { self } else { folder.interner().mk_ty(kind) }) } } -impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> { +impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { match self.kind() { ty::RawPtr(ref tm) => tm.visit_with(visitor), @@ -727,19 +534,19 @@ impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { folder.try_fold_region(self) } } -impl<'tcx> TypeVisitable<'tcx> for ty::Region<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_region(*self) } } -impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> { +impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> { fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( self, _folder: &mut F, @@ -748,81 +555,59 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> { } } -impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> { +impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { ControlFlow::Continue(()) } } -impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { folder.try_fold_predicate(self) } } -impl<'tcx> TypeVisitable<'tcx> for ty::Predicate<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_predicate(*self) } - - #[inline] - fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { - self.outer_exclusive_binder() > binder - } - - #[inline] - fn has_type_flags(&self, flags: ty::TypeFlags) -> bool { - self.flags().intersects(flags) - } } -impl<'tcx> TypeSuperFoldable<'tcx> for ty::Predicate<'tcx> { +impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( self, folder: &mut F, ) -> Result<Self, F::Error> { let new = self.kind().try_fold_with(folder)?; - Ok(folder.tcx().reuse_or_mk_predicate(self, new)) + Ok(folder.interner().reuse_or_mk_predicate(self, new)) } } -impl<'tcx> TypeSuperVisitable<'tcx> for ty::Predicate<'tcx> { +impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.kind().visit_with(visitor) } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Predicate<'tcx>> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v)) } } -impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_id(|x| x.try_fold_with(folder)) - } -} - -impl<'tcx, T: TypeVisitable<'tcx>, I: Idx> TypeVisitable<'tcx> for IndexVec<I, T> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - -impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { folder.try_fold_const(self) } } -impl<'tcx> TypeVisitable<'tcx> for ty::Const<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_const(*self) } } -impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> { +impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> { fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( self, folder: &mut F, @@ -830,39 +615,39 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> { let ty = self.ty().try_fold_with(folder)?; let kind = self.kind().try_fold_with(folder)?; if ty != self.ty() || kind != self.kind() { - Ok(folder.tcx().mk_const(kind, ty)) + Ok(folder.interner().mk_const(kind, ty)) } else { Ok(self) } } } -impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> { +impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.ty().visit_with(visitor)?; self.kind().visit_with(visitor) } } -impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for InferConst<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { Ok(self) } } -impl<'tcx> TypeVisitable<'tcx> for InferConst<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for InferConst<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { ControlFlow::Continue(()) } } -impl<'tcx> TypeSuperVisitable<'tcx> for ty::UnevaluatedConst<'tcx> { +impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.substs.visit_with(visitor) } } -impl<'tcx> TypeVisitable<'tcx> for TyAndLayout<'tcx, Ty<'tcx>> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_ty(self.ty) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 89cde91e755..abde81236e2 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -7,8 +7,10 @@ use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use crate::ty::visit::ValidateBoundVars; use crate::ty::InferTy::*; use crate::ty::{ - self, AdtDef, DefIdTree, Discr, FallibleTypeFolder, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, + ir::{FallibleTypeFolder, TypeVisitor}, + AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperFoldable, + TypeSuperVisitable, TypeVisitable, }; use crate::ty::{List, ParamEnv}; use hir::def::DefKind; @@ -1147,10 +1149,10 @@ struct SkipBindersAt<'tcx> { index: ty::DebruijnIndex, } -impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> { +impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for SkipBindersAt<'tcx> { type Error = (); - fn tcx(&self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1171,7 +1173,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> { if index == self.index { Err(()) } else { - Ok(self.tcx().mk_bound(index.shifted_out(1), bv)) + Ok(self.interner().mk_bound(index.shifted_out(1), bv)) } } else { ty.try_super_fold_with(self) @@ -1185,7 +1187,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> { if index == self.index { Err(()) } else { - Ok(self.tcx().mk_region(ty::ReLateBound(index.shifted_out(1), bv))) + Ok(self.interner().mk_region(ty::ReLateBound(index.shifted_out(1), bv))) } } else { r.try_super_fold_with(self) @@ -1199,7 +1201,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> { if index == self.index { Err(()) } else { - Ok(self.tcx().mk_const( + Ok(self.interner().mk_const( ty::ConstKind::Bound(index.shifted_out(1), bv), ct.ty().try_fold_with(self)?, )) @@ -2038,7 +2040,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<TyCtxt<'tcx>> for ContainsTyVisitor<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { @@ -2056,7 +2058,7 @@ impl<'tcx> Ty<'tcx> { pub fn contains_closure(self) -> bool { struct ContainsClosureVisitor; - impl<'tcx> TypeVisitor<'tcx> for ContainsClosureVisitor { + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsClosureVisitor { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index cf1bb5f8ac8..a6ab7440c8e 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -1,10 +1,10 @@ // Type substitutions. use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use crate::ty::fold::{ir::TypeFolder, FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; use crate::ty::visit::{TypeVisitable, TypeVisitor}; -use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; +use crate::ty::{self, ir, Lift, List, ParamConst, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; @@ -227,7 +227,7 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { } } -impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), @@ -237,7 +237,7 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for GenericArg<'tcx> { +impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> { fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), @@ -475,7 +475,7 @@ impl<'tcx> InternalSubsts<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. @@ -486,7 +486,11 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { match self.len() { 1 => { let param0 = self[0].try_fold_with(folder)?; - if param0 == self[0] { Ok(self) } else { Ok(folder.tcx().intern_substs(&[param0])) } + if param0 == self[0] { + Ok(self) + } else { + Ok(folder.interner().intern_substs(&[param0])) + } } 2 => { let param0 = self[0].try_fold_with(folder)?; @@ -494,7 +498,7 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { if param0 == self[0] && param1 == self[1] { Ok(self) } else { - Ok(folder.tcx().intern_substs(&[param0, param1])) + Ok(folder.interner().intern_substs(&[param0, param1])) } } 0 => Ok(self), @@ -503,7 +507,7 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { +impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { // This code is fairly hot, though not as hot as `SubstsRef`. // @@ -527,7 +531,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { if param0 == self[0] && param1 == self[1] { Ok(self) } else { - Ok(folder.tcx().intern_type_list(&[param0, param1])) + Ok(folder.interner().intern_type_list(&[param0, param1])) } } _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)), @@ -535,7 +539,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List<T> { +impl<'tcx, T: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> { #[inline] fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.iter().try_for_each(|t| t.visit_with(visitor)) @@ -553,8 +557,8 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List<T> { pub struct EarlyBinder<T>(pub T); /// For early binders, you should first call `subst` before using any visitors. -impl<'tcx, T> !TypeFoldable<'tcx> for ty::EarlyBinder<T> {} -impl<'tcx, T> !TypeVisitable<'tcx> for ty::EarlyBinder<T> {} +impl<'tcx, T> !ir::TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {} +impl<'tcx, T> !ir::TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {} impl<T> EarlyBinder<T> { pub fn as_ref(&self) -> EarlyBinder<&T> { @@ -776,9 +780,9 @@ struct SubstFolder<'a, 'tcx> { binders_passed: u32, } -impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> { #[inline] - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -987,7 +991,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { return val; } - let result = ty::fold::shift_vars(TypeFolder::tcx(self), val, self.binders_passed); + let result = ty::fold::shift_vars(TypeFolder::interner(self), val, self.binders_passed); debug!("shift_vars: shifted result = {:?}", result); result diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 796164b0d6a..e907ce46c86 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -4,8 +4,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; use crate::ty::layout::IntegerExt; use crate::ty::{ - self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitable, + self, ir::TypeFolder, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, + TypeSuperFoldable, }; use crate::ty::{GenericArgKind, SubstsRef}; use rustc_apfloat::Float as _; @@ -842,8 +842,8 @@ impl<'tcx> OpaqueTypeExpander<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1343,7 +1343,7 @@ where for t in iter { new_list.push(t.try_fold_with(folder)?) } - Ok(intern(folder.tcx(), &new_list)) + Ok(intern(folder.interner(), &new_list)) } Some((_, Err(err))) => { return Err(err); diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index d7b7a094737..8a93b59900e 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -1,69 +1,19 @@ -//! 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, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; use rustc_errors::ErrorGuaranteed; 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<'tcx>: 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<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>; +pub trait TypeVisitable<'tcx> = ir::TypeVisitable<TyCtxt<'tcx>> + TypeVisitableExt<'tcx>; +pub trait TypeSuperVisitable<'tcx> = ir::TypeSuperVisitable<TyCtxt<'tcx>>; +pub trait TypeVisitor<'tcx> = ir::TypeVisitor<TyCtxt<'tcx>>; + +pub mod ir { + pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +} +pub trait TypeVisitableExt<'tcx>: ir::TypeVisitable<TyCtxt<'tcx>> { /// 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 @@ -185,45 +135,7 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { } } -pub trait TypeSuperVisitable<'tcx>: TypeVisitable<'tcx> { - /// 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<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>; -} - -/// 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 { - type BreakTy = !; - - fn visit_binder<T: TypeVisitable<'tcx>>( - &mut self, - t: &Binder<'tcx, T>, - ) -> ControlFlow<Self::BreakTy> { - t.super_visit_with(self) - } - - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - t.super_visit_with(self) - } - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - r.super_visit_with(self) - } - - fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { - c.super_visit_with(self) - } - - fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> { - p.super_visit_with(self) - } -} +impl<'tcx, T: ir::TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {} /////////////////////////////////////////////////////////////////////////// // Region folder @@ -278,7 +190,7 @@ impl<'tcx> TyCtxt<'tcx> { callback: F, } - impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<F> + impl<'tcx, F> ir::TypeVisitor<TyCtxt<'tcx>> for RegionVisitor<F> where F: FnMut(ty::Region<'tcx>) -> bool, { @@ -380,7 +292,7 @@ impl<'tcx> ValidateBoundVars<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> { +impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> { type BreakTy = (); fn visit_binder<T: TypeVisitable<'tcx>>( @@ -492,7 +404,7 @@ struct HasEscapingVarsVisitor { outer_index: ty::DebruijnIndex, } -impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor { +impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor { type BreakTy = FoundEscapingVars; fn visit_binder<T: TypeVisitable<'tcx>>( @@ -569,7 +481,7 @@ impl std::fmt::Debug for HasTypeFlagsVisitor { } } -impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { +impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor { type BreakTy = FoundFlags; #[inline] @@ -639,7 +551,7 @@ impl LateBoundRegionsCollector { } } -impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { +impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector { fn visit_binder<T: TypeVisitable<'tcx>>( &mut self, t: &Binder<'tcx, T>, @@ -701,7 +613,7 @@ impl MaxUniverse { } } -impl<'tcx> TypeVisitor<'tcx> for MaxUniverse { +impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for MaxUniverse { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { if let ty::Placeholder(placeholder) = t.kind() { self.max_universe = ty::UniverseIndex::from_u32( diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 31a3ffbb1d8..83b8988ceca 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -189,9 +189,7 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; -use rustc_middle::ty::{ - self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitable, VtblEntry, -}; +use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, VtblEntry}; use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext}; use rustc_session::config::EntryFnType; use rustc_session::lint::builtin::LARGE_ASSIGNMENTS; diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index cf13d4584a1..aba842817ef 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ self, query::Providers, subst::SubstsRef, - visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, + visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable}, Const, Ty, TyCtxt, UnusedGenericParams, }; use rustc_span::symbol::sym; @@ -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<TyCtxt<'tcx>> for MarkUsedGenericParams<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> { if !c.has_non_region_param() { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 43552861532..9cff62e8514 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -28,7 +28,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind}; -use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{ir::TypeVisitor, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, sym, Ident}; @@ -174,7 +174,7 @@ where } } -impl<'tcx, V> TypeVisitor<'tcx> for DefIdVisitorSkeleton<'_, 'tcx, V> +impl<'tcx, V> TypeVisitor<TyCtxt<'tcx>> for DefIdVisitorSkeleton<'_, 'tcx, V> where V: DefIdVisitor<'tcx> + ?Sized, { diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 50c1787ef8c..c0bfe152a1e 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -6,7 +6,7 @@ use rustc_hir::lang_items::LangItem; 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::{self, Ty, TypeFoldable}; use rustc_middle::ty::{GenericArg, ToPredicate}; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 4fea49893a6..b52200e066f 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -14,7 +14,7 @@ use rustc_infer::traits::specialization_graph::LeafDef; use rustc_infer::traits::Reveal; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{ProjectionPredicate, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::{ir::TypeVisitor, ProjectionPredicate, TypeSuperVisitable}; use rustc_middle::ty::{ToPredicate, TypeVisitable}; use rustc_span::{sym, DUMMY_SP}; use std::iter; @@ -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<TyCtxt<'tcx>> for ContainsTerm<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { if t.needs_infer() { diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6a840704e86..3adb15cb441 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -8,7 +8,8 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::InferCtxt; use crate::traits::project::ProjectAndUnifyResult; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::fold::{ir::TypeFolder, TypeSuperFoldable}; +#[cfg(not(bootstrap))] use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ImplPolarity, Region, RegionVid}; @@ -858,8 +859,8 @@ pub struct RegionReplacer<'a, 'tcx> { tcx: TyCtxt<'tcx>, } -impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionReplacer<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 61f508a7a07..a95694e5144 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -22,7 +22,7 @@ use rustc_infer::traits::util; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{self, ir::TypeVisitor, ImplSubject, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::fmt::Debug; @@ -627,7 +627,7 @@ enum OrphanCheckEarlyExit<'tcx> { LocalTy(Ty<'tcx>), } -impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx> { type BreakTy = OrphanCheckEarlyExit<'tcx>; fn visit_region(&mut self, _r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { 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 786473457ae..dd9b5b534d7 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -14,7 +14,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::abstract_const::NotConstEvaluatable; -use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{self, ir::TypeVisitor, TyCtxt, TypeVisitable}; use rustc_span::Span; use std::ops::ControlFlow; @@ -171,7 +171,7 @@ fn satisfied_from_param_env<'tcx>( single_match: Option<Result<ty::Const<'tcx>, ()>>, } - impl<'a, 'tcx> TypeVisitor<'tcx> for Visitor<'a, 'tcx> { + impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for Visitor<'a, 'tcx> { type BreakTy = (); fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { 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 4867855c2ae..c2565b7a3aa 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -34,11 +34,10 @@ use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::fold::{ir::TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print}; use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, - TypeVisitable, }; use rustc_session::config::TraitSolver; use rustc_session::Limit; @@ -2675,8 +2674,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { var_map: FxHashMap<Ty<'tcx>, Ty<'tcx>>, } - impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ParamToVarFolder<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -2964,7 +2963,7 @@ impl ArgKind { struct HasNumericInferVisitor; -impl<'tcx> ty::TypeVisitor<'tcx> for HasNumericInferVisitor { +impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for HasNumericInferVisitor { type BreakTy = (); fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { 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 cca178299df..0a1dfa7925b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -30,10 +30,10 @@ use rustc_middle::hir::map; use rustc_middle::ty::error::TypeError::{self, Sorts}; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{ - self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree, - GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts, - IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitable, TypeckResults, + self, ir::TypeFolder, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, + DefIdTree, GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts, + IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeSuperFoldable, + TypeckResults, }; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -4081,7 +4081,7 @@ struct ReplaceImplTraitFolder<'tcx> { replace_ty: Ty<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for ReplaceImplTraitFolder<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> 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 { @@ -4091,7 +4091,7 @@ impl<'tcx> TypeFolder<'tcx> for ReplaceImplTraitFolder<'tcx> { t.super_fold_with(self) } - fn tcx(&self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 83458017e00..067e63de911 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -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::ir::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { // 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 977446894e7..c12ba103c34 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -19,7 +19,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, InternalSubsts}; use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, ir::TypeVisitor, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, }; use rustc_middle::ty::{Predicate, ToPredicate}; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; @@ -836,7 +836,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>( supertraits: Option<Vec<DefId>>, } - impl<'tcx> TypeVisitor<'tcx> for IllegalSelfTypeVisitor<'tcx> { + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalSelfTypeVisitor<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index c2bce774bb5..a380d4697ea 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -30,7 +30,7 @@ use rustc_infer::infer::at::At; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::ImplSourceBuiltinData; use rustc_middle::traits::select::OverflowError; -use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable}; use rustc_middle::ty::DefIdTree; use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt}; @@ -448,8 +448,8 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { } } -impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { - fn tcx<'c>(&'c self) -> TyCtxt<'tcx> { +impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.selcx.tcx() } @@ -503,7 +503,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { Reveal::UserFacing => ty.super_fold_with(self), Reveal::All => { - let recursion_limit = self.tcx().recursion_limit(); + let recursion_limit = self.interner().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( &ty, @@ -514,8 +514,8 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { } let substs = substs.fold_with(self); - let generic_ty = self.tcx().bound_type_of(def_id); - let concrete_ty = generic_ty.subst(self.tcx(), substs); + let generic_ty = self.interner().bound_type_of(def_id); + let concrete_ty = generic_ty.subst(self.interner(), substs); self.depth += 1; let folded_ty = self.fold_ty(concrete_ty); self.depth -= 1; @@ -740,8 +740,8 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -846,8 +846,8 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -888,7 +888,7 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - self.tcx().mk_region(ty::ReLateBound(db, *replace_var)) + self.interner().mk_region(ty::ReLateBound(db, *replace_var)) } None => r1, } @@ -915,7 +915,7 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - self.tcx().mk_bound(db, *replace_var) + self.interner().mk_bound(db, *replace_var) } None => ty, } @@ -939,7 +939,7 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - self.tcx().mk_const(ty::ConstKind::Bound(db, *replace_var), ct.ty()) + self.interner().mk_const(ty::ConstKind::Bound(db, *replace_var), ct.ty()) } None => ct, } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 1b2533a5cf6..e7282a450f6 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -11,9 +11,9 @@ use crate::traits::{ObligationCause, PredicateObligation, Reveal}; use rustc_data_structures::sso::SsoHashMap; 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::fold::{ir::FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt}; use rustc_span::DUMMY_SP; use std::ops::ControlFlow; @@ -115,7 +115,7 @@ struct MaxEscapingBoundVarVisitor { escaping: usize, } -impl<'tcx> TypeVisitor<'tcx> for MaxEscapingBoundVarVisitor { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor { fn visit_binder<T: TypeVisitable<'tcx>>( &mut self, t: &ty::Binder<'tcx, T>, @@ -170,10 +170,10 @@ struct QueryNormalizer<'cx, 'tcx> { universes: Vec<Option<ty::UniverseIndex>>, } -impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { +impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> { type Error = NoSolution; - fn tcx<'c>(&'c self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -214,7 +214,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { Reveal::All => { let substs = substs.try_fold_with(self)?; - let recursion_limit = self.tcx().recursion_limit(); + let recursion_limit = self.interner().recursion_limit(); if !recursion_limit.value_within_limit(self.anon_depth) { // A closure or generator may have itself as in its upvars. // This should be checked handled by the recursion check for opaque @@ -228,8 +228,8 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { return ty.try_super_fold_with(self); } - let generic_ty = self.tcx().bound_type_of(def_id); - let concrete_ty = generic_ty.subst(self.tcx(), substs); + let generic_ty = self.interner().bound_type_of(def_id); + let concrete_ty = generic_ty.subst(self.interner(), substs); self.anon_depth += 1; if concrete_ty == ty { bug!( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45c4811321a..302adb79766 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -48,7 +48,7 @@ use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::SubstsRef; use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; -use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable}; use rustc_session::config::TraitSolver; use rustc_span::symbol::sym; diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 69b965f3a38..8402499b296 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -1,6 +1,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; +#[cfg(not(bootstrap))] +use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable}; use rustc_span::Span; use std::ops::ControlFlow; @@ -78,7 +80,7 @@ impl<'tcx> Search<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 7101f404269..20725c656de 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -769,8 +769,8 @@ struct ReplaceOpaqueTyFolder<'tcx> { binder_index: ty::DebruijnIndex, } -impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for ReplaceOpaqueTyFolder<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 4f71dcde818..2978fc4ed8c 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -35,8 +35,9 @@ use rustc_ast::ast; use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{ - self, Binder, Region, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, + ir::{TypeFolder, TypeVisitor}, + Binder, Region, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, }; use rustc_span::def_id::DefId; @@ -925,7 +926,7 @@ impl<'tcx> BoundVarsCollector<'tcx> { } } -impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for BoundVarsCollector<'tcx> { fn visit_binder<T: TypeVisitable<'tcx>>( &mut self, t: &Binder<'tcx, T>, @@ -1006,8 +1007,8 @@ impl<'a, 'tcx> NamedBoundVarSubstitutor<'a, 'tcx> { } } -impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1062,8 +1063,8 @@ impl<'tcx> ParamsSubstitutor<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1138,8 +1139,8 @@ impl<'tcx> ReverseParamsSubstitutor<'tcx> { } } -impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseParamsSubstitutor<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1174,7 +1175,7 @@ impl PlaceholdersCollector { } } -impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for PlaceholdersCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { match t.kind() { ty::Placeholder(p) if p.universe == self.universe_index => { diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index 5855a8e28dd..f33f9edd627 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -9,7 +9,7 @@ pub(crate) mod lowering; use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind}; use rustc_middle::traits::ChalkRustInterner; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; use rustc_infer::infer::canonical::{ Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse, diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs new file mode 100644 index 00000000000..ee4ef57c38f --- /dev/null +++ b/compiler/rustc_type_ir/src/fold.rs @@ -0,0 +1,239 @@ +//! 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<I: Interner>: TypeVisitable<I> { + /// 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<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error>; + + /// 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<F: TypeFolder<I>>(self, folder: &mut F) -> Self { + self.try_fold_with(folder).into_ok() + } +} + +// This trait is implemented for types of interest. +pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> { + /// 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<F: FallibleTypeFolder<I>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error>; + + /// 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<F: TypeFolder<I>>(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<I: Interner>: FallibleTypeFolder<I, Error = !> { + fn interner(&self) -> I; + + fn fold_binder<T>(&mut self, t: I::Binder<T>) -> I::Binder<T> + where + T: TypeFoldable<I>, + I::Binder<T>: TypeSuperFoldable<I>, + { + t.super_fold_with(self) + } + + fn fold_ty(&mut self, t: I::Ty) -> I::Ty + where + I::Ty: TypeSuperFoldable<I>, + { + t.super_fold_with(self) + } + + fn fold_region(&mut self, r: I::Region) -> I::Region + where + I::Region: TypeSuperFoldable<I>, + { + r.super_fold_with(self) + } + + fn fold_const(&mut self, c: I::Const) -> I::Const + where + I::Const: TypeSuperFoldable<I>, + { + c.super_fold_with(self) + } + + fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate + where + I::Predicate: TypeSuperFoldable<I>, + { + 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<I: Interner>: Sized { + type Error; + + fn interner(&self) -> I; + + fn try_fold_binder<T>(&mut self, t: I::Binder<T>) -> Result<I::Binder<T>, Self::Error> + where + T: TypeFoldable<I>, + I::Binder<T>: TypeSuperFoldable<I>, + { + t.try_super_fold_with(self) + } + + fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Self::Error> + where + I::Ty: TypeSuperFoldable<I>, + { + t.try_super_fold_with(self) + } + + fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, Self::Error> + where + I::Region: TypeSuperFoldable<I>, + { + r.try_super_fold_with(self) + } + + fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Self::Error> + where + I::Const: TypeSuperFoldable<I>, + { + c.try_super_fold_with(self) + } + + fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, Self::Error> + where + I::Predicate: TypeSuperFoldable<I>, + { + p.try_super_fold_with(self) + } +} + +// This blanket implementation of the fallible trait for infallible folders +// delegates to infallible methods to ensure coherence. +impl<I: Interner, F> FallibleTypeFolder<I> for F +where + F: TypeFolder<I>, +{ + type Error = !; + + fn interner(&self) -> I { + TypeFolder::interner(self) + } + + fn try_fold_binder<T>(&mut self, t: I::Binder<T>) -> Result<I::Binder<T>, !> + where + T: TypeFoldable<I>, + I::Binder<T>: TypeSuperFoldable<I>, + { + Ok(self.fold_binder(t)) + } + + fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, !> + where + I::Ty: TypeSuperFoldable<I>, + { + Ok(self.fold_ty(t)) + } + + fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, !> + where + I::Region: TypeSuperFoldable<I>, + { + Ok(self.fold_region(r)) + } + + fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, !> + where + I::Const: TypeSuperFoldable<I>, + { + Ok(self.fold_const(c)) + } + + fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, !> + where + I::Predicate: TypeSuperFoldable<I>, + { + Ok(self.fold_predicate(p)) + } +} diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 4aa958878d4..29d261fda8d 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,6 +1,10 @@ +#![feature(associated_type_defaults)] #![feature(fmt_helpers_for_derive)] +#![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)] @@ -18,8 +22,14 @@ use std::hash::Hash; use std::mem::discriminant; pub mod codec; +pub mod fold; pub mod sty; pub mod ty_info; +pub mod visit; + +#[macro_use] +mod macros; +mod structural_impls; pub use codec::*; pub use sty::*; @@ -28,13 +38,15 @@ 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 Binder<T>; 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 Predicate; 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 00000000000..6c181039730 --- /dev/null +++ b/compiler/rustc_type_ir/src/macros.rs @@ -0,0 +1,176 @@ +/// Used for types that are `Copy` and which **do not care arena +/// allocated data** (i.e., don't need to be folded). +macro_rules! TrivialTypeTraversalImpls { + ($($ty:ty,)+) => { + $( + impl<I: $crate::Interner> $crate::fold::TypeFoldable<I> for $ty { + fn try_fold_with<F: $crate::fold::FallibleTypeFolder<I>>( + self, + _: &mut F, + ) -> ::std::result::Result<Self, F::Error> { + Ok(self) + } + + #[inline] + fn fold_with<F: $crate::fold::TypeFolder<I>>( + self, + _: &mut F, + ) -> Self { + self + } + } + + impl<I: $crate::Interner> $crate::visit::TypeVisitable<I> for $ty { + #[inline] + fn visit_with<F: $crate::visit::TypeVisitor<I>>( + &self, + _: &mut F) + -> ::std::ops::ControlFlow<F::BreakTy> + { + ::std::ops::ControlFlow::Continue(()) + } + } + )+ + }; +} + +macro_rules! EnumTypeTraversalImpl { + (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { + $($variants:tt)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::fold::TypeFoldable<$tcx> for $s + $(where $($wc)*)* + { + fn try_fold_with<V: $crate::fold::FallibleTypeFolder<$tcx>>( + self, + folder: &mut V, + ) -> ::std::result::Result<Self, V::Error> { + EnumTypeTraversalImpl!(@FoldVariants(self, folder) input($($variants)*) output()) + } + } + }; + + (impl<$($p:tt),*> TypeVisitable<$tcx:tt> for $s:path { + $($variants:tt)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::visit::TypeVisitable<$tcx> for $s + $(where $($wc)*)* + { + fn visit_with<V: $crate::visit::TypeVisitor<$tcx>>( + &self, + visitor: &mut V, + ) -> ::std::ops::ControlFlow<V::BreakTy> { + 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)* + } + }; + + (@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::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::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_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs new file mode 100644 index 00000000000..b6abe9a7357 --- /dev/null +++ b/compiler/rustc_type_ir/src/structural_impls.rs @@ -0,0 +1,238 @@ +//! This module contains implementations of the `TypeFoldable` and `TypeVisitable` +//! 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}; +use crate::visit::{TypeVisitable, TypeVisitor}; +use crate::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; + +/////////////////////////////////////////////////////////////////////////// +// Atomic structs +// +// For things that don't carry any arena-allocated data (and are +// copy...), just add them to this list. + +TrivialTypeTraversalImpls! { + (), + bool, + usize, + u16, + u32, + u64, + String, + crate::DebruijnIndex, +} + +/////////////////////////////////////////////////////////////////////////// +// Traversal implementations. + +impl<I: Interner, T: TypeFoldable<I>, U: TypeFoldable<I>> TypeFoldable<I> for (T, U) { + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<(T, U), F::Error> { + Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?)) + } +} + +impl<I: Interner, T: TypeVisitable<I>, U: TypeVisitable<I>> TypeVisitable<I> for (T, U) { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + self.0.visit_with(visitor)?; + self.1.visit_with(visitor) + } +} + +impl<I: Interner, A: TypeFoldable<I>, B: TypeFoldable<I>, C: TypeFoldable<I>> TypeFoldable<I> + for (A, B, C) +{ + fn try_fold_with<F: FallibleTypeFolder<I>>( + 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<I: Interner, A: TypeVisitable<I>, B: TypeVisitable<I>, C: TypeVisitable<I>> TypeVisitable<I> + for (A, B, C) +{ + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + self.0.visit_with(visitor)?; + self.1.visit_with(visitor)?; + self.2.visit_with(visitor) + } +} + +EnumTypeTraversalImpl! { + impl<I, T> TypeFoldable<I> for Option<T> { + (Some)(a), + (None), + } where I: Interner, T: TypeFoldable<I> +} +EnumTypeTraversalImpl! { + impl<I, T> TypeVisitable<I> for Option<T> { + (Some)(a), + (None), + } where I: Interner, T: TypeVisitable<I> +} + +EnumTypeTraversalImpl! { + impl<I, T, E> TypeFoldable<I> for Result<T, E> { + (Ok)(a), + (Err)(a), + } where I: Interner, T: TypeFoldable<I>, E: TypeFoldable<I>, +} +EnumTypeTraversalImpl! { + impl<I, T, E> TypeVisitable<I> for Result<T, E> { + (Ok)(a), + (Err)(a), + } where I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>, +} + +impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Rc<T> { + fn try_fold_with<F: FallibleTypeFolder<I>>(mut self, folder: &mut F) -> Result<Self, F::Error> { + // 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<ManuallyDrop<T>>` so that + // panicking during `make_mut` does not leak the `T`. + Rc::make_mut(&mut self); + + // Casting to `Rc<ManuallyDrop<T>>` is safe because `ManuallyDrop` + // is `repr(transparent)`. + let ptr = Rc::into_raw(self).cast::<ManuallyDrop<T>>(); + 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<T>`. + Ok(Rc::from_raw(Rc::into_raw(unique).cast())) + } + } +} + +impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Rc<T> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + (**self).visit_with(visitor) + } +} + +impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Arc<T> { + fn try_fold_with<F: FallibleTypeFolder<I>>(mut self, folder: &mut F) -> Result<Self, F::Error> { + // 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<ManuallyDrop<T>>` so that + // panicking during `make_mut` does not leak the `T`. + Arc::make_mut(&mut self); + + // Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop` + // is `repr(transparent)`. + let ptr = Arc::into_raw(self).cast::<ManuallyDrop<T>>(); + 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<T>`. + Ok(Arc::from_raw(Arc::into_raw(unique).cast())) + } + } +} + +impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Arc<T> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + (**self).visit_with(visitor) + } +} + +impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Box<T> { + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + self.try_map_id(|value| value.try_fold_with(folder)) + } +} + +impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<T> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + (**self).visit_with(visitor) + } +} + +impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Vec<T> { + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + self.try_map_id(|t| t.try_fold_with(folder)) + } +} + +impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Vec<T> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for &[T] { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Box<[T]> { + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + self.try_map_id(|t| t.try_fold_with(folder)) + } +} + +impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<[T]> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix, T> { + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + self.try_map_id(|x| x.try_fold_with(folder)) + } +} + +impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix, T> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + 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 00000000000..62239fd2006 --- /dev/null +++ b/compiler/rustc_type_ir/src/visit.rs @@ -0,0 +1,115 @@ +//! 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::Interner; + +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<I: Interner>: 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<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>; +} + +pub trait TypeSuperVisitable<I: Interner>: TypeVisitable<I> { + /// 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<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>; +} + +/// 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<I: Interner>: Sized { + type BreakTy = !; + + fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy> + where + I::Binder<T>: TypeSuperVisitable<I>, + { + t.super_visit_with(self) + } + + fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> + where + I::Ty: TypeSuperVisitable<I>, + { + t.super_visit_with(self) + } + + fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> + where + I::Region: TypeSuperVisitable<I>, + { + r.super_visit_with(self) + } + + fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> + where + I::Const: TypeSuperVisitable<I>, + { + c.super_visit_with(self) + } + + fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> + where + I::Predicate: TypeSuperVisitable<I>, + { + p.super_visit_with(self) + } +} diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index f1a784b5fd2..d2c597664fa 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -1266,7 +1266,12 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> { // If the fallback fails for any reason we return the original error. match File::open(path, &opts) { Ok(file) => file.file_attr(), - Err(e) if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as _) => { + Err(e) + if [Some(c::ERROR_SHARING_VIOLATION as _), Some(c::ERROR_ACCESS_DENIED as _)] + .contains(&e.raw_os_error()) => + { + // `ERROR_ACCESS_DENIED` is returned when the user doesn't have permission for the resource. + // One such example is `System Volume Information` as default but can be created as well // `ERROR_SHARING_VIOLATION` will almost never be returned. // Usually if a file is locked you can still read some metadata. // However, there are special system files, such as diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 6c9c26faef6..615794958d0 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -193,10 +193,46 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let (tx, rx): (SyncSender<PathBuf>, _) = std::sync::mpsc::sync_channel(128); let walker = match paths.get(0) { Some(first) => { - let mut walker = WalkBuilder::new(first); + let find_shortcut_candidates = |p: &PathBuf| { + let mut candidates = Vec::new(); + for candidate in WalkBuilder::new(src.clone()).max_depth(Some(3)).build() { + if let Ok(entry) = candidate { + if let Some(dir_name) = p.file_name() { + if entry.path().is_dir() && entry.file_name() == dir_name { + candidates.push(entry.into_path()); + } + } + } + } + candidates + }; + + // Only try to look for shortcut candidates for single component paths like + // `std` and not for e.g. relative paths like `../library/std`. + let should_look_for_shortcut_dir = |p: &PathBuf| p.components().count() == 1; + + let mut walker = if should_look_for_shortcut_dir(first) { + if let [single_candidate] = &find_shortcut_candidates(first)[..] { + WalkBuilder::new(single_candidate) + } else { + WalkBuilder::new(first) + } + } else { + WalkBuilder::new(first) + }; + for path in &paths[1..] { - walker.add(path); + if should_look_for_shortcut_dir(path) { + if let [single_candidate] = &find_shortcut_candidates(path)[..] { + walker.add(single_candidate); + } else { + walker.add(path); + } + } else { + walker.add(path); + } } + walker } None => WalkBuilder::new(src.clone()), diff --git a/src/doc/book b/src/doc/book -Subproject f2a78f64b668f63f581203c6bac509903f7c00e +Subproject d94e03a18a2590ed3f1c67b859cb11528d2a2d5 diff --git a/src/doc/embedded-book b/src/doc/embedded-book -Subproject f1a4614aa41cc544b91b79760a709e113f3451d +Subproject 701d1551429da4cb609082c0ac99df569e33671 diff --git a/src/doc/nomicon b/src/doc/nomicon -Subproject bd1829d235296952bf72ca55635e360584b8805 +Subproject 79b53665a7c61d171fb8c5ad0b73b371f9ee6ba diff --git a/src/doc/reference b/src/doc/reference -Subproject 22882fb3f7b4d69fdc0d1731e8b9cfcb6910537 +Subproject e5adb99c04817b7fbe08f4ffce5b36702667345 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject 134376872e8c387ef369507e0ee9b5a0e327271 +Subproject efe23c4fe12e06351b8dc8c3d18312c76145510 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide -Subproject e359ee27fc3da3356d71a732128c0a1abe02e53 +Subproject 41a96ab971cb45e2a184df20619ad1829765c99 diff --git a/src/doc/style-guide/src/cargo.md b/src/doc/style-guide/src/cargo.md index f4993ba06a8..13b96ca8c5e 100644 --- a/src/doc/style-guide/src/cargo.md +++ b/src/doc/style-guide/src/cargo.md @@ -17,8 +17,7 @@ followed by the `description` at the end of that section. Don't use quotes around any standard key names; use bare keys. Only use quoted keys for non-standard keys whose names require them, and avoid introducing such key names when possible. See the [TOML -specification](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md#table) -for details. +specification](https://toml.io/en/v1.0.0#keys) for details. Put a single space both before and after the `=` between a key and value. Do not indent any key names; start all key names at the start of a line. diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index a302750aa1a..6c15eac2c19 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -734,8 +734,8 @@ struct RegionReplacer<'a, 'tcx> { tcx: TyCtxt<'tcx>, } -impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionReplacer<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 42bdbddbce6..bf3bbeb2dd1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -20,7 +20,7 @@ use rustc_hir::PredicateOrigin; use rustc_hir_analysis::hir_ty_to_ty; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_middle::middle::resolve_lifetime as rl; -use rustc_middle::ty::fold::TypeFolder; +use rustc_middle::ty::fold::ir::TypeFolder; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::TypeVisitable; use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Ty, TyCtxt}; 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 5836eb73bd9..e9dc7351b58 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::ir::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<TyCtxt<'_>> for ContainsRegion { type BreakTy = (); fn visit_region(&mut self, _: ty::Region<'_>) -> ControlFlow<Self::BreakTy> { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index c48d27b05f0..c785d89e280 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -17,7 +17,7 @@ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, DefIdTree, FnSig, IntTy, List, ParamEnv, Predicate, - PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, + PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, ir::TypeVisitor, UintTy, VariantDef, VariantDiscr, }; use rustc_middle::ty::{GenericArg, GenericArgKind}; @@ -838,7 +838,7 @@ pub fn for_each_top_level_late_bound_region<B>( index: u32, f: F, } - impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow<B>> TypeVisitor<'tcx> for V<F> { + impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow<B>> TypeVisitor<TyCtxt<'tcx>> for V<F> { type BreakTy = B; fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow<Self::BreakTy> { if let RegionKind::ReLateBound(idx, bound) = r.kind() && idx.as_u32() == self.index { diff --git a/tests/mir-opt/copy-prop/mutate_through_pointer.rs b/tests/mir-opt/copy-prop/mutate_through_pointer.rs index 609e49d6bc9..da142e33948 100644 --- a/tests/mir-opt/copy-prop/mutate_through_pointer.rs +++ b/tests/mir-opt/copy-prop/mutate_through_pointer.rs @@ -1,3 +1,13 @@ +// This attempts to mutate `a` via a pointer derived from `addr_of!(a)`. That is UB +// according to Miri. However, the decision to make this UB - and to allow +// rustc to rely on that fact for the purpose of optimizations - has not been +// finalized. +// +// As such, we include this test to ensure that copy prop does not rely on that +// fact. Specifically, if `addr_of!(a)` could not be used to modify a, it would +// be correct for CopyProp to replace all occurrences of `a` with `c` - but that +// would cause `f(true)` to output `false` instead of `true`. + #![feature(custom_mir, core_intrinsics)] #![allow(unused_assignments)] extern crate core; diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff index a91a755830d..004643e36f1 100644 --- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff @@ -32,7 +32,7 @@ _5 = _3; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11 _4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> bb1; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18 // mir::Constant - // + span: $DIR/sibling_ptr.rs:8:12: 8:15 + // + span: $DIR/sibling_ptr.rs:15:12: 15:15 // + literal: Const { ty: unsafe fn(*mut u8, usize) -> *mut u8 {ptr::mut_ptr::<impl *mut u8>::add}, val: Value(<ZST>) } } diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs index 87ef00d1829..6dfb3a4ed30 100644 --- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs +++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs @@ -1,3 +1,10 @@ +// This attempts to modify `x.1` via a pointer derived from `addr_of_mut!(x.0)`. +// According to Miri, that is UB. However, T-opsem has not finalized that +// decision and as such we cannot rely on it in optimizations. Consequently, +// DataflowConstProp must treat the `addr_of_mut!(x.0)` as potentially being +// used to modify `x.1` - if it did not, then it might incorrectly assume that it +// can infer the value of `x.1` at the end of this function. + // unit-test: DataflowConstProp // EMIT_MIR sibling_ptr.main.DataflowConstProp.diff @@ -7,5 +14,5 @@ fn main() { let p = std::ptr::addr_of_mut!(x.0); *p.add(1) = 1; } - let x1 = x.1; // should not be propagated + let x1 = x.1; // should not be propagated } diff --git a/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff index ea7f5007224..fd691fdd153 100644 --- a/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff @@ -3,42 +3,42 @@ fn escaping() -> () { let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19 - let _1: (); // in scope 0 at $DIR/sroa.rs:+2:5: +2:42 - let mut _2: *const u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41 - let _3: &u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41 - let _4: Escaping; // in scope 0 at $DIR/sroa.rs:+2:8: +2:39 - let mut _5: u32; // in scope 0 at $DIR/sroa.rs:+2:34: +2:37 + let _1: (); // in scope 0 at $DIR/sroa.rs:+1:5: +1:42 + let mut _2: *const u32; // in scope 0 at $DIR/sroa.rs:+1:7: +1:41 + let _3: &u32; // in scope 0 at $DIR/sroa.rs:+1:7: +1:41 + let _4: Escaping; // in scope 0 at $DIR/sroa.rs:+1:8: +1:39 + let mut _5: u32; // in scope 0 at $DIR/sroa.rs:+1:34: +1:37 bb0: { - StorageLive(_1); // scope 0 at $DIR/sroa.rs:+2:5: +2:42 - StorageLive(_2); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 - StorageLive(_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 - StorageLive(_4); // scope 0 at $DIR/sroa.rs:+2:8: +2:39 - StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:34: +2:37 - _5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+2:34: +2:37 + StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:5: +1:42 + StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:7: +1:41 + StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:41 + StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:8: +1:39 + StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:34: +1:37 + _5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+1:34: +1:37 // mir::Constant - // + span: $DIR/sroa.rs:73:34: 73:35 + // + span: $DIR/sroa.rs:78:34: 78:35 // + literal: Const { ty: fn() -> u32 {g}, val: Value(<ZST>) } } bb1: { - _4 = Escaping { a: const 1_u32, b: const 2_u32, c: move _5 }; // scope 0 at $DIR/sroa.rs:+2:8: +2:39 - StorageDead(_5); // scope 0 at $DIR/sroa.rs:+2:38: +2:39 - _3 = &(_4.0: u32); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 - _2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41 - _1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+2:5: +2:42 + _4 = Escaping { a: const 1_u32, b: const 2_u32, c: move _5 }; // scope 0 at $DIR/sroa.rs:+1:8: +1:39 + StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:38: +1:39 + _3 = &(_4.0: u32); // scope 0 at $DIR/sroa.rs:+1:7: +1:41 + _2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:41 + _1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+1:5: +1:42 // mir::Constant - // + span: $DIR/sroa.rs:73:5: 73:6 + // + span: $DIR/sroa.rs:78:5: 78:6 // + literal: Const { ty: fn(*const u32) {f}, val: Value(<ZST>) } } bb2: { - StorageDead(_2); // scope 0 at $DIR/sroa.rs:+2:41: +2:42 - StorageDead(_4); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 - StorageDead(_3); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 - StorageDead(_1); // scope 0 at $DIR/sroa.rs:+2:42: +2:43 - _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +3:2 - return; // scope 0 at $DIR/sroa.rs:+3:2: +3:2 + StorageDead(_2); // scope 0 at $DIR/sroa.rs:+1:41: +1:42 + StorageDead(_4); // scope 0 at $DIR/sroa.rs:+1:42: +1:43 + StorageDead(_3); // scope 0 at $DIR/sroa.rs:+1:42: +1:43 + StorageDead(_1); // scope 0 at $DIR/sroa.rs:+1:42: +1:43 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +2:2 + return; // scope 0 at $DIR/sroa.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs index b69de2e124e..fff92cf8d9f 100644 --- a/tests/mir-opt/sroa.rs +++ b/tests/mir-opt/sroa.rs @@ -68,8 +68,13 @@ fn f(a: *const u32) { println!("{}", unsafe { *a.add(2) }); } +// `f` uses the `&e.a` to access `e.c`. This is UB according to Miri today; however, +// T-opsem has not finalized that decision and as such rustc should not rely on +// it. If SROA were to rely on it, it would be (almost) correct to turn `e` into +// three distinct locals - one for each field - and pass a reference to only one +// of them to `f`. However, this would lead to a miscompilation because `b` and `c` +// might no longer appear right after `a` in memory. pub fn escaping() { - // Verify this struct is not flattened. f(&Escaping { a: 1, b: 2, c: g() }.a); } diff --git a/tests/ui/async-await/dont-suggest-missing-await.stderr b/tests/ui/async-await/dont-suggest-missing-await.stderr index 8e2d42c8f13..1fa4e5db0cb 100644 --- a/tests/ui/async-await/dont-suggest-missing-await.stderr +++ b/tests/ui/async-await/dont-suggest-missing-await.stderr @@ -2,12 +2,15 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | LL | take_u32(x) - | -------- ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found future | | | arguments to this function are incorrect | - = note: expected type `u32` - found opaque type `impl Future<Output = u32>` +note: calling an async function returns a future + --> $DIR/dont-suggest-missing-await.rs:14:18 + | +LL | take_u32(x) + | ^ note: function defined here --> $DIR/dont-suggest-missing-await.rs:5:4 | diff --git a/tests/ui/async-await/generator-desc.stderr b/tests/ui/async-await/generator-desc.stderr index 9fdb1ce47d7..51ac9d86bfb 100644 --- a/tests/ui/async-await/generator-desc.stderr +++ b/tests/ui/async-await/generator-desc.stderr @@ -17,12 +17,10 @@ error[E0308]: mismatched types --> $DIR/generator-desc.rs:12:16 | LL | fun(one(), two()); - | --- ^^^^^ expected opaque type, found a different opaque type + | --- ^^^^^ expected future, found a different future | | | arguments to this function are incorrect | - = note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:5:16>) - found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:6:16>) = help: consider `await`ing on both `Future`s = note: distinct uses of `impl Trait` result in different opaque types note: function defined here diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 3c01fca2f4d..168ef8e9ee4 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -2,7 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/async-example-desugared-boxed-in-trait.rs:15:28 | LL | async fn foo(&self) -> i32 { - | ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found opaque type + | ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future | note: type in trait --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22 diff --git a/tests/ui/async-await/issue-61076.rs b/tests/ui/async-await/issue-61076.rs index 9c4acbe0a5b..cf6e5b4e436 100644 --- a/tests/ui/async-await/issue-61076.rs +++ b/tests/ui/async-await/issue-61076.rs @@ -86,7 +86,7 @@ async fn match_() { match tuple() { //~ HELP consider `await`ing on the `Future` //~^ NOTE this expression has type `impl Future<Output = Tuple>` Tuple(_) => {} //~ ERROR mismatched types - //~^ NOTE expected opaque type, found `Tuple` + //~^ NOTE expected future, found `Tuple` //~| NOTE expected opaque type `impl Future<Output = Tuple>` } } diff --git a/tests/ui/async-await/issue-61076.stderr b/tests/ui/async-await/issue-61076.stderr index b25b29bf50c..44de282988b 100644 --- a/tests/ui/async-await/issue-61076.stderr +++ b/tests/ui/async-await/issue-61076.stderr @@ -62,7 +62,7 @@ LL | match tuple() { | ------- this expression has type `impl Future<Output = Tuple>` LL | LL | Tuple(_) => {} - | ^^^^^^^^ expected opaque type, found `Tuple` + | ^^^^^^^^ expected future, found `Tuple` | = note: expected opaque type `impl Future<Output = Tuple>` found struct `Tuple` diff --git a/tests/ui/async-await/issue-98634.stderr b/tests/ui/async-await/issue-98634.stderr index 4c5dfeed9ba..5b7f18a98b5 100644 --- a/tests/ui/async-await/issue-98634.stderr +++ b/tests/ui/async-await/issue-98634.stderr @@ -2,10 +2,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Futu --> $DIR/issue-98634.rs:45:23 | LL | StructAsync { callback }.await; - | ^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found opaque type + | ^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future | - = note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>` - found opaque type `impl Future<Output = ()>` note: required by a bound in `StructAsync` --> $DIR/issue-98634.rs:9:35 | @@ -16,10 +14,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Futu --> $DIR/issue-98634.rs:45:9 | LL | StructAsync { callback }.await; - | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found opaque type + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future | - = note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>` - found opaque type `impl Future<Output = ()>` note: required by a bound in `StructAsync` --> $DIR/issue-98634.rs:9:35 | @@ -30,10 +26,8 @@ error[E0271]: expected `callback` to be a fn item that returns `Pin<Box<dyn Futu --> $DIR/issue-98634.rs:45:33 | LL | StructAsync { callback }.await; - | ^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found opaque type + | ^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future | - = note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>` - found opaque type `impl Future<Output = ()>` note: required by a bound in `StructAsync` --> $DIR/issue-98634.rs:9:35 | diff --git a/tests/ui/async-await/issues/issue-102206.stderr b/tests/ui/async-await/issues/issue-102206.stderr index ebb80f6e07e..750b7a886ef 100644 --- a/tests/ui/async-await/issues/issue-102206.stderr +++ b/tests/ui/async-await/issues/issue-102206.stderr @@ -4,12 +4,10 @@ error[E0308]: mismatched types LL | std::mem::size_of_val(foo()); | --------------------- ^^^^^ | | | - | | expected `&_`, found opaque type + | | expected `&_`, found future | | help: consider borrowing here: `&foo()` | arguments to this function are incorrect | - = note: expected reference `&_` - found opaque type `impl Future<Output = ()>` note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL diff --git a/tests/ui/async-await/suggest-missing-await-closure.stderr b/tests/ui/async-await/suggest-missing-await-closure.stderr index e47325cb4ae..d44af5b8dd8 100644 --- a/tests/ui/async-await/suggest-missing-await-closure.stderr +++ b/tests/ui/async-await/suggest-missing-await-closure.stderr @@ -2,12 +2,15 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | LL | take_u32(x) - | -------- ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found future | | | arguments to this function are incorrect | - = note: expected type `u32` - found opaque type `impl Future<Output = u32>` +note: calling an async function returns a future + --> $DIR/suggest-missing-await-closure.rs:16:18 + | +LL | take_u32(x) + | ^ note: function defined here --> $DIR/suggest-missing-await-closure.rs:6:4 | diff --git a/tests/ui/async-await/suggest-missing-await.stderr b/tests/ui/async-await/suggest-missing-await.stderr index 4ed0272ac1a..f0ec34a6a55 100644 --- a/tests/ui/async-await/suggest-missing-await.stderr +++ b/tests/ui/async-await/suggest-missing-await.stderr @@ -2,12 +2,15 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:12:14 | LL | take_u32(x) - | -------- ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found future | | | arguments to this function are incorrect | - = note: expected type `u32` - found opaque type `impl Future<Output = u32>` +note: calling an async function returns a future + --> $DIR/suggest-missing-await.rs:12:14 + | +LL | take_u32(x) + | ^ note: function defined here --> $DIR/suggest-missing-await.rs:3:4 | @@ -22,10 +25,13 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:22:5 | LL | dummy() - | ^^^^^^^ expected `()`, found opaque type + | ^^^^^^^ expected `()`, found future | - = note: expected unit type `()` - found opaque type `impl Future<Output = ()>` +note: calling an async function returns a future + --> $DIR/suggest-missing-await.rs:22:5 + | +LL | dummy() + | ^^^^^^^ help: consider `await`ing on the `Future` | LL | dummy().await @@ -45,7 +51,7 @@ LL | | dummy() LL | | LL | | } else { LL | | dummy().await - | | ^^^^^^^^^^^^^ expected opaque type, found `()` + | | ^^^^^^^^^^^^^ expected future, found `()` LL | | LL | | }; | |_____- `if` and `else` have incompatible types @@ -67,7 +73,7 @@ LL | | 0 => dummy(), LL | | 1 => dummy(), | | ------- this is found to be of type `impl Future<Output = ()>` LL | | 2 => dummy().await, - | | ^^^^^^^^^^^^^ expected opaque type, found `()` + | | ^^^^^^^^^^^^^ expected future, found `()` LL | | LL | | }; | |_____- `match` arms have incompatible types @@ -86,7 +92,7 @@ error[E0308]: mismatched types LL | let _x = match dummy() { | ------- this expression has type `impl Future<Output = ()>` LL | () => {} - | ^^ expected opaque type, found `()` + | ^^ expected future, found `()` | = note: expected opaque type `impl Future<Output = ()>` found unit type `()` @@ -102,7 +108,7 @@ LL | match dummy_result() { | -------------- this expression has type `impl Future<Output = Result<(), ()>>` ... LL | Ok(_) => {} - | ^^^^^ expected opaque type, found `Result<_, _>` + | ^^^^^ expected future, found `Result<_, _>` | = note: expected opaque type `impl Future<Output = Result<(), ()>>` found enum `Result<_, _>` @@ -118,7 +124,7 @@ LL | match dummy_result() { | -------------- this expression has type `impl Future<Output = Result<(), ()>>` ... LL | Err(_) => {} - | ^^^^^^ expected opaque type, found `Result<_, _>` + | ^^^^^^ expected future, found `Result<_, _>` | = note: expected opaque type `impl Future<Output = Result<(), ()>>` found enum `Result<_, _>` diff --git a/tests/ui/coherence/issue-85026.stderr b/tests/ui/coherence/issue-85026.stderr index a5da19bbfaa..fb6e9976583 100644 --- a/tests/ui/coherence/issue-85026.stderr +++ b/tests/ui/coherence/issue-85026.stderr @@ -1,16 +1,16 @@ error[E0785]: cannot define inherent `impl` for a dyn auto trait - --> $DIR/issue-85026.rs:5:6 + --> $DIR/issue-85026.rs:5:1 | LL | impl dyn AutoTrait {} - | ^^^^^^^^^^^^^ impl requires at least one non-auto trait + | ^^^^^^^^^^^^^^^^^^ impl requires at least one non-auto trait | = note: define and implement a new trait or type instead error[E0785]: cannot define inherent `impl` for a dyn auto trait - --> $DIR/issue-85026.rs:8:6 + --> $DIR/issue-85026.rs:8:1 | LL | impl dyn Unpin {} - | ^^^^^^^^^ impl requires at least one non-auto trait + | ^^^^^^^^^^^^^^ impl requires at least one non-auto trait | = note: define and implement a new trait or type instead diff --git a/tests/ui/const-generics/wrong-normalization.stderr b/tests/ui/const-generics/wrong-normalization.stderr index fb806bdb1e7..658a8406608 100644 --- a/tests/ui/const-generics/wrong-normalization.stderr +++ b/tests/ui/const-generics/wrong-normalization.stderr @@ -1,8 +1,8 @@ error[E0118]: no nominal type found for inherent implementation - --> $DIR/wrong-normalization.rs:16:6 + --> $DIR/wrong-normalization.rs:16:1 | LL | impl <I8<{i8::MIN}> as Identity>::Identity { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead diff --git a/tests/ui/error-codes/E0116.stderr b/tests/ui/error-codes/E0116.stderr index a5ceeb4a55d..8a027686760 100644 --- a/tests/ui/error-codes/E0116.stderr +++ b/tests/ui/error-codes/E0116.stderr @@ -2,7 +2,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/E0116.rs:1:1 | LL | impl Vec<u8> {} - | ^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead diff --git a/tests/ui/error-codes/E0118.stderr b/tests/ui/error-codes/E0118.stderr index 8c6fa7947a8..442f8a4f870 100644 --- a/tests/ui/error-codes/E0118.stderr +++ b/tests/ui/error-codes/E0118.stderr @@ -1,8 +1,8 @@ error[E0118]: no nominal type found for inherent implementation - --> $DIR/E0118.rs:1:9 + --> $DIR/E0118.rs:1:1 | LL | impl<T> T { - | ^ impl requires a nominal type + | ^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead diff --git a/tests/ui/error-codes/E0390.stderr b/tests/ui/error-codes/E0390.stderr index 0e5a9ca762b..ec4b5758c5b 100644 --- a/tests/ui/error-codes/E0390.stderr +++ b/tests/ui/error-codes/E0390.stderr @@ -1,16 +1,16 @@ error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/E0390.rs:5:6 + --> $DIR/E0390.rs:5:1 | LL | impl *mut Foo {} - | ^^^^^^^^ + | ^^^^^^^^^^^^^ | = help: consider using an extension trait instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/E0390.rs:7:6 + --> $DIR/E0390.rs:7:1 | LL | impl fn(Foo) {} - | ^^^^^^^ + | ^^^^^^^^^^^^ | = help: consider using an extension trait instead diff --git a/tests/ui/impl-trait/issue-102605.stderr b/tests/ui/impl-trait/issue-102605.stderr index 8ff08968008..dfe18e43eee 100644 --- a/tests/ui/impl-trait/issue-102605.stderr +++ b/tests/ui/impl-trait/issue-102605.stderr @@ -2,12 +2,15 @@ error[E0308]: mismatched types --> $DIR/issue-102605.rs:13:20 | LL | convert_result(foo()) - | -------------- ^^^^^ expected `Result<(), _>`, found opaque type + | -------------- ^^^^^ expected `Result<(), _>`, found future | | | arguments to this function are incorrect | - = note: expected enum `Result<(), _>` - found opaque type `impl Future<Output = Result<(), String>>` +note: calling an async function returns a future + --> $DIR/issue-102605.rs:13:20 + | +LL | convert_result(foo()) + | ^^^^^ note: function defined here --> $DIR/issue-102605.rs:7:4 | diff --git a/tests/ui/impl-trait/issue-99914.stderr b/tests/ui/impl-trait/issue-99914.stderr index a4b7fc1f5bc..c86e9eadc87 100644 --- a/tests/ui/impl-trait/issue-99914.stderr +++ b/tests/ui/impl-trait/issue-99914.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-99914.rs:9:27 | LL | t.and_then(|t| -> _ { bar(t) }); - | ^^^^^^ expected `Result<_, Error>`, found opaque type + | ^^^^^^ expected `Result<_, Error>`, found future | - = note: expected enum `Result<_, Error>` - found opaque type `impl Future<Output = ()>` help: try wrapping the expression in `Ok` | LL | t.and_then(|t| -> _ { Ok(bar(t)) }); diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index b9fc8726ffc..99eed29207b 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -1,4 +1,4 @@ -error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:198:90: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead +error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:201:90: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead query stack during panic: #0 [eval_to_allocation_raw] const-evaluating + checking `BAR` diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 3ad0a9f9d5c..e3a9caa6460 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -303,10 +303,10 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887> error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:233:23 + --> $DIR/where-allowed.rs:233:1 | LL | impl <T = impl Debug> T {} - | ^ impl requires a nominal type + | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead diff --git a/tests/ui/incoherent-inherent-impls/needs-has-incoherent-impls.stderr b/tests/ui/incoherent-inherent-impls/needs-has-incoherent-impls.stderr index 8f70825115d..f5900afe2dc 100644 --- a/tests/ui/incoherent-inherent-impls/needs-has-incoherent-impls.stderr +++ b/tests/ui/incoherent-inherent-impls/needs-has-incoherent-impls.stderr @@ -1,114 +1,80 @@ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:5:1 | -LL | / impl extern_crate::StructWithAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::StructWithAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:7:5 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:13:1 | -LL | / impl extern_crate::StructNoAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::StructNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:13:1 | -LL | / impl extern_crate::StructNoAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::StructNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:17:1 | -LL | / impl extern_crate::StructNoAttr { -LL | | -LL | | #[rustc_allow_incoherent_impl] -LL | | fn bar() {} -LL | | } - | |_^ +LL | impl extern_crate::StructNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:17:1 | -LL | / impl extern_crate::StructNoAttr { -LL | | -LL | | #[rustc_allow_incoherent_impl] -LL | | fn bar() {} -LL | | } - | |_^ +LL | impl extern_crate::StructNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:22:1 | -LL | / impl extern_crate::EnumWithAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumWithAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:24:5 | LL | fn foo() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:30:1 | -LL | / impl extern_crate::EnumNoAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:30:1 | -LL | / impl extern_crate::EnumNoAttr { -LL | | -LL | | fn foo() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0390]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/needs-has-incoherent-impls.rs:34:1 | -LL | / impl extern_crate::EnumNoAttr { -LL | | -LL | | #[rustc_allow_incoherent_impl] -LL | | fn bar() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider moving this inherent impl into the crate defining the type if possible help: alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items --> $DIR/needs-has-incoherent-impls.rs:34:1 | -LL | / impl extern_crate::EnumNoAttr { -LL | | -LL | | #[rustc_allow_incoherent_impl] -LL | | fn bar() {} -LL | | } - | |_^ +LL | impl extern_crate::EnumNoAttr { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr b/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr index b3f8b51d0ea..6dc1680cf89 100644 --- a/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr +++ b/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr @@ -2,7 +2,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/no-attr-empty-impl.rs:4:1 | LL | impl extern_crate::StructWithAttr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead @@ -10,7 +10,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/no-attr-empty-impl.rs:7:1 | LL | impl extern_crate::StructNoAttr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead @@ -18,7 +18,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/no-attr-empty-impl.rs:10:1 | LL | impl extern_crate::EnumWithAttr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead @@ -26,15 +26,15 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher --> $DIR/no-attr-empty-impl.rs:13:1 | LL | impl extern_crate::EnumNoAttr {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/no-attr-empty-impl.rs:16:6 + --> $DIR/no-attr-empty-impl.rs:16:1 | LL | impl f32 {} - | ^^^ + | ^^^^^^^^ | = help: consider using an extension trait instead diff --git a/tests/ui/kinds-of-primitive-impl.stderr b/tests/ui/kinds-of-primitive-impl.stderr index f4dbd1c40e8..21aac58f1f2 100644 --- a/tests/ui/kinds-of-primitive-impl.stderr +++ b/tests/ui/kinds-of-primitive-impl.stderr @@ -1,32 +1,32 @@ error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:1:6 + --> $DIR/kinds-of-primitive-impl.rs:1:1 | LL | impl u8 { - | ^^ + | ^^^^^^^ | = help: consider using an extension trait instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:6:6 + --> $DIR/kinds-of-primitive-impl.rs:6:1 | LL | impl str { - | ^^^ + | ^^^^^^^^ | = help: consider using an extension trait instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:12:6 + --> $DIR/kinds-of-primitive-impl.rs:12:1 | LL | impl char { - | ^^^^ + | ^^^^^^^^^ | = help: consider using an extension trait instead error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:21:6 + --> $DIR/kinds-of-primitive-impl.rs:21:1 | LL | impl &MyType { - | ^^^^^^^ + | ^^^^^^^^^^^^ | = help: consider using an extension trait instead = note: you could also try moving the reference to uses of `MyType` (such as `self`) within the implementation diff --git a/tests/ui/privacy/private-in-public-ill-formed.stderr b/tests/ui/privacy/private-in-public-ill-formed.stderr index e7c94bc301b..abc8538e5b3 100644 --- a/tests/ui/privacy/private-in-public-ill-formed.stderr +++ b/tests/ui/privacy/private-in-public-ill-formed.stderr @@ -1,16 +1,16 @@ error[E0118]: no nominal type found for inherent implementation - --> $DIR/private-in-public-ill-formed.rs:14:10 + --> $DIR/private-in-public-ill-formed.rs:14:5 | LL | impl <Priv as PrivTr>::AssocAlias { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead error[E0118]: no nominal type found for inherent implementation - --> $DIR/private-in-public-ill-formed.rs:31:10 + --> $DIR/private-in-public-ill-formed.rs:31:5 | LL | impl <Priv as PrivTr>::AssocAlias { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead diff --git a/tests/ui/suggestions/if-then-neeing-semi.rs b/tests/ui/suggestions/if-then-neeing-semi.rs index 7be4312bfba..a4eefb41508 100644 --- a/tests/ui/suggestions/if-then-neeing-semi.rs +++ b/tests/ui/suggestions/if-then-neeing-semi.rs @@ -26,8 +26,8 @@ async fn async_extra_semicolon_same() { //~^ HELP consider removing this semicolon } else { async_dummy() //~ ERROR `if` and `else` have incompatible types - //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~^ NOTE expected `()`, found future + //~| NOTE calling an async function returns a future //~| HELP consider `await`ing on the `Future` }; } @@ -39,8 +39,8 @@ async fn async_extra_semicolon_different() { //~^ HELP consider removing this semicolon } else { async_dummy2() //~ ERROR `if` and `else` have incompatible types - //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~^ NOTE expected `()`, found future + //~| NOTE calling an async function returns a future //~| HELP consider `await`ing on the `Future` }; } @@ -52,8 +52,7 @@ async fn async_different_futures() { //~| HELP consider `await`ing on both `Future`s } else { async_dummy2() //~ ERROR `if` and `else` have incompatible types - //~^ NOTE expected opaque type, found a different opaque type - //~| NOTE expected opaque type `impl Future<Output = ()>` + //~^ NOTE expected future, found a different future //~| NOTE distinct uses of `impl Trait` result in different opaque types }; } diff --git a/tests/ui/suggestions/if-then-neeing-semi.stderr b/tests/ui/suggestions/if-then-neeing-semi.stderr index 567deb405fc..6833e0bab2b 100644 --- a/tests/ui/suggestions/if-then-neeing-semi.stderr +++ b/tests/ui/suggestions/if-then-neeing-semi.stderr @@ -9,14 +9,17 @@ LL | | async_dummy(); LL | | LL | | } else { LL | | async_dummy() - | | ^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^ expected `()`, found future ... | LL | | LL | | }; | |_____- `if` and `else` have incompatible types | - = note: expected unit type `()` - found opaque type `impl Future<Output = ()>` +note: calling an async function returns a future + --> $DIR/if-then-neeing-semi.rs:28:9 + | +LL | async_dummy() + | ^^^^^^^^^^^^^ help: consider `await`ing on the `Future` | LL | async_dummy().await @@ -38,14 +41,17 @@ LL | | async_dummy(); LL | | LL | | } else { LL | | async_dummy2() - | | ^^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^^ expected `()`, found future ... | LL | | LL | | }; | |_____- `if` and `else` have incompatible types | - = note: expected unit type `()` - found opaque type `impl Future<Output = ()>` +note: calling an async function returns a future + --> $DIR/if-then-neeing-semi.rs:41:9 + | +LL | async_dummy2() + | ^^^^^^^^^^^^^^ help: consider `await`ing on the `Future` | LL | async_dummy2().await @@ -69,14 +75,12 @@ LL | | async_dummy() LL | | LL | | } else { LL | | async_dummy2() - | | ^^^^^^^^^^^^^^ expected opaque type, found a different opaque type -... | + | | ^^^^^^^^^^^^^^ expected future, found a different future +LL | | LL | | LL | | }; | |_____- `if` and `else` have incompatible types | - = note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/if-then-neeing-semi.rs:18:24>) - found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/if-then-neeing-semi.rs:20:25>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/tests/ui/suggestions/issue-81839.stderr b/tests/ui/suggestions/issue-81839.stderr index 4af7cc9f8ec..6d0a0c7b3fa 100644 --- a/tests/ui/suggestions/issue-81839.stderr +++ b/tests/ui/suggestions/issue-81839.stderr @@ -10,12 +10,9 @@ LL | | cx.answer_str("hi"); | | this is found to be of type `()` LL | | } LL | | _ => cx.answer_str("hi"), - | | ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^^^^^^^ expected `()`, found future LL | | } | |_____- `match` arms have incompatible types - | - = note: expected unit type `()` - found opaque type `impl Future<Output = Test>` error: aborting due to previous error diff --git a/tests/ui/suggestions/match-prev-arm-needing-semi.rs b/tests/ui/suggestions/match-prev-arm-needing-semi.rs index 3f863cb104e..11463c453d4 100644 --- a/tests/ui/suggestions/match-prev-arm-needing-semi.rs +++ b/tests/ui/suggestions/match-prev-arm-needing-semi.rs @@ -24,8 +24,8 @@ async fn async_extra_semicolon_same() { //~^ HELP consider removing this semicolon } false => async_dummy(), //~ ERROR `match` arms have incompatible types - //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~^ NOTE expected `()`, found future + //~| NOTE calling an async function returns a future //~| HELP consider `await`ing on the `Future` }; } @@ -37,8 +37,8 @@ async fn async_extra_semicolon_different() { //~^ HELP consider removing this semicolon } false => async_dummy2(), //~ ERROR `match` arms have incompatible types - //~^ NOTE expected `()`, found opaque type - //~| NOTE expected unit type `()` + //~^ NOTE expected `()`, found future + //~| NOTE calling an async function returns a future //~| HELP consider `await`ing on the `Future` }; } @@ -48,8 +48,7 @@ async fn async_different_futures() { true => async_dummy(), //~ NOTE this is found to be //~| HELP consider `await`ing on both `Future`s false => async_dummy2(), //~ ERROR `match` arms have incompatible types - //~^ NOTE expected opaque type, found a different opaque type - //~| NOTE expected opaque type `impl Future<Output = ()>` + //~^ NOTE expected future, found a different future //~| NOTE distinct uses of `impl Trait` result in different opaque types }; } diff --git a/tests/ui/suggestions/match-prev-arm-needing-semi.stderr b/tests/ui/suggestions/match-prev-arm-needing-semi.stderr index df18c7b0b23..cf3cf45ef40 100644 --- a/tests/ui/suggestions/match-prev-arm-needing-semi.stderr +++ b/tests/ui/suggestions/match-prev-arm-needing-semi.stderr @@ -9,14 +9,17 @@ LL | | async_dummy(); LL | | LL | | } LL | | false => async_dummy(), - | | ^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^ expected `()`, found future ... | LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: expected unit type `()` - found opaque type `impl Future<Output = ()>` +note: calling an async function returns a future + --> $DIR/match-prev-arm-needing-semi.rs:26:18 + | +LL | false => async_dummy(), + | ^^^^^^^^^^^^^ help: consider `await`ing on the `Future` | LL | false => async_dummy().await, @@ -38,14 +41,17 @@ LL | | async_dummy(); LL | | LL | | } LL | | false => async_dummy2(), - | | ^^^^^^^^^^^^^^ expected `()`, found opaque type + | | ^^^^^^^^^^^^^^ expected `()`, found future ... | LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: expected unit type `()` - found opaque type `impl Future<Output = ()>` +note: calling an async function returns a future + --> $DIR/match-prev-arm-needing-semi.rs:39:18 + | +LL | false => async_dummy2(), + | ^^^^^^^^^^^^^^ help: consider `await`ing on the `Future` | LL | false => async_dummy2().await, @@ -67,14 +73,12 @@ LL | | true => async_dummy(), | | ------------- this is found to be of type `impl Future<Output = ()>` LL | | LL | | false => async_dummy2(), - | | ^^^^^^^^^^^^^^ expected opaque type, found a different opaque type -... | + | | ^^^^^^^^^^^^^^ expected future, found a different future +LL | | LL | | LL | | }; | |_____- `match` arms have incompatible types | - = note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>) - found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:18:25>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/tests/ui/suggestions/opaque-type-error.stderr b/tests/ui/suggestions/opaque-type-error.stderr index 133ffb05873..5c90d3012ab 100644 --- a/tests/ui/suggestions/opaque-type-error.stderr +++ b/tests/ui/suggestions/opaque-type-error.stderr @@ -2,22 +2,20 @@ error[E0308]: `if` and `else` have incompatible types --> $DIR/opaque-type-error.rs:20:9 | LL | fn thing_one() -> impl Future<Output = Result<(), ()>> { - | ------------------------------------ the expected opaque type + | ------------------------------------ the expected future ... LL | fn thing_two() -> impl Future<Output = Result<(), ()>> { - | ------------------------------------ the found opaque type + | ------------------------------------ the found future ... LL | / if true { LL | | thing_one() | | ----------- expected because of this LL | | } else { LL | | thing_two() - | | ^^^^^^^^^^^ expected opaque type, found a different opaque type + | | ^^^^^^^^^^^ expected future, found a different future LL | | }.await | |_____- `if` and `else` have incompatible types | - = note: expected opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:8:19>) - found opaque type `impl Future<Output = Result<(), ()>>` (opaque type at <$DIR/opaque-type-error.rs:12:19>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/tests/ui/traits/trait-or-new-type-instead.stderr b/tests/ui/traits/trait-or-new-type-instead.stderr index 4726b0668e5..6fd8a03fd8f 100644 --- a/tests/ui/traits/trait-or-new-type-instead.stderr +++ b/tests/ui/traits/trait-or-new-type-instead.stderr @@ -1,11 +1,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/trait-or-new-type-instead.rs:1:1 | -LL | / impl<T> Option<T> { -LL | | -LL | | pub fn foo(&self) { } -LL | | } - | |_^ impl for type defined outside of crate. +LL | impl<T> Option<T> { + | ^^^^^^^^^^^^^^^^^ impl for type defined outside of crate. | = note: define and implement a trait or new type instead diff --git a/tests/ui/type-alias-impl-trait/issue-98604.stderr b/tests/ui/type-alias-impl-trait/issue-98604.stderr index bb9dd2365ea..fa16d321890 100644 --- a/tests/ui/type-alias-impl-trait/issue-98604.stderr +++ b/tests/ui/type-alias-impl-trait/issue-98604.stderr @@ -2,10 +2,8 @@ error[E0271]: expected `test` to be a fn item that returns `Pin<Box<dyn Future<O --> $DIR/issue-98604.rs:9:5 | LL | Box::new(test) as AsyncFnPtr; - | ^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found opaque type + | ^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future | - = note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>` - found opaque type `impl Future<Output = ()>` = note: required for the cast from `fn() -> impl Future<Output = ()> {test}` to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>` error: aborting due to previous error diff --git a/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr index 6a1a9f45bc6..0d72ae118f3 100644 --- a/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr +++ b/tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr @@ -18,10 +18,13 @@ error[E0308]: mismatched types --> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5 | LL | hello() - | ^^^^^^^ expected `()`, found opaque type + | ^^^^^^^ expected `()`, found future | - = note: expected unit type `()` - found opaque type `impl Future<Output = ()>` +note: calling an async function returns a future + --> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5 + | +LL | hello() + | ^^^^^^^ help: consider `await`ing on the `Future` | LL | hello().await |
