Skip to content

Commit 16adb60

Browse files
committed
Auto merge of #141432 - lcnr:canonicalize-regions, r=<try>
refactor `CanonicalVarKind` it's unnecessary. I don't believe we'll ever need to store additional info shared by all `CanonicalVarKind`s. r? `@compiler-errors`
2 parents 52bf0cf + 05d9393 commit 16adb60

29 files changed

+344
-349
lines changed

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

Lines changed: 48 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ use tracing::debug;
1717

1818
use crate::infer::InferCtxt;
1919
use crate::infer::canonical::{
20-
Canonical, CanonicalQueryInput, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind,
21-
OriginalQueryValues,
20+
Canonical, CanonicalQueryInput, CanonicalTyVarKind, CanonicalVarKind, OriginalQueryValues,
2221
};
2322

2423
impl<'tcx> InferCtxt<'tcx> {
@@ -175,7 +174,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
175174
ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r,
176175

177176
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
178-
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) },
177+
CanonicalVarKind::PlaceholderRegion(placeholder.universe),
179178
r,
180179
),
181180

@@ -186,10 +185,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
186185
.unwrap_region_constraints()
187186
.probe_value(vid)
188187
.unwrap_err();
189-
canonicalizer.canonical_var_for_region(
190-
CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) },
191-
r,
192-
)
188+
canonicalizer.canonical_var_for_region(CanonicalVarKind::Region(universe), r)
193189
}
194190

195191
_ => {
@@ -294,7 +290,7 @@ struct Canonicalizer<'cx, 'tcx> {
294290
/// Set to `None` to disable the resolution of inference variables.
295291
infcx: Option<&'cx InferCtxt<'tcx>>,
296292
tcx: TyCtxt<'tcx>,
297-
variables: SmallVec<[CanonicalVarInfo<'tcx>; 8]>,
293+
variables: SmallVec<[CanonicalVarKind; 8]>,
298294
query_state: &'cx mut OriginalQueryValues<'tcx>,
299295
// Note that indices is only used once `var_values` is big enough to be
300296
// heap-allocated.
@@ -368,9 +364,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
368364
ui = ty::UniverseIndex::ROOT;
369365
}
370366
self.canonicalize_ty_var(
371-
CanonicalVarInfo {
372-
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
373-
},
367+
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
374368
t,
375369
)
376370
}
@@ -382,36 +376,29 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
382376
if nt != t {
383377
return self.fold_ty(nt);
384378
} else {
385-
self.canonicalize_ty_var(
386-
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
387-
t,
388-
)
379+
self.canonicalize_ty_var(CanonicalVarKind::Ty(CanonicalTyVarKind::Int), t)
389380
}
390381
}
391382
ty::Infer(ty::FloatVar(vid)) => {
392383
let nt = self.infcx.unwrap().opportunistic_resolve_float_var(vid);
393384
if nt != t {
394385
return self.fold_ty(nt);
395386
} else {
396-
self.canonicalize_ty_var(
397-
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
398-
t,
399-
)
387+
self.canonicalize_ty_var(CanonicalVarKind::Ty(CanonicalTyVarKind::Float), t)
400388
}
401389
}
402390

403391
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
404392
bug!("encountered a fresh type during canonicalization")
405393
}
406394

407-
ty::Placeholder(mut placeholder) => {
408-
if !self.canonicalize_mode.preserve_universes() {
409-
placeholder.universe = ty::UniverseIndex::ROOT;
410-
}
411-
self.canonicalize_ty_var(
412-
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) },
413-
t,
414-
)
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)
415402
}
416403

417404
ty::Bound(debruijn, _) => {
@@ -483,10 +470,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
483470
// FIXME: perf problem described in #55921.
484471
ui = ty::UniverseIndex::ROOT;
485472
}
486-
return self.canonicalize_const_var(
487-
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
488-
ct,
489-
);
473+
return self.canonicalize_const_var(CanonicalVarKind::Const(ui), ct);
490474
}
491475
}
492476
}
@@ -501,10 +485,13 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
501485
}
502486
}
503487
ty::ConstKind::Placeholder(placeholder) => {
504-
return self.canonicalize_const_var(
505-
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) },
506-
ct,
507-
);
488+
let universe = if self.canonicalize_mode.preserve_universes() {
489+
placeholder.universe
490+
} else {
491+
ty::UniverseIndex::ROOT
492+
};
493+
return self
494+
.canonicalize_const_var(CanonicalVarKind::PlaceholderConst(universe), ct);
508495
}
509496
_ => {}
510497
}
@@ -595,7 +582,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
595582
debug_assert!(!out_value.has_infer() && !out_value.has_placeholders());
596583

597584
let canonical_variables =
598-
tcx.mk_canonical_var_infos(&canonicalizer.universe_canonicalized_variables());
585+
tcx.mk_canonical_var_kinds(&canonicalizer.universe_canonicalized_variables());
599586

600587
let max_universe = canonical_variables
601588
.iter()
@@ -610,7 +597,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
610597
/// or returns an existing variable if `kind` has already been
611598
/// seen. `kind` is expected to be an unbound variable (or
612599
/// potentially a free region).
613-
fn canonical_var(&mut self, info: CanonicalVarInfo<'tcx>, kind: GenericArg<'tcx>) -> BoundVar {
600+
fn canonical_var(&mut self, info: CanonicalVarKind, kind: GenericArg<'tcx>) -> BoundVar {
614601
let Canonicalizer { variables, query_state, indices, .. } = self;
615602

616603
let var_values = &mut query_state.var_values;
@@ -673,7 +660,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
673660
/// Replaces the universe indexes used in `var_values` with their index in
674661
/// `query_state.universe_map`. This minimizes the maximum universe used in
675662
/// the canonicalized value.
676-
fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarInfo<'tcx>; 8]> {
663+
fn universe_canonicalized_variables(self) -> SmallVec<[CanonicalVarKind; 8]> {
677664
if self.query_state.universe_map.len() == 1 {
678665
return self.variables;
679666
}
@@ -688,37 +675,24 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
688675

689676
self.variables
690677
.iter()
691-
.map(|v| CanonicalVarInfo {
692-
kind: match v.kind {
693-
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
694-
return *v;
695-
}
696-
CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
697-
CanonicalVarKind::Ty(CanonicalTyVarKind::General(reverse_universe_map[&u]))
698-
}
699-
CanonicalVarKind::Region(u) => {
700-
CanonicalVarKind::Region(reverse_universe_map[&u])
701-
}
702-
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
703-
CanonicalVarKind::PlaceholderTy(placeholder) => {
704-
CanonicalVarKind::PlaceholderTy(ty::Placeholder {
705-
universe: reverse_universe_map[&placeholder.universe],
706-
..placeholder
707-
})
708-
}
709-
CanonicalVarKind::PlaceholderRegion(placeholder) => {
710-
CanonicalVarKind::PlaceholderRegion(ty::Placeholder {
711-
universe: reverse_universe_map[&placeholder.universe],
712-
..placeholder
713-
})
714-
}
715-
CanonicalVarKind::PlaceholderConst(placeholder) => {
716-
CanonicalVarKind::PlaceholderConst(ty::Placeholder {
717-
universe: reverse_universe_map[&placeholder.universe],
718-
..placeholder
719-
})
720-
}
721-
},
678+
.map(|&kind| match kind {
679+
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
680+
return kind;
681+
}
682+
CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
683+
CanonicalVarKind::Ty(CanonicalTyVarKind::General(reverse_universe_map[&u]))
684+
}
685+
CanonicalVarKind::Region(u) => CanonicalVarKind::Region(reverse_universe_map[&u]),
686+
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
687+
CanonicalVarKind::PlaceholderTy(ui) => {
688+
CanonicalVarKind::PlaceholderTy(reverse_universe_map[&ui])
689+
}
690+
CanonicalVarKind::PlaceholderRegion(ui) => {
691+
CanonicalVarKind::PlaceholderRegion(reverse_universe_map[&ui])
692+
}
693+
CanonicalVarKind::PlaceholderConst(ui) => {
694+
CanonicalVarKind::PlaceholderConst(reverse_universe_map[&ui])
695+
}
722696
})
723697
.collect()
724698
}
@@ -740,17 +714,14 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
740714
&mut self,
741715
r: ty::Region<'tcx>,
742716
) -> ty::Region<'tcx> {
743-
self.canonical_var_for_region(
744-
CanonicalVarInfo { kind: CanonicalVarKind::Region(ty::UniverseIndex::ROOT) },
745-
r,
746-
)
717+
self.canonical_var_for_region(CanonicalVarKind::Region(ty::UniverseIndex::ROOT), r)
747718
}
748719

749720
/// Creates a canonical variable (with the given `info`)
750721
/// representing the region `r`; return a region referencing it.
751722
fn canonical_var_for_region(
752723
&mut self,
753-
info: CanonicalVarInfo<'tcx>,
724+
info: CanonicalVarKind,
754725
r: ty::Region<'tcx>,
755726
) -> ty::Region<'tcx> {
756727
let var = self.canonical_var(info, r.into());
@@ -762,10 +733,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
762733
/// if `ty_var` is bound to anything; if so, canonicalize
763734
/// *that*. Otherwise, create a new canonical variable for
764735
/// `ty_var`.
765-
fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo<'tcx>, ty_var: Ty<'tcx>) -> Ty<'tcx> {
736+
fn canonicalize_ty_var(&mut self, info: CanonicalVarKind, ty_var: Ty<'tcx>) -> Ty<'tcx> {
766737
debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
767738
let var = self.canonical_var(info, ty_var.into());
768-
Ty::new_bound(self.tcx, self.binder_index, var.into())
739+
Ty::new_bound(self.tcx, self.binder_index, ty::BoundTy::new_anon(var))
769740
}
770741

771742
/// Given a type variable `const_var` of the given kind, first check
@@ -774,7 +745,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
774745
/// `const_var`.
775746
fn canonicalize_const_var(
776747
&mut self,
777-
info: CanonicalVarInfo<'tcx>,
748+
info: CanonicalVarKind,
778749
const_var: ty::Const<'tcx>,
779750
) -> ty::Const<'tcx> {
780751
debug_assert!(

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

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -81,33 +81,30 @@ impl<'tcx> InferCtxt<'tcx> {
8181
fn instantiate_canonical_vars(
8282
&self,
8383
span: Span,
84-
variables: &List<CanonicalVarInfo<'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(|info| self.instantiate_canonical_var(span, info, &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-
cv_info: CanonicalVarInfo<'tcx>,
104+
kind: CanonicalVarKind,
108105
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
109106
) -> GenericArg<'tcx> {
110-
match cv_info.kind {
107+
match kind {
111108
CanonicalVarKind::Ty(ty_kind) => {
112109
let ty = match ty_kind {
113110
CanonicalTyVarKind::General(ui) => {
@@ -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
}

0 commit comments

Comments
 (0)