Auto merge of #107924 - eggyal:move_fold_visit_traits_to_type_lib_with_trait_alias, r=oli-obk
Move folding & visiting traits into type library
This is a rework of #107712, following feedback on that PR.
In particular, this version uses trait aliases to reduce the API churn for trait consumers. Doing so requires a workaround for #107747 until its fix in #107803 is merged into the stage0 compiler; this workaround, which uses conditional compilation based on the `bootstrap` configuration predicate, sits in dedicated commit b409329c
for ease of reversion.
The possibility of the `rustc_middle` crate retaining its own distinct versions of each folding/visiting trait, blanket-implemented on all types that implement the respective trait in the type library, was also explored: however since this would necessitate making each `rustc_middle` trait a subtrait of the respective type library trait (so that such blanket implementations can delegate their generic methods), no benefit would be gained.
r? types
This commit is contained in:
commit
a3c9eede5d
86 changed files with 1182 additions and 999 deletions
|
@ -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::{
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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, .. }) => {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()),
|
||||
)
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() => {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>),
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)]
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
@ -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)*
|
||||
)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
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,
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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>;
|
||||
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>>;
|
||||
|
||||
/// 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>;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
{
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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,
|
||||
|
|
239
compiler/rustc_type_ir/src/fold.rs
Normal file
239
compiler/rustc_type_ir/src/fold.rs
Normal file
|
@ -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))
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
176
compiler/rustc_type_ir/src/macros.rs
Normal file
176
compiler/rustc_type_ir/src/macros.rs
Normal file
|
@ -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)*
|
||||
)
|
||||
)
|
||||
};
|
||||
}
|
238
compiler/rustc_type_ir/src/structural_impls.rs
Normal file
238
compiler/rustc_type_ir/src/structural_impls.rs
Normal file
|
@ -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))
|
||||
}
|
||||
}
|
115
compiler/rustc_type_ir/src/visit.rs
Normal file
115
compiler/rustc_type_ir/src/visit.rs
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue