Skip to content

Commit cc54612

Browse files
authoredFeb 14, 2024
Rollup merge of #120498 - compiler-errors:type-flags, r=lcnr
Uplift `TypeVisitableExt` into `rustc_type_ir` This uplifts `TypeVisitableExt` into `rustc_type_ir` so it can be used in an interner-agnostic way. It also moves some `TypeSuperVisitable` bounds onto `Interner` since we don't expect to support libraries that have types which aren't foldable by default. This restores a couple of asserts in the canonicalizer code we uplifted, and also makes it so that we can use type-flags-based helpers in the solver code, which I'm interested in uplifting. r? lcnr
2 parents 407de0e + 7e80867 commit cc54612

File tree

13 files changed

+469
-341
lines changed

13 files changed

+469
-341
lines changed
 

‎compiler/rustc_middle/src/ty/consts.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ impl<'tcx> IntoKind for Const<'tcx> {
3535
}
3636
}
3737

38+
impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> {
39+
fn flags(&self) -> TypeFlags {
40+
self.0.flags
41+
}
42+
43+
fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
44+
self.0.outer_exclusive_binder
45+
}
46+
}
47+
3848
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
3949
fn ty(self) -> Ty<'tcx> {
4050
self.ty()
@@ -63,11 +73,13 @@ impl<'tcx> Const<'tcx> {
6373
self.0.kind
6474
}
6575

76+
// FIXME(compiler-errors): Think about removing this.
6677
#[inline]
6778
pub fn flags(self) -> TypeFlags {
6879
self.0.flags
6980
}
7081

82+
// FIXME(compiler-errors): Think about removing this.
7183
#[inline]
7284
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
7385
self.0.outer_exclusive_binder

‎compiler/rustc_middle/src/ty/context.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::ty::{
2828
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
2929
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
3030
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
31-
Visibility,
31+
TypeVisitable, Visibility,
3232
};
3333
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
3434
use rustc_ast::{self as ast, attr};
@@ -87,7 +87,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
8787
type GenericArg = ty::GenericArg<'tcx>;
8888
type Term = ty::Term<'tcx>;
8989

90-
type Binder<T> = Binder<'tcx, T>;
90+
type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
91+
type BoundVars = &'tcx List<ty::BoundVariableKind>;
92+
type BoundVar = ty::BoundVariableKind;
9193
type CanonicalVars = CanonicalVarInfos<'tcx>;
9294

9395
type Ty = Ty<'tcx>;
@@ -151,6 +153,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
151153
) -> Self::Const {
152154
Const::new_bound(self, debruijn, var, ty)
153155
}
156+
157+
fn expect_error_or_delayed_bug() {
158+
let has_errors = ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs());
159+
assert!(has_errors.is_some());
160+
}
154161
}
155162

156163
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;

‎compiler/rustc_middle/src/ty/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,16 @@ impl<'tcx> IntoKind for Ty<'tcx> {
504504
}
505505
}
506506

507+
impl<'tcx> rustc_type_ir::visit::Flags for Ty<'tcx> {
508+
fn flags(&self) -> TypeFlags {
509+
self.0.flags
510+
}
511+
512+
fn outer_exclusive_binder(&self) -> DebruijnIndex {
513+
self.0.outer_exclusive_binder
514+
}
515+
}
516+
507517
impl EarlyParamRegion {
508518
/// Does this early bound region have a name? Early bound regions normally
509519
/// always have names except when using anonymous lifetimes (`'_`).

‎compiler/rustc_middle/src/ty/predicate.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,30 @@ pub struct Predicate<'tcx>(
2929
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
3030
);
3131

32+
impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> {
33+
fn flags(&self) -> TypeFlags {
34+
self.0.flags
35+
}
36+
37+
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
38+
self.0.outer_exclusive_binder
39+
}
40+
}
41+
3242
impl<'tcx> Predicate<'tcx> {
3343
/// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`.
3444
#[inline]
3545
pub fn kind(self) -> ty::Binder<'tcx, PredicateKind<'tcx>> {
3646
self.0.internee
3747
}
3848

49+
// FIXME(compiler-errors): Think about removing this.
3950
#[inline(always)]
4051
pub fn flags(self) -> TypeFlags {
4152
self.0.flags
4253
}
4354

55+
// FIXME(compiler-errors): Think about removing this.
4456
#[inline(always)]
4557
pub fn outer_exclusive_binder(self) -> DebruijnIndex {
4658
self.0.outer_exclusive_binder

‎compiler/rustc_middle/src/ty/region.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@ impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> {
2626
}
2727
}
2828

29+
impl<'tcx> rustc_type_ir::visit::Flags for Region<'tcx> {
30+
fn flags(&self) -> TypeFlags {
31+
self.type_flags()
32+
}
33+
34+
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
35+
match **self {
36+
ty::ReBound(debruijn, _) => debruijn.shifted_in(1),
37+
_ => ty::INNERMOST,
38+
}
39+
}
40+
}
41+
2942
impl<'tcx> Region<'tcx> {
3043
#[inline]
3144
pub fn new_early_param(

‎compiler/rustc_middle/src/ty/sty.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,16 @@ where
942942
}
943943
}
944944

945+
impl<'tcx, T> rustc_type_ir::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
946+
fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> {
947+
self.bound_vars
948+
}
949+
950+
fn has_no_bound_vars(&self) -> bool {
951+
self.bound_vars.is_empty()
952+
}
953+
}
954+
945955
impl<'tcx, T> Binder<'tcx, T> {
946956
/// Skips the binder and returns the "bound" value. This is a
947957
/// risky thing to do because it's easy to get confused about
@@ -1808,6 +1818,7 @@ impl<'tcx> Ty<'tcx> {
18081818
self.0.0
18091819
}
18101820

1821+
// FIXME(compiler-errors): Think about removing this.
18111822
#[inline(always)]
18121823
pub fn flags(self) -> TypeFlags {
18131824
self.0.0.flags

‎compiler/rustc_middle/src/ty/util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,7 @@ impl<'tcx> Ty<'tcx> {
13201320
ty
13211321
}
13221322

1323+
// FIXME(compiler-errors): Think about removing this.
13231324
#[inline]
13241325
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
13251326
self.0.outer_exclusive_binder

‎compiler/rustc_middle/src/ty/visit.rs

Lines changed: 1 addition & 310 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,10 @@
11
use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
2-
use rustc_errors::ErrorGuaranteed;
32

43
use rustc_data_structures::fx::FxHashSet;
54
use rustc_data_structures::sso::SsoHashSet;
65
use std::ops::ControlFlow;
76

8-
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
9-
10-
pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
11-
/// Returns `true` if `self` has any late-bound regions that are either
12-
/// bound by `binder` or bound by some binder outside of `binder`.
13-
/// If `binder` is `ty::INNERMOST`, this indicates whether
14-
/// there are any late-bound regions that appear free.
15-
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
16-
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break()
17-
}
18-
19-
/// Returns `true` if this type has any regions that escape `binder` (and
20-
/// hence are not bound by it).
21-
fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
22-
self.has_vars_bound_at_or_above(binder.shifted_in(1))
23-
}
24-
25-
/// Return `true` if this type has regions that are not a part of the type.
26-
/// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
27-
/// would return `true`. The latter can occur when traversing through the
28-
/// former.
29-
///
30-
/// See [`HasEscapingVarsVisitor`] for more information.
31-
fn has_escaping_bound_vars(&self) -> bool {
32-
self.has_vars_bound_at_or_above(ty::INNERMOST)
33-
}
34-
35-
fn has_type_flags(&self, flags: TypeFlags) -> bool {
36-
let res =
37-
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags);
38-
trace!(?self, ?flags, ?res, "has_type_flags");
39-
res
40-
}
41-
fn has_projections(&self) -> bool {
42-
self.has_type_flags(TypeFlags::HAS_PROJECTION)
43-
}
44-
fn has_inherent_projections(&self) -> bool {
45-
self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
46-
}
47-
fn has_opaque_types(&self) -> bool {
48-
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
49-
}
50-
fn has_coroutines(&self) -> bool {
51-
self.has_type_flags(TypeFlags::HAS_TY_COROUTINE)
52-
}
53-
fn references_error(&self) -> bool {
54-
self.has_type_flags(TypeFlags::HAS_ERROR)
55-
}
56-
fn error_reported(&self) -> Result<(), ErrorGuaranteed> {
57-
if self.references_error() {
58-
// We must include lint errors and delayed bugs here.
59-
if let Some(reported) =
60-
ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs())
61-
{
62-
Err(reported)
63-
} else {
64-
bug!("expected some kind of error in `error_reported`");
65-
}
66-
} else {
67-
Ok(())
68-
}
69-
}
70-
fn has_non_region_param(&self) -> bool {
71-
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
72-
}
73-
fn has_infer_regions(&self) -> bool {
74-
self.has_type_flags(TypeFlags::HAS_RE_INFER)
75-
}
76-
fn has_infer_types(&self) -> bool {
77-
self.has_type_flags(TypeFlags::HAS_TY_INFER)
78-
}
79-
fn has_non_region_infer(&self) -> bool {
80-
self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER)
81-
}
82-
fn has_infer(&self) -> bool {
83-
self.has_type_flags(TypeFlags::HAS_INFER)
84-
}
85-
fn has_placeholders(&self) -> bool {
86-
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER)
87-
}
88-
fn has_non_region_placeholders(&self) -> bool {
89-
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER)
90-
}
91-
fn has_param(&self) -> bool {
92-
self.has_type_flags(TypeFlags::HAS_PARAM)
93-
}
94-
/// "Free" regions in this context means that it has any region
95-
/// that is not (a) erased or (b) late-bound.
96-
fn has_free_regions(&self) -> bool {
97-
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
98-
}
99-
100-
fn has_erased_regions(&self) -> bool {
101-
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
102-
}
103-
104-
/// True if there are any un-erased free regions.
105-
fn has_erasable_regions(&self) -> bool {
106-
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
107-
}
108-
109-
/// Indicates whether this value references only 'global'
110-
/// generic parameters that are the same regardless of what fn we are
111-
/// in. This is used for caching.
112-
fn is_global(&self) -> bool {
113-
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
114-
}
115-
116-
/// True if there are any late-bound regions
117-
fn has_bound_regions(&self) -> bool {
118-
self.has_type_flags(TypeFlags::HAS_RE_BOUND)
119-
}
120-
/// True if there are any late-bound non-region variables
121-
fn has_non_region_bound_vars(&self) -> bool {
122-
self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
123-
}
124-
/// True if there are any bound variables
125-
fn has_bound_vars(&self) -> bool {
126-
self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
127-
}
128-
129-
/// Indicates whether this value still has parameters/placeholders/inference variables
130-
/// which could be replaced later, in a way that would change the results of `impl`
131-
/// specialization.
132-
fn still_further_specializable(&self) -> bool {
133-
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
134-
}
135-
}
136-
137-
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {}
7+
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
1388

1399
///////////////////////////////////////////////////////////////////////////
14010
// Region folder
@@ -370,185 +240,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
370240
}
371241
}
372242

373-
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
374-
struct FoundEscapingVars;
375-
376-
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
377-
/// bound region or a bound type.
378-
///
379-
/// So, for example, consider a type like the following, which has two binders:
380-
///
381-
/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
382-
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
383-
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
384-
///
385-
/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
386-
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
387-
/// fn type*, that type has an escaping region: `'a`.
388-
///
389-
/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
390-
/// we already use the term "free var". It refers to the regions or types that we use to represent
391-
/// bound regions or type params on a fn definition while we are type checking its body.
392-
///
393-
/// To clarify, conceptually there is no particular difference between
394-
/// an "escaping" var and a "free" var. However, there is a big
395-
/// difference in practice. Basically, when "entering" a binding
396-
/// level, one is generally required to do some sort of processing to
397-
/// a bound var, such as replacing it with a fresh/placeholder
398-
/// var, or making an entry in the environment to represent the
399-
/// scope to which it is attached, etc. An escaping var represents
400-
/// a bound var for which this processing has not yet been done.
401-
struct HasEscapingVarsVisitor {
402-
/// Anything bound by `outer_index` or "above" is escaping.
403-
outer_index: ty::DebruijnIndex,
404-
}
405-
406-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor {
407-
type BreakTy = FoundEscapingVars;
408-
409-
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
410-
&mut self,
411-
t: &Binder<'tcx, T>,
412-
) -> ControlFlow<Self::BreakTy> {
413-
self.outer_index.shift_in(1);
414-
let result = t.super_visit_with(self);
415-
self.outer_index.shift_out(1);
416-
result
417-
}
418-
419-
#[inline]
420-
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
421-
// If the outer-exclusive-binder is *strictly greater* than
422-
// `outer_index`, that means that `t` contains some content
423-
// bound at `outer_index` or above (because
424-
// `outer_exclusive_binder` is always 1 higher than the
425-
// content in `t`). Therefore, `t` has some escaping vars.
426-
if t.outer_exclusive_binder() > self.outer_index {
427-
ControlFlow::Break(FoundEscapingVars)
428-
} else {
429-
ControlFlow::Continue(())
430-
}
431-
}
432-
433-
#[inline]
434-
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
435-
// If the region is bound by `outer_index` or anything outside
436-
// of outer index, then it escapes the binders we have
437-
// visited.
438-
if r.bound_at_or_above_binder(self.outer_index) {
439-
ControlFlow::Break(FoundEscapingVars)
440-
} else {
441-
ControlFlow::Continue(())
442-
}
443-
}
444-
445-
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
446-
// If the outer-exclusive-binder is *strictly greater* than
447-
// `outer_index`, that means that `ct` contains some content
448-
// bound at `outer_index` or above (because
449-
// `outer_exclusive_binder` is always 1 higher than the
450-
// content in `t`). Therefore, `t` has some escaping vars.
451-
if ct.outer_exclusive_binder() > self.outer_index {
452-
ControlFlow::Break(FoundEscapingVars)
453-
} else {
454-
ControlFlow::Continue(())
455-
}
456-
}
457-
458-
#[inline]
459-
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
460-
if predicate.outer_exclusive_binder() > self.outer_index {
461-
ControlFlow::Break(FoundEscapingVars)
462-
} else {
463-
ControlFlow::Continue(())
464-
}
465-
}
466-
}
467-
468-
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
469-
struct FoundFlags;
470-
471-
// FIXME: Optimize for checking for infer flags
472-
struct HasTypeFlagsVisitor {
473-
flags: ty::TypeFlags,
474-
}
475-
476-
impl std::fmt::Debug for HasTypeFlagsVisitor {
477-
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
478-
self.flags.fmt(fmt)
479-
}
480-
}
481-
482-
// Note: this visitor traverses values down to the level of
483-
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
484-
// type flags at the outer layer are enough. So it's faster than it first
485-
// looks, particular for `Ty`/`Predicate` where it's just a field access.
486-
//
487-
// N.B. The only case where this isn't totally true is binders, which also
488-
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
489-
// are present, regardless of whether those bound variables are used. This
490-
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
491-
// specifically detect this case in `visit_binder`.
492-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
493-
type BreakTy = FoundFlags;
494-
495-
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
496-
&mut self,
497-
t: &Binder<'tcx, T>,
498-
) -> ControlFlow<Self::BreakTy> {
499-
// If we're looking for the HAS_BINDER_VARS flag, check if the
500-
// binder has vars. This won't be present in the binder's bound
501-
// value, so we need to check here too.
502-
if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.bound_vars().is_empty() {
503-
return ControlFlow::Break(FoundFlags);
504-
}
505-
506-
t.super_visit_with(self)
507-
}
508-
509-
#[inline]
510-
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
511-
// Note: no `super_visit_with` call.
512-
let flags = t.flags();
513-
if flags.intersects(self.flags) {
514-
ControlFlow::Break(FoundFlags)
515-
} else {
516-
ControlFlow::Continue(())
517-
}
518-
}
519-
520-
#[inline]
521-
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
522-
// Note: no `super_visit_with` call, as usual for `Region`.
523-
let flags = r.type_flags();
524-
if flags.intersects(self.flags) {
525-
ControlFlow::Break(FoundFlags)
526-
} else {
527-
ControlFlow::Continue(())
528-
}
529-
}
530-
531-
#[inline]
532-
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
533-
// Note: no `super_visit_with` call.
534-
if c.flags().intersects(self.flags) {
535-
ControlFlow::Break(FoundFlags)
536-
} else {
537-
ControlFlow::Continue(())
538-
}
539-
}
540-
541-
#[inline]
542-
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
543-
// Note: no `super_visit_with` call.
544-
if predicate.flags().intersects(self.flags) {
545-
ControlFlow::Break(FoundFlags)
546-
} else {
547-
ControlFlow::Continue(())
548-
}
549-
}
550-
}
551-
552243
/// Collects all the late-bound regions at the innermost binding level
553244
/// into a hash set.
554245
struct LateBoundRegionsCollector {

‎compiler/rustc_next_trait_solver/src/canonicalizer.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::cmp::Ordering;
22

33
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
4+
use rustc_type_ir::visit::TypeVisitableExt;
45
use rustc_type_ir::{
56
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
67
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
@@ -62,8 +63,8 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
6263

6364
let value = value.fold_with(&mut canonicalizer);
6465
// FIXME: Restore these assertions. Should we uplift type flags?
65-
// assert!(!value.has_infer(), "unexpected infer in {value:?}");
66-
// assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
66+
assert!(!value.has_infer(), "unexpected infer in {value:?}");
67+
assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
6768

6869
let (max_universe, variables) = canonicalizer.finalize();
6970

‎compiler/rustc_type_ir/src/binder.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use crate::Interner;
2+
3+
pub trait BoundVars<I: Interner> {
4+
fn bound_vars(&self) -> I::BoundVars;
5+
6+
fn has_no_bound_vars(&self) -> bool;
7+
}

‎compiler/rustc_type_ir/src/interner.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ use smallvec::SmallVec;
22
use std::fmt::Debug;
33
use std::hash::Hash;
44

5+
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
56
use crate::{
6-
BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind,
7-
UniverseIndex,
7+
BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind,
8+
TyKind, UniverseIndex,
89
};
910

1011
pub trait Interner: Sized {
@@ -19,7 +20,10 @@ pub trait Interner: Sized {
1920
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
2021
type Term: Copy + Debug + Hash + Ord;
2122

22-
type Binder<T>;
23+
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
24+
type BoundVars: IntoIterator<Item = Self::BoundVar>;
25+
type BoundVar;
26+
2327
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
2428

2529
// Kinds of tys
@@ -28,7 +32,9 @@ pub trait Interner: Sized {
2832
+ Hash
2933
+ Ord
3034
+ Into<Self::GenericArg>
31-
+ IntoKind<Kind = TyKind<Self>>;
35+
+ IntoKind<Kind = TyKind<Self>>
36+
+ TypeSuperVisitable<Self>
37+
+ Flags;
3238
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
3339
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
3440
type ParamTy: Copy + Debug + Hash + Ord;
@@ -48,7 +54,9 @@ pub trait Interner: Sized {
4854
+ Ord
4955
+ Into<Self::GenericArg>
5056
+ IntoKind<Kind = ConstKind<Self>>
51-
+ ConstTy<Self>;
57+
+ ConstTy<Self>
58+
+ TypeSuperVisitable<Self>
59+
+ Flags;
5260
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
5361
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
5462
type ParamConst: Copy + Debug + Hash + Ord;
@@ -62,15 +70,16 @@ pub trait Interner: Sized {
6270
+ Hash
6371
+ Ord
6472
+ Into<Self::GenericArg>
65-
+ IntoKind<Kind = RegionKind<Self>>;
73+
+ IntoKind<Kind = RegionKind<Self>>
74+
+ Flags;
6675
type EarlyParamRegion: Copy + Debug + Hash + Ord;
6776
type LateParamRegion: Copy + Debug + Hash + Ord;
6877
type BoundRegion: Copy + Debug + Hash + Ord;
6978
type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Ord;
7079
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
7180

7281
// Predicates
73-
type Predicate: Copy + Debug + Hash + Eq;
82+
type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
7483
type TraitPredicate: Copy + Debug + Hash + Eq;
7584
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
7685
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
@@ -86,6 +95,9 @@ pub trait Interner: Sized {
8695
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
8796
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
8897
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
98+
99+
/// Assert that an error has been delayed or emitted.
100+
fn expect_error_or_delayed_bug();
89101
}
90102

91103
/// Common capabilities of placeholder kinds

‎compiler/rustc_type_ir/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub mod visit;
3030

3131
#[macro_use]
3232
mod macros;
33+
mod binder;
3334
mod canonical;
3435
mod const_kind;
3536
mod debug;
@@ -39,6 +40,7 @@ mod interner;
3940
mod predicate_kind;
4041
mod region_kind;
4142

43+
pub use binder::*;
4244
pub use canonical::*;
4345
#[cfg(feature = "nightly")]
4446
pub use codec::*;

‎compiler/rustc_type_ir/src/visit.rs

Lines changed: 369 additions & 20 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.