Move visitable bounds up into interner

This commit is contained in:
Michael Goulet 2024-02-13 15:53:15 +00:00
parent edc5053352
commit 7e80867f3c
4 changed files with 37 additions and 77 deletions

View File

@ -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>;

View File

@ -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,

View File

@ -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;

View File

@ -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 {