Move visitable bounds up into interner
This commit is contained in:
parent
edc5053352
commit
7e80867f3c
@ -28,7 +28,7 @@ use crate::ty::{
|
|||||||
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
|
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
|
||||||
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
|
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
|
||||||
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
|
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
|
||||||
Visibility,
|
TypeVisitable, Visibility,
|
||||||
};
|
};
|
||||||
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
||||||
use rustc_ast::{self as ast, attr};
|
use rustc_ast::{self as ast, attr};
|
||||||
@ -87,7 +87,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
type GenericArg = ty::GenericArg<'tcx>;
|
type GenericArg = ty::GenericArg<'tcx>;
|
||||||
type Term = ty::Term<'tcx>;
|
type Term = ty::Term<'tcx>;
|
||||||
|
|
||||||
type Binder<T> = Binder<'tcx, T>;
|
type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
|
||||||
type BoundVars = &'tcx List<ty::BoundVariableKind>;
|
type BoundVars = &'tcx List<ty::BoundVariableKind>;
|
||||||
type BoundVar = ty::BoundVariableKind;
|
type BoundVar = ty::BoundVariableKind;
|
||||||
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_type_ir::visit::{Flags, TypeVisitableExt};
|
use rustc_type_ir::visit::TypeVisitableExt;
|
||||||
use rustc_type_ir::{
|
use rustc_type_ir::{
|
||||||
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
|
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
|
||||||
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
|
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
|
||||||
@ -45,13 +45,7 @@ pub struct Canonicalizer<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> {
|
|||||||
binder_index: ty::DebruijnIndex,
|
binder_index: ty::DebruijnIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infcx, I>
|
impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infcx, I> {
|
||||||
where
|
|
||||||
I::Ty: Flags,
|
|
||||||
I::Region: Flags,
|
|
||||||
I::Const: Flags,
|
|
||||||
I::Predicate: Flags,
|
|
||||||
{
|
|
||||||
pub fn canonicalize<T: TypeFoldable<I>>(
|
pub fn canonicalize<T: TypeFoldable<I>>(
|
||||||
infcx: &'a Infcx,
|
infcx: &'a Infcx,
|
||||||
canonicalize_mode: CanonicalizeMode,
|
canonicalize_mode: CanonicalizeMode,
|
||||||
|
@ -2,6 +2,7 @@ use smallvec::SmallVec;
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||||
use crate::{
|
use crate::{
|
||||||
BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind,
|
BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind,
|
||||||
TyKind, UniverseIndex,
|
TyKind, UniverseIndex,
|
||||||
@ -19,7 +20,7 @@ pub trait Interner: Sized {
|
|||||||
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||||
type Term: Copy + Debug + Hash + Ord;
|
type Term: Copy + Debug + Hash + Ord;
|
||||||
|
|
||||||
type Binder<T>: BoundVars<Self>;
|
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
|
||||||
type BoundVars: IntoIterator<Item = Self::BoundVar>;
|
type BoundVars: IntoIterator<Item = Self::BoundVar>;
|
||||||
type BoundVar;
|
type BoundVar;
|
||||||
|
|
||||||
@ -31,7 +32,9 @@ pub trait Interner: Sized {
|
|||||||
+ Hash
|
+ Hash
|
||||||
+ Ord
|
+ Ord
|
||||||
+ Into<Self::GenericArg>
|
+ Into<Self::GenericArg>
|
||||||
+ IntoKind<Kind = TyKind<Self>>;
|
+ IntoKind<Kind = TyKind<Self>>
|
||||||
|
+ TypeSuperVisitable<Self>
|
||||||
|
+ Flags;
|
||||||
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
|
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
|
||||||
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||||
type ParamTy: Copy + Debug + Hash + Ord;
|
type ParamTy: Copy + Debug + Hash + Ord;
|
||||||
@ -51,7 +54,9 @@ pub trait Interner: Sized {
|
|||||||
+ Ord
|
+ Ord
|
||||||
+ Into<Self::GenericArg>
|
+ Into<Self::GenericArg>
|
||||||
+ IntoKind<Kind = ConstKind<Self>>
|
+ IntoKind<Kind = ConstKind<Self>>
|
||||||
+ ConstTy<Self>;
|
+ ConstTy<Self>
|
||||||
|
+ TypeSuperVisitable<Self>
|
||||||
|
+ Flags;
|
||||||
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||||
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
|
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
|
||||||
type ParamConst: Copy + Debug + Hash + Ord;
|
type ParamConst: Copy + Debug + Hash + Ord;
|
||||||
@ -65,7 +70,8 @@ pub trait Interner: Sized {
|
|||||||
+ Hash
|
+ Hash
|
||||||
+ Ord
|
+ Ord
|
||||||
+ Into<Self::GenericArg>
|
+ Into<Self::GenericArg>
|
||||||
+ IntoKind<Kind = RegionKind<Self>>;
|
+ IntoKind<Kind = RegionKind<Self>>
|
||||||
|
+ Flags;
|
||||||
type EarlyParamRegion: Copy + Debug + Hash + Ord;
|
type EarlyParamRegion: Copy + Debug + Hash + Ord;
|
||||||
type LateParamRegion: Copy + Debug + Hash + Ord;
|
type LateParamRegion: Copy + Debug + Hash + Ord;
|
||||||
type BoundRegion: Copy + Debug + Hash + Ord;
|
type BoundRegion: Copy + Debug + Hash + Ord;
|
||||||
@ -73,7 +79,7 @@ pub trait Interner: Sized {
|
|||||||
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
|
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
|
||||||
|
|
||||||
// Predicates
|
// Predicates
|
||||||
type Predicate: Copy + Debug + Hash + Eq;
|
type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
|
||||||
type TraitPredicate: Copy + Debug + Hash + Eq;
|
type TraitPredicate: Copy + Debug + Hash + Eq;
|
||||||
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
|
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||||
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
|
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||||
|
@ -87,38 +87,28 @@ pub trait TypeVisitor<I: Interner>: Sized {
|
|||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
type BreakTy;
|
type BreakTy;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy>
|
fn visit_binder<T: TypeVisitable<I>>(
|
||||||
where
|
&mut self,
|
||||||
I::Binder<T>: TypeSuperVisitable<I>,
|
t: &I::Binder<T>,
|
||||||
{
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy>
|
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
||||||
where
|
|
||||||
I::Ty: TypeSuperVisitable<I>,
|
|
||||||
{
|
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The default region visitor is a no-op because `Region` is non-recursive
|
// The default region visitor is a no-op because `Region` is non-recursive
|
||||||
// and has no `super_visit_with` method to call. That also explains the
|
// and has no `super_visit_with` method to call.
|
||||||
// lack of `I::Region: TypeSuperVisitable<I>` bound.
|
|
||||||
fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
|
fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy>
|
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
|
||||||
where
|
|
||||||
I::Const: TypeSuperVisitable<I>,
|
|
||||||
{
|
|
||||||
c.super_visit_with(self)
|
c.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy>
|
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
||||||
where
|
|
||||||
I::Predicate: TypeSuperVisitable<I>,
|
|
||||||
{
|
|
||||||
p.super_visit_with(self)
|
p.super_visit_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,13 +317,7 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T
|
impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T {
|
||||||
where
|
|
||||||
I::Ty: Flags,
|
|
||||||
I::Region: Flags,
|
|
||||||
I::Const: Flags,
|
|
||||||
I::Predicate: Flags,
|
|
||||||
{
|
|
||||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||||
let res =
|
let res =
|
||||||
self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags);
|
self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags);
|
||||||
@ -381,19 +365,13 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
|
|||||||
// are present, regardless of whether those bound variables are used. This
|
// are present, regardless of whether those bound variables are used. This
|
||||||
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
|
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
|
||||||
// specifically detect this case in `visit_binder`.
|
// specifically detect this case in `visit_binder`.
|
||||||
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor
|
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
||||||
where
|
|
||||||
I::Ty: Flags,
|
|
||||||
I::Region: Flags,
|
|
||||||
I::Const: Flags,
|
|
||||||
I::Predicate: Flags,
|
|
||||||
{
|
|
||||||
type BreakTy = FoundFlags;
|
type BreakTy = FoundFlags;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy>
|
fn visit_binder<T: TypeVisitable<I>>(
|
||||||
where
|
&mut self,
|
||||||
I::Binder<T>: TypeSuperVisitable<I>,
|
t: &I::Binder<T>,
|
||||||
{
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
// If we're looking for the HAS_BINDER_VARS flag, check if the
|
// If we're looking for the HAS_BINDER_VARS flag, check if the
|
||||||
// binder has vars. This won't be present in the binder's bound
|
// binder has vars. This won't be present in the binder's bound
|
||||||
// value, so we need to check here too.
|
// value, so we need to check here too.
|
||||||
@ -480,19 +458,13 @@ struct HasEscapingVarsVisitor {
|
|||||||
outer_index: ty::DebruijnIndex,
|
outer_index: ty::DebruijnIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor
|
impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
||||||
where
|
|
||||||
I::Ty: Flags,
|
|
||||||
I::Region: Flags,
|
|
||||||
I::Const: Flags,
|
|
||||||
I::Predicate: Flags,
|
|
||||||
{
|
|
||||||
type BreakTy = FoundEscapingVars;
|
type BreakTy = FoundEscapingVars;
|
||||||
|
|
||||||
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy>
|
fn visit_binder<T: TypeVisitable<I>>(
|
||||||
where
|
&mut self,
|
||||||
I::Binder<T>: TypeSuperVisitable<I>,
|
t: &I::Binder<T>,
|
||||||
{
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
self.outer_index.shift_in(1);
|
self.outer_index.shift_in(1);
|
||||||
let result = t.super_visit_with(self);
|
let result = t.super_visit_with(self);
|
||||||
self.outer_index.shift_out(1);
|
self.outer_index.shift_out(1);
|
||||||
@ -550,19 +522,10 @@ where
|
|||||||
|
|
||||||
struct HasErrorVisitor;
|
struct HasErrorVisitor;
|
||||||
|
|
||||||
impl<I: Interner> TypeVisitor<I> for HasErrorVisitor
|
impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
|
||||||
where
|
|
||||||
I::Ty: Flags,
|
|
||||||
I::Region: Flags,
|
|
||||||
I::Const: Flags,
|
|
||||||
I::Predicate: Flags,
|
|
||||||
{
|
|
||||||
type BreakTy = I::ErrorGuaranteed;
|
type BreakTy = I::ErrorGuaranteed;
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: <I as Interner>::Ty) -> ControlFlow<Self::BreakTy>
|
fn visit_ty(&mut self, t: <I as Interner>::Ty) -> ControlFlow<Self::BreakTy> {
|
||||||
where
|
|
||||||
<I as Interner>::Ty: TypeSuperVisitable<I>,
|
|
||||||
{
|
|
||||||
if let ty::Error(guar) = t.kind() {
|
if let ty::Error(guar) = t.kind() {
|
||||||
ControlFlow::Break(guar)
|
ControlFlow::Break(guar)
|
||||||
} else {
|
} else {
|
||||||
@ -570,10 +533,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_const(&mut self, c: <I as Interner>::Const) -> ControlFlow<Self::BreakTy>
|
fn visit_const(&mut self, c: <I as Interner>::Const) -> ControlFlow<Self::BreakTy> {
|
||||||
where
|
|
||||||
<I as Interner>::Const: TypeSuperVisitable<I>,
|
|
||||||
{
|
|
||||||
if let ty::ConstKind::Error(guar) = c.kind() {
|
if let ty::ConstKind::Error(guar) = c.kind() {
|
||||||
ControlFlow::Break(guar)
|
ControlFlow::Break(guar)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user