Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 05d9393

Browse files
committedMay 23, 2025·
do not canonicalize BoundVar for placeholders
1 parent 2746b9b commit 05d9393

File tree

23 files changed

+229
-184
lines changed

23 files changed

+229
-184
lines changed
 

‎compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,10 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
173173
match r.kind() {
174174
ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r,
175175

176-
ty::RePlaceholder(placeholder) => canonicalizer
177-
.canonical_var_for_region(CanonicalVarKind::PlaceholderRegion(placeholder), r),
176+
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
177+
CanonicalVarKind::PlaceholderRegion(placeholder.universe),
178+
r,
179+
),
178180

179181
ty::ReVar(vid) => {
180182
let universe = infcx
@@ -288,7 +290,7 @@ struct Canonicalizer<'cx, 'tcx> {
288290
/// Set to `None` to disable the resolution of inference variables.
289291
infcx: Option<&'cx InferCtxt<'tcx>>,
290292
tcx: TyCtxt<'tcx>,
291-
variables: SmallVec<[CanonicalVarKind<'tcx>; 8]>,
293+
variables: SmallVec<[CanonicalVarKind; 8]>,
292294
query_state: &'cx mut OriginalQueryValues<'tcx>,
293295
// Note that indices is only used once `var_values` is big enough to be
294296
// heap-allocated.
@@ -390,11 +392,13 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
390392
bug!("encountered a fresh type during canonicalization")
391393
}
392394

393-
ty::Placeholder(mut placeholder) => {
394-
if !self.canonicalize_mode.preserve_universes() {
395-
placeholder.universe = ty::UniverseIndex::ROOT;
396-
}
397-
self.canonicalize_ty_var(CanonicalVarKind::PlaceholderTy(placeholder), t)
395+
ty::Placeholder(placeholder) => {
396+
let universe = if self.canonicalize_mode.preserve_universes() {
397+
placeholder.universe
398+
} else {
399+
ty::UniverseIndex::ROOT
400+
};
401+
self.canonicalize_ty_var(CanonicalVarKind::PlaceholderTy(universe), t)
398402
}
399403

400404
ty::Bound(debruijn, _) => {
@@ -481,8 +485,13 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
481485
}
482486
}
483487
ty::ConstKind::Placeholder(placeholder) => {
488+
let universe = if self.canonicalize_mode.preserve_universes() {
489+
placeholder.universe
490+
} else {
491+
ty::UniverseIndex::ROOT
492+
};
484493
return self
485-
.canonicalize_const_var(CanonicalVarKind::PlaceholderConst(placeholder), ct);
494+
.canonicalize_const_var(CanonicalVarKind::PlaceholderConst(universe), ct);
486495
}
487496
_ => {}
488497
}
@@ -588,7 +597,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
588597
/// or returns an existing variable if `kind` has already been
589598
/// seen. `kind` is expected to be an unbound variable (or
590599
/// potentially a free region).
591-
fn canonical_var(&mut self, info: CanonicalVarKind<'tcx>, kind: GenericArg<'tcx>) -> BoundVar {
600+
fn canonical_var(&mut self, info: CanonicalVarKind, kind: GenericArg<'tcx>) -> BoundVar {
592601
let Canonicalizer { variables, query_state, indices, .. } = self;
593602

594603
let var_values = &mut query_state.var_values;
@@ -651,7 +660,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
651660
/// Replaces the universe indexes used in `var_values` with their index in
652661
/// `query_state.universe_map`. This minimizes the maximum universe used in
653662
/// the canonicalized value.
654-
fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarKind<'tcx>; 8]> {
663+
fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarKind; 8]> {
655664
if self.query_state.universe_map.len() == 1 {
656665
return self.variables;
657666
}
@@ -675,23 +684,14 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
675684
}
676685
CanonicalVarKind::Region(u) => CanonicalVarKind::Region(reverse_universe_map[&u]),
677686
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
678-
CanonicalVarKind::PlaceholderTy(placeholder) => {
679-
CanonicalVarKind::PlaceholderTy(ty::Placeholder {
680-
universe: reverse_universe_map[&placeholder.universe],
681-
..placeholder
682-
})
687+
CanonicalVarKind::PlaceholderTy(ui) => {
688+
CanonicalVarKind::PlaceholderTy(reverse_universe_map[&ui])
683689
}
684-
CanonicalVarKind::PlaceholderRegion(placeholder) => {
685-
CanonicalVarKind::PlaceholderRegion(ty::Placeholder {
686-
universe: reverse_universe_map[&placeholder.universe],
687-
..placeholder
688-
})
690+
CanonicalVarKind::PlaceholderRegion(ui) => {
691+
CanonicalVarKind::PlaceholderRegion(reverse_universe_map[&ui])
689692
}
690-
CanonicalVarKind::PlaceholderConst(placeholder) => {
691-
CanonicalVarKind::PlaceholderConst(ty::Placeholder {
692-
universe: reverse_universe_map[&placeholder.universe],
693-
..placeholder
694-
})
693+
CanonicalVarKind::PlaceholderConst(ui) => {
694+
CanonicalVarKind::PlaceholderConst(reverse_universe_map[&ui])
695695
}
696696
})
697697
.collect()
@@ -721,7 +721,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
721721
/// representing the region `r`; return a region referencing it.
722722
fn canonical_var_for_region(
723723
&mut self,
724-
info: CanonicalVarKind<'tcx>,
724+
info: CanonicalVarKind,
725725
r: ty::Region<'tcx>,
726726
) -> ty::Region<'tcx> {
727727
let var = self.canonical_var(info, r.into());
@@ -733,10 +733,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
733733
/// if `ty_var` is bound to anything; if so, canonicalize
734734
/// *that*. Otherwise, create a new canonical variable for
735735
/// `ty_var`.
736-
fn canonicalize_ty_var(&mut self, info: CanonicalVarKind<'tcx>, ty_var: Ty<'tcx>) -> Ty<'tcx> {
736+
fn canonicalize_ty_var(&mut self, info: CanonicalVarKind, ty_var: Ty<'tcx>) -> Ty<'tcx> {
737737
debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
738738
let var = self.canonical_var(info, ty_var.into());
739-
Ty::new_bound(self.tcx, self.binder_index, var.into())
739+
Ty::new_bound(self.tcx, self.binder_index, ty::BoundTy::new_anon(var))
740740
}
741741

742742
/// Given a type variable `const_var` of the given kind, first check
@@ -745,7 +745,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
745745
/// `const_var`.
746746
fn canonicalize_const_var(
747747
&mut self,
748-
info: CanonicalVarKind<'tcx>,
748+
info: CanonicalVarKind,
749749
const_var: ty::Const<'tcx>,
750750
) -> ty::Const<'tcx> {
751751
debug_assert!(

‎compiler/rustc_infer/src/infer/canonical/mod.rs

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -81,30 +81,27 @@ impl<'tcx> InferCtxt<'tcx> {
8181
fn instantiate_canonical_vars(
8282
&self,
8383
span: Span,
84-
variables: &List<CanonicalVarKind<'tcx>>,
84+
variables: &List<CanonicalVarKind>,
8585
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
8686
) -> CanonicalVarValues<'tcx> {
8787
CanonicalVarValues {
88-
var_values: self.tcx.mk_args_from_iter(
89-
variables
90-
.iter()
91-
.map(|kind| self.instantiate_canonical_var(span, kind, &universe_map)),
92-
),
88+
var_values: self.tcx.mk_args_from_iter(variables.iter().enumerate().map(
89+
|(at_index, kind)| {
90+
self.instantiate_canonical_var(span, at_index, kind, &universe_map)
91+
},
92+
)),
9393
}
9494
}
9595

96-
/// Given the "info" about a canonical variable, creates a fresh
97-
/// variable for it. If this is an existentially quantified
98-
/// variable, then you'll get a new inference variable; if it is a
99-
/// universally quantified variable, you get a placeholder.
96+
/// Given the "info" about a canonical variable, creates a fresh variable for it.
10097
///
101-
/// FIXME(-Znext-solver): This is public because it's used by the
102-
/// new trait solver which has a different canonicalization routine.
103-
/// We should somehow deduplicate all of this.
104-
pub fn instantiate_canonical_var(
98+
/// This ICEs if the input is not an existential variable. Handle placeholders separately
99+
/// or call [Self::instantiate_canonical_var] instead.
100+
#[inline]
101+
pub fn instantiate_existential_canonical_var(
105102
&self,
106103
span: Span,
107-
kind: CanonicalVarKind<'tcx>,
104+
kind: CanonicalVarKind,
108105
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
109106
) -> GenericArg<'tcx> {
110107
match kind {
@@ -121,32 +118,68 @@ impl<'tcx> InferCtxt<'tcx> {
121118
ty.into()
122119
}
123120

124-
CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, bound }) => {
125-
let universe_mapped = universe_map(universe);
126-
let placeholder_mapped = ty::PlaceholderType { universe: universe_mapped, bound };
127-
Ty::new_placeholder(self.tcx, placeholder_mapped).into()
128-
}
129-
130121
CanonicalVarKind::Region(ui) => self
131122
.next_region_var_in_universe(
132123
RegionVariableOrigin::MiscVariable(span),
133124
universe_map(ui),
134125
)
135126
.into(),
136127

137-
CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, bound }) => {
128+
CanonicalVarKind::Const(ui) => {
129+
self.next_const_var_in_universe(span, universe_map(ui)).into()
130+
}
131+
132+
CanonicalVarKind::PlaceholderRegion(_)
133+
| CanonicalVarKind::PlaceholderTy(_)
134+
| CanonicalVarKind::PlaceholderConst(_) => unreachable!(),
135+
}
136+
}
137+
138+
/// Given the "info" about a canonical variable, creates a fresh
139+
/// variable for it. If this is an existentially quantified
140+
/// variable, then you'll get a new inference variable; if it is a
141+
/// universally quantified variable, you get a placeholder.
142+
///
143+
/// FIXME(-Znext-solver): This is public because it's used by the
144+
/// new trait solver which has a different canonicalization routine.
145+
/// We should somehow deduplicate all of this.
146+
pub fn instantiate_canonical_var(
147+
&self,
148+
span: Span,
149+
at_index: usize,
150+
kind: CanonicalVarKind,
151+
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
152+
) -> GenericArg<'tcx> {
153+
match kind {
154+
CanonicalVarKind::Region(_) | CanonicalVarKind::Ty(_) | CanonicalVarKind::Const(_) => {
155+
self.instantiate_existential_canonical_var(span, kind, universe_map)
156+
}
157+
158+
CanonicalVarKind::PlaceholderTy(universe) => {
159+
let var = ty::BoundVar::from_usize(at_index);
138160
let universe_mapped = universe_map(universe);
139-
let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, bound };
140-
ty::Region::new_placeholder(self.tcx, placeholder_mapped).into()
161+
let placeholder = ty::PlaceholderType {
162+
universe: universe_mapped,
163+
bound: ty::BoundTy::new_anon(var),
164+
};
165+
Ty::new_placeholder(self.tcx, placeholder).into()
141166
}
142167

143-
CanonicalVarKind::Const(ui) => {
144-
self.next_const_var_in_universe(span, universe_map(ui)).into()
168+
CanonicalVarKind::PlaceholderRegion(universe) => {
169+
let var = ty::BoundVar::from_usize(at_index);
170+
let universe_mapped = universe_map(universe);
171+
let placeholder = ty::PlaceholderRegion {
172+
universe: universe_mapped,
173+
bound: ty::BoundRegion::new_anon(var),
174+
};
175+
ty::Region::new_placeholder(self.tcx, placeholder).into()
145176
}
146-
CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }) => {
177+
178+
CanonicalVarKind::PlaceholderConst(universe) => {
179+
let var = ty::BoundVar::from_usize(at_index);
147180
let universe_mapped = universe_map(universe);
148-
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound };
149-
ty::Const::new_placeholder(self.tcx, placeholder_mapped).into()
181+
let placeholder = ty::PlaceholderConst { universe: universe_mapped, bound: var };
182+
ty::Const::new_placeholder(self.tcx, placeholder).into()
150183
}
151184
}
152185
}

‎compiler/rustc_infer/src/infer/canonical/query_response.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,15 +449,17 @@ impl<'tcx> InferCtxt<'tcx> {
449449
if var_kind.universe() != ty::UniverseIndex::ROOT {
450450
// A variable from inside a binder of the query. While ideally these shouldn't
451451
// exist at all, we have to deal with them for now.
452-
self.instantiate_canonical_var(cause.span, var_kind, |u| {
452+
self.instantiate_canonical_var(cause.span, index, var_kind, |u| {
453453
universe_map[u.as_usize()]
454454
})
455455
} else if var_kind.is_existential() {
456456
match opt_values[BoundVar::new(index)] {
457457
Some(k) => k,
458-
None => self.instantiate_canonical_var(cause.span, var_kind, |u| {
459-
universe_map[u.as_usize()]
460-
}),
458+
None => {
459+
self.instantiate_canonical_var(cause.span, index, var_kind, |u| {
460+
universe_map[u.as_usize()]
461+
})
462+
}
461463
}
462464
} else {
463465
// For placeholders which were already part of the input, we simply map this

‎compiler/rustc_middle/src/infer/canonical.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ use crate::ty::{self, GenericArg, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}
3535

3636
pub type CanonicalQueryInput<'tcx, V> = ir::CanonicalQueryInput<TyCtxt<'tcx>, V>;
3737
pub type Canonical<'tcx, V> = ir::Canonical<TyCtxt<'tcx>, V>;
38-
pub type CanonicalVarKind<'tcx> = ir::CanonicalVarKind<TyCtxt<'tcx>>;
38+
pub type CanonicalVarKind = ir::CanonicalVarKind;
3939
pub type CanonicalVarValues<'tcx> = ir::CanonicalVarValues<TyCtxt<'tcx>>;
40-
pub type CanonicalVarKinds<'tcx> = &'tcx List<CanonicalVarKind<'tcx>>;
40+
pub type CanonicalVarKinds<'tcx> = &'tcx List<CanonicalVarKind>;
4141

4242
/// When we canonicalize a value to form a query, we wind up replacing
4343
/// various parts of it with canonical variables. This struct stores

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarKinds<'tcx> {
314314
fn decode(decoder: &mut D) -> Self {
315315
let len = decoder.read_usize();
316316
decoder.interner().mk_canonical_var_infos_from_iter(
317-
(0..len).map::<CanonicalVarKind<'tcx>, _>(|_| Decodable::decode(decoder)),
317+
(0..len).map::<CanonicalVarKind, _>(|_| Decodable::decode(decoder)),
318318
)
319319
}
320320
}

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
108108
}
109109
type LocalDefIds = &'tcx ty::List<LocalDefId>;
110110
type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
111-
fn mk_canonical_var_kinds(
112-
self,
113-
kinds: &[ty::CanonicalVarKind<Self>],
114-
) -> Self::CanonicalVarKinds {
111+
fn mk_canonical_var_kinds(self, kinds: &[ty::CanonicalVarKind]) -> Self::CanonicalVarKinds {
115112
self.mk_canonical_var_kinds(kinds)
116113
}
117114

@@ -836,7 +833,7 @@ pub struct CtxtInterners<'tcx> {
836833
const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>,
837834
args: InternedSet<'tcx, GenericArgs<'tcx>>,
838835
type_lists: InternedSet<'tcx, List<Ty<'tcx>>>,
839-
canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind<'tcx>>>,
836+
canonical_var_kinds: InternedSet<'tcx, List<CanonicalVarKind>>,
840837
region: InternedSet<'tcx, RegionKind<'tcx>>,
841838
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
842839
predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
@@ -2678,7 +2675,7 @@ slice_interners!(
26782675
const_lists: pub mk_const_list(Const<'tcx>),
26792676
args: pub mk_args(GenericArg<'tcx>),
26802677
type_lists: pub mk_type_list(Ty<'tcx>),
2681-
canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind<'tcx>),
2678+
canonical_var_kinds: pub mk_canonical_var_kinds(CanonicalVarKind),
26822679
poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
26832680
projs: pub mk_projs(ProjectionKind),
26842681
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
@@ -3058,7 +3055,7 @@ impl<'tcx> TyCtxt<'tcx> {
30583055
pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
30593056
where
30603057
I: Iterator<Item = T>,
3061-
T: CollectAndApply<CanonicalVarKind<'tcx>, &'tcx List<CanonicalVarKind<'tcx>>>,
3058+
T: CollectAndApply<CanonicalVarKind, &'tcx List<CanonicalVarKind>>,
30623059
{
30633060
T::collect_and_apply(iter, |xs| self.mk_canonical_var_kinds(xs))
30643061
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,13 +437,23 @@ pub struct BoundRegion {
437437
pub kind: BoundRegionKind,
438438
}
439439

440+
impl BoundRegion {
441+
pub fn new_anon(var: BoundVar) -> BoundRegion {
442+
BoundRegion { var, kind: BoundRegionKind::Anon }
443+
}
444+
}
445+
440446
impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundRegion {
447+
fn new_anon(var: BoundVar) -> BoundRegion {
448+
Self::new_anon(var)
449+
}
450+
441451
fn var(self) -> BoundVar {
442452
self.var
443453
}
444454

445-
fn assert_eq(self, var: ty::BoundVariableKind) {
446-
assert_eq!(self.kind, var.expect_region())
455+
fn assert_eq(self, kind: ty::BoundVariableKind) {
456+
assert_eq!(self.kind, kind.expect_region())
447457
}
448458
}
449459

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,17 @@ pub struct BoundTy {
374374
pub kind: BoundTyKind,
375375
}
376376

377+
impl BoundTy {
378+
pub fn new_anon(var: BoundVar) -> BoundTy {
379+
BoundTy { var, kind: BoundTyKind::Anon }
380+
}
381+
}
382+
377383
impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundTy {
384+
fn new_anon(var: BoundVar) -> BoundTy {
385+
Self::new_anon(var)
386+
}
387+
378388
fn var(self) -> BoundVar {
379389
self.var
380390
}
@@ -391,12 +401,6 @@ pub enum BoundTyKind {
391401
Param(DefId, Symbol),
392402
}
393403

394-
impl From<BoundVar> for BoundTy {
395-
fn from(var: BoundVar) -> Self {
396-
BoundTy { var, kind: BoundTyKind::Anon }
397-
}
398-
}
399-
400404
/// Constructors for `Ty`
401405
impl<'tcx> Ty<'tcx> {
402406
/// Avoid using this in favour of more specific `new_*` methods, where possible.

‎compiler/rustc_next_trait_solver/src/canonicalizer.rs

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner> {
5050

5151
// Mutable fields.
5252
variables: &'a mut Vec<I::GenericArg>,
53-
var_kinds: Vec<CanonicalVarKind<I>>,
53+
var_kinds: Vec<CanonicalVarKind>,
5454
variable_lookup_table: HashMap<I::GenericArg, usize>,
5555
binder_index: ty::DebruijnIndex,
5656

@@ -149,7 +149,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
149149
fn get_or_insert_bound_var(
150150
&mut self,
151151
arg: impl Into<I::GenericArg>,
152-
kind: CanonicalVarKind<I>,
152+
kind: CanonicalVarKind,
153153
) -> ty::BoundVar {
154154
// FIXME: 16 is made up and arbitrary. We should look at some
155155
// perf data here.
@@ -232,7 +232,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
232232
let mut existential_in_new_uv = None;
233233
let mut next_orig_uv = Some(ty::UniverseIndex::ROOT);
234234
while let Some(orig_uv) = next_orig_uv.take() {
235-
let mut update_uv = |var: &mut CanonicalVarKind<I>, orig_uv, is_existential| {
235+
let mut update_uv = |var: &mut CanonicalVarKind, orig_uv, is_existential| {
236236
let uv = var.universe();
237237
match uv.cmp(&orig_uv) {
238238
Ordering::Less => (), // Already updated
@@ -349,16 +349,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
349349
panic!("fresh vars not expected in canonicalization")
350350
}
351351
},
352-
ty::Placeholder(placeholder) => match self.canonicalize_mode {
353-
CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderTy(
354-
PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
355-
),
356-
CanonicalizeMode::Response { .. } => CanonicalVarKind::PlaceholderTy(placeholder),
357-
},
352+
ty::Placeholder(placeholder) => CanonicalVarKind::PlaceholderTy(placeholder.universe()),
358353
ty::Param(_) => match self.canonicalize_mode {
359-
CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderTy(
360-
PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
361-
),
354+
CanonicalizeMode::Input { .. } => {
355+
CanonicalVarKind::PlaceholderTy(ty::UniverseIndex::ROOT)
356+
}
362357
CanonicalizeMode::Response { .. } => panic!("param ty in response: {t:?}"),
363358
},
364359
ty::Bool
@@ -454,7 +449,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
454449
if max_input_universe.can_name(placeholder.universe()) {
455450
panic!("new placeholder in universe {max_input_universe:?}: {r:?}");
456451
}
457-
CanonicalVarKind::PlaceholderRegion(placeholder)
452+
CanonicalVarKind::PlaceholderRegion(placeholder.universe())
458453
}
459454
},
460455

@@ -503,18 +498,13 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
503498
}
504499
ty::InferConst::Fresh(_) => todo!(),
505500
},
506-
ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
507-
CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderConst(
508-
PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
509-
),
510-
CanonicalizeMode::Response { .. } => {
511-
CanonicalVarKind::PlaceholderConst(placeholder)
512-
}
513-
},
501+
ty::ConstKind::Placeholder(placeholder) => {
502+
CanonicalVarKind::PlaceholderConst(placeholder.universe())
503+
}
514504
ty::ConstKind::Param(_) => match self.canonicalize_mode {
515-
CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderConst(
516-
PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
517-
),
505+
CanonicalizeMode::Input { .. } => {
506+
CanonicalVarKind::PlaceholderConst(ty::UniverseIndex::ROOT)
507+
}
518508
CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"),
519509
},
520510
// FIXME: See comment above -- we could fold the region separately or something.

‎compiler/rustc_next_trait_solver/src/delegate.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,20 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
5959
where
6060
V: TypeFoldable<Self::Interner>;
6161

62-
fn instantiate_canonical_var_with_infer(
62+
fn instantiate_existential_canonical_var(
6363
&self,
64-
kind: ty::CanonicalVarKind<Self::Interner>,
64+
kind: ty::CanonicalVarKind,
6565
span: <Self::Interner as Interner>::Span,
6666
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
6767
) -> <Self::Interner as Interner>::GenericArg;
68+
fn instantiate_canonical_var(
69+
&self,
70+
at_index: usize,
71+
kind: ty::CanonicalVarKind,
72+
span: <Self::Interner as Interner>::Span,
73+
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
74+
) -> <Self::Interner as Interner>::GenericArg;
75+
6876
fn add_item_bounds_for_hidden_type(
6977
&self,
7078
def_id: <Self::Interner as Interner>::DefId,

‎compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ where
365365
// A variable from inside a binder of the query. While ideally these shouldn't
366366
// exist at all (see the FIXME at the start of this method), we have to deal with
367367
// them for now.
368-
delegate.instantiate_canonical_var_with_infer(var_kind, span, |idx| {
368+
delegate.instantiate_canonical_var(index, var_kind, span, |idx| {
369369
prev_universe + idx.index()
370370
})
371371
} else if var_kind.is_existential() {
@@ -379,13 +379,14 @@ where
379379
if let Some(v) = opt_values[ty::BoundVar::from_usize(index)] {
380380
v
381381
} else {
382-
delegate
383-
.instantiate_canonical_var_with_infer(var_kind, span, |_| prev_universe)
382+
delegate.instantiate_existential_canonical_var(var_kind, span, |_| {
383+
prev_universe
384+
})
384385
}
385386
} else {
386387
// For placeholders which were already part of the input, we simply map this
387388
// universal bound variable back the placeholder of the input.
388-
original_values[var_kind.expect_placeholder_index()]
389+
opt_values[ty::BoundVar::from_usize(index)].unwrap()
389390
}
390391
}),
391392
);

‎compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,22 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
188188
canonical.instantiate(self.tcx, &values)
189189
}
190190

191-
fn instantiate_canonical_var_with_infer(
191+
fn instantiate_existential_canonical_var(
192192
&self,
193-
kind: CanonicalVarKind<'tcx>,
193+
kind: CanonicalVarKind,
194194
span: Span,
195195
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
196196
) -> ty::GenericArg<'tcx> {
197-
self.0.instantiate_canonical_var(span, kind, universe_map)
197+
self.0.instantiate_existential_canonical_var(span, kind, universe_map)
198+
}
199+
fn instantiate_canonical_var(
200+
&self,
201+
at_index: usize,
202+
kind: CanonicalVarKind,
203+
span: Span,
204+
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
205+
) -> ty::GenericArg<'tcx> {
206+
self.0.instantiate_canonical_var(span, at_index, kind, universe_map)
198207
}
199208

200209
fn add_item_bounds_for_hidden_type(

‎compiler/rustc_type_ir/src/canonical.rs

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -88,42 +88,42 @@ impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
8888
/// canonical value. This is sufficient information for code to create
8989
/// a copy of the canonical value in some other inference context,
9090
/// with fresh inference variables replacing the canonical values.
91-
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
91+
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
9292
#[cfg_attr(
9393
feature = "nightly",
9494
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
9595
)]
96-
pub enum CanonicalVarKind<I: Interner> {
96+
pub enum CanonicalVarKind {
9797
/// Some kind of type inference variable.
9898
Ty(CanonicalTyVarKind),
9999

100100
/// A "placeholder" that represents "any type".
101-
PlaceholderTy(I::PlaceholderTy),
101+
PlaceholderTy(UniverseIndex),
102102

103103
/// Region variable `'?R`.
104104
Region(UniverseIndex),
105105

106106
/// A "placeholder" that represents "any region". Created when you
107107
/// are solving a goal like `for<'a> T: Foo<'a>` to represent the
108108
/// bound region `'a`.
109-
PlaceholderRegion(I::PlaceholderRegion),
109+
PlaceholderRegion(UniverseIndex),
110110

111111
/// Some kind of const inference variable.
112112
Const(UniverseIndex),
113113

114114
/// A "placeholder" that represents "any const".
115-
PlaceholderConst(I::PlaceholderConst),
115+
PlaceholderConst(UniverseIndex),
116116
}
117117

118-
impl<I: Interner> CanonicalVarKind<I> {
118+
impl CanonicalVarKind {
119119
pub fn universe(self) -> UniverseIndex {
120120
match self {
121-
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui,
122-
CanonicalVarKind::Region(ui) => ui,
123-
CanonicalVarKind::Const(ui) => ui,
124-
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
125-
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
126-
CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe(),
121+
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
122+
| CanonicalVarKind::Region(ui)
123+
| CanonicalVarKind::Const(ui)
124+
| CanonicalVarKind::PlaceholderTy(ui)
125+
| CanonicalVarKind::PlaceholderRegion(ui)
126+
| CanonicalVarKind::PlaceholderConst(ui) => ui,
127127
CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => {
128128
UniverseIndex::ROOT
129129
}
@@ -134,23 +134,16 @@ impl<I: Interner> CanonicalVarKind<I> {
134134
///
135135
/// In case this is a float or int variable, this causes an ICE if
136136
/// the updated universe is not the root.
137-
pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind<I> {
137+
pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind {
138138
match self {
139139
CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => {
140140
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
141141
}
142142
CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
143143
CanonicalVarKind::Const(_) => CanonicalVarKind::Const(ui),
144-
145-
CanonicalVarKind::PlaceholderTy(placeholder) => {
146-
CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui))
147-
}
148-
CanonicalVarKind::PlaceholderRegion(placeholder) => {
149-
CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui))
150-
}
151-
CanonicalVarKind::PlaceholderConst(placeholder) => {
152-
CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui))
153-
}
144+
CanonicalVarKind::PlaceholderTy(_) => CanonicalVarKind::PlaceholderTy(ui),
145+
CanonicalVarKind::PlaceholderRegion(_) => CanonicalVarKind::PlaceholderRegion(ui),
146+
CanonicalVarKind::PlaceholderConst(_) => CanonicalVarKind::PlaceholderConst(ui),
154147
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
155148
assert_eq!(ui, UniverseIndex::ROOT);
156149
self
@@ -178,18 +171,6 @@ impl<I: Interner> CanonicalVarKind<I> {
178171
| CanonicalVarKind::PlaceholderConst(_) => false,
179172
}
180173
}
181-
182-
pub fn expect_placeholder_index(self) -> usize {
183-
match self {
184-
CanonicalVarKind::Ty(_) | CanonicalVarKind::Region(_) | CanonicalVarKind::Const(_) => {
185-
panic!("expected placeholder: {self:?}")
186-
}
187-
188-
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
189-
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
190-
CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.var().as_usize(),
191-
}
192-
}
193174
}
194175

195176
/// Rust actually has more than one category of type variables;

‎compiler/rustc_type_ir/src/inherent.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,9 +527,11 @@ pub trait IntoKind {
527527
}
528528

529529
pub trait BoundVarLike<I: Interner> {
530+
fn new_anon(var: ty::BoundVar) -> Self;
531+
530532
fn var(self) -> ty::BoundVar;
531533

532-
fn assert_eq(self, var: I::BoundVarKind);
534+
fn assert_eq(self, kinid: I::BoundVarKind);
533535
}
534536

535537
pub trait ParamLike {

‎compiler/rustc_type_ir/src/interner.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,9 @@ pub trait Interner:
6868
+ Debug
6969
+ Hash
7070
+ Eq
71-
+ SliceLike<Item = ty::CanonicalVarKind<Self>>
71+
+ SliceLike<Item = ty::CanonicalVarKind>
7272
+ Default;
73-
fn mk_canonical_var_kinds(
74-
self,
75-
kinds: &[ty::CanonicalVarKind<Self>],
76-
) -> Self::CanonicalVarKinds;
73+
fn mk_canonical_var_kinds(self, kinds: &[ty::CanonicalVarKind]) -> Self::CanonicalVarKinds;
7774

7875
type ExternalConstraints: Copy
7976
+ Debug

‎compiler/rustc_type_ir/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ rustc_index::newtype_index! {
386386
}
387387

388388
impl<I: Interner> inherent::BoundVarLike<I> for BoundVar {
389+
fn new_anon(var: BoundVar) -> Self {
390+
var
391+
}
392+
389393
fn var(self) -> BoundVar {
390394
self
391395
}

‎tests/ui/traits/const-traits/const-impl-trait.stderr

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
8989
note: `PartialEq` can't be used with `~const` because it isn't annotated with `#[const_trait]`
9090
--> $SRC_DIR/core/src/cmp.rs:LL:COL
9191

92+
error[E0792]: expected generic type parameter, found `_`
93+
--> $DIR/const-impl-trait.rs:15:1
94+
|
95+
LL | / const fn wrap(
96+
LL | | x: impl ~const PartialEq + ~const Destruct,
97+
| | --------------------------------------- this generic parameter must be used with a generic type parameter
98+
LL | | ) -> impl ~const PartialEq + ~const Destruct {
99+
| |____________________________________________^
100+
92101
error: `~const` can only be applied to `#[const_trait]` traits
93102
--> $DIR/const-impl-trait.rs:27:22
94103
|
@@ -191,7 +200,7 @@ LL | a == a
191200
|
192201
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
193202

194-
error: aborting due to 21 previous errors
203+
error: aborting due to 22 previous errors
195204

196-
Some errors have detailed explanations: E0015, E0635.
205+
Some errors have detailed explanations: E0015, E0635, E0792.
197206
For more information about an error, try `rustc --explain E0015`.

‎tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.bad.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ LL | #![feature(non_lifetime_binders)]
77
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
error[E0310]: the placeholder type `!1_"T"` may not live long enough
10+
error[E0310]: the placeholder type `!1_1` may not live long enough
1111
--> $DIR/placeholders-dont-outlive-static.rs:13:5
1212
|
1313
LL | foo();
1414
| ^^^^^
1515
| |
16-
| the placeholder type `!1_"T"` must be valid for the static lifetime...
17-
| ...so that the type `T` will meet its required lifetime bounds
16+
| the placeholder type `!1_1` must be valid for the static lifetime...
17+
| ...so that the type `!1_1` will meet its required lifetime bounds
1818
|
1919
help: consider adding an explicit lifetime bound
2020
|
21-
LL | fn bad() where !1_"T": 'static {
22-
| +++++++++++++++++++++
21+
LL | fn bad() where !1_1: 'static {
22+
| +++++++++++++++++++
2323

2424
error: aborting due to 1 previous error; 1 warning emitted
2525

‎tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.good.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ LL | #![feature(non_lifetime_binders)]
77
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
error[E0310]: the placeholder type `!1_"T"` may not live long enough
10+
error[E0310]: the placeholder type `!1_1` may not live long enough
1111
--> $DIR/placeholders-dont-outlive-static.rs:19:5
1212
|
1313
LL | foo();
1414
| ^^^^^
1515
| |
16-
| the placeholder type `!1_"T"` must be valid for the static lifetime...
17-
| ...so that the type `T` will meet its required lifetime bounds
16+
| the placeholder type `!1_1` must be valid for the static lifetime...
17+
| ...so that the type `!1_1` will meet its required lifetime bounds
1818
|
1919
help: consider adding an explicit lifetime bound
2020
|
21-
LL | fn good() where for<T> T: 'static, !1_"T": 'static {
22-
| +++++++++++++++++
21+
LL | fn good() where for<T> T: 'static, !1_1: 'static {
22+
| +++++++++++++++
2323

2424
error: aborting due to 1 previous error; 1 warning emitted
2525

‎tests/ui/traits/non_lifetime_binders/placeholders-dont-outlive-static.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn foo() where for<T> T: 'static {}
1111
#[cfg(bad)]
1212
fn bad() {
1313
foo();
14-
//[bad]~^ ERROR the placeholder type `!1_"T"` may not live long enough
14+
//[bad]~^ ERROR the placeholder type `!1_1` may not live long enough
1515
}
1616

1717
#[cfg(good)]

‎tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,19 @@ help: consider adding an explicit lifetime bound
2828
LL | for<F> F: 'a, !1_"F": 'a
2929
| ++++++++++
3030

31-
error[E0309]: the placeholder type `!1_"F"` may not live long enough
31+
error[E0309]: the placeholder type `!1_2` may not live long enough
3232
--> $DIR/type-match-with-late-bound.rs:11:1
3333
|
3434
LL | async fn walk2<'a, T: 'a>(_: T)
35-
| -- the placeholder type `!1_"F"` must be valid for the lifetime `'a` as defined here...
35+
| -- the placeholder type `!1_2` must be valid for the lifetime `'a` as defined here...
3636
...
3737
LL | {}
38-
| ^^ ...so that the type `F` will meet its required lifetime bounds
38+
| ^^ ...so that the type `!1_2` will meet its required lifetime bounds
3939
|
4040
help: consider adding an explicit lifetime bound
4141
|
42-
LL | for<F> F: 'a, !1_"F": 'a
43-
| ++++++++++
42+
LL | for<F> F: 'a, !1_2: 'a
43+
| ++++++++
4444

4545
error[E0309]: the placeholder type `!2_"F"` may not live long enough
4646
--> $DIR/type-match-with-late-bound.rs:11:1
Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
1-
error[E0308]: mismatched types
1+
error: higher-ranked lifetime error
22
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
33
|
44
LL | x
5-
| ^ one type is more general than the other
5+
| ^
66
|
7-
= note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
8-
found existential trait ref `for<'a> Supertrait<'a, 'a>`
7+
= note: could not prove `&'c (dyn for<'a> Subtrait<'a, 'a> + 'd): CoerceUnsized<&'e (dyn for<'a, 'b> Supertrait<'a, 'b> + 'f)>`
98

10-
error[E0308]: mismatched types
9+
error: higher-ranked lifetime error
1110
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
1211
|
1312
LL | x
14-
| ^ one type is more general than the other
13+
| ^
1514
|
16-
= note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
17-
found existential trait ref `for<'a> Supertrait<'a, 'a>`
15+
= note: could not prove `&'c (dyn for<'a> Subtrait<'a, 'a> + 'd): CoerceUnsized<&'e (dyn for<'a, 'b> Supertrait<'a, 'b> + 'f)>`
1816
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
1917

2018
error: aborting due to 2 previous errors
2119

22-
For more information about this error, try `rustc --explain E0308`.

‎tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ impl<'a> Supertrait<'a, 'a> for () {
1919
}
2020
impl<'a> Subtrait<'a, 'a> for () {}
2121
fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> {
22-
x //~ ERROR mismatched types
23-
//[current]~^ ERROR mismatched types
22+
x //[next]~ ERROR mismatched types
23+
//[current]~^ ERROR higher-ranked lifetime error
24+
//[current]~| ERROR higher-ranked lifetime error
2425
}
2526

2627
fn transmute<'a, 'b>(x: &'a str) -> &'b str {

0 commit comments

Comments
 (0)
Please sign in to comment.