Skip to content

Commit fea82c9

Browse files
committed
yeet GeneralizerDelegate
1 parent 5c54004 commit fea82c9

File tree

1 file changed

+51
-125
lines changed

1 file changed

+51
-125
lines changed

compiler/rustc_infer/src/infer/relate/generalize.rs

+51-125
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::mem;
22

3-
use crate::infer::nll_relate::TypeRelatingDelegate;
43
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind, TypeVariableValue};
54
use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin};
65
use rustc_data_structures::sso::SsoHashMap;
@@ -43,13 +42,7 @@ impl<'tcx> InferCtxt<'tcx> {
4342
//
4443
// We then relate `generalized_ty <: source_ty`,adding constraints like `'x: '?2` and `?1 <: ?3`.
4544
let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } =
46-
generalize(
47-
self,
48-
&mut CombineDelegate { infcx: self, span: relation.span() },
49-
source_ty,
50-
target_vid,
51-
ambient_variance,
52-
)?;
45+
self.generalize(relation.span(), target_vid, ambient_variance, source_ty)?;
5346

5447
// Constrain `b_vid` to the generalized type `generalized_ty`.
5548
if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() {
@@ -180,13 +173,7 @@ impl<'tcx> InferCtxt<'tcx> {
180173
// FIXME(generic_const_exprs): Occurs check failures for unevaluated
181174
// constants and generic expressions are not yet handled correctly.
182175
let Generalization { value_may_be_infer: generalized_ct, has_unconstrained_ty_var } =
183-
generalize(
184-
self,
185-
&mut CombineDelegate { infcx: self, span },
186-
source_ct,
187-
target_vid,
188-
ty::Variance::Invariant,
189-
)?;
176+
self.generalize(span, target_vid, ty::Variance::Invariant, source_ct)?;
190177

191178
debug_assert!(!generalized_ct.is_ct_infer());
192179
if has_unconstrained_ty_var {
@@ -202,93 +189,45 @@ impl<'tcx> InferCtxt<'tcx> {
202189
// `generalized_ct` and `source_ct` here.`
203190
Ok(generalized_ct)
204191
}
205-
}
206-
207-
/// Attempts to generalize `term` for the type variable `for_vid`.
208-
/// This checks for cycles -- that is, whether the type `term`
209-
/// references `for_vid`.
210-
pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
211-
infcx: &InferCtxt<'tcx>,
212-
delegate: &mut D,
213-
term: T,
214-
for_vid: impl Into<ty::TermVid>,
215-
ambient_variance: ty::Variance,
216-
) -> RelateResult<'tcx, Generalization<T>> {
217-
let (for_universe, root_vid) = match for_vid.into() {
218-
ty::TermVid::Ty(ty_vid) => (
219-
infcx.probe_ty_var(ty_vid).unwrap_err(),
220-
ty::TermVid::Ty(infcx.inner.borrow_mut().type_variables().sub_root_var(ty_vid)),
221-
),
222-
ty::TermVid::Const(ct_vid) => (
223-
infcx.probe_const_var(ct_vid).unwrap_err(),
224-
ty::TermVid::Const(infcx.inner.borrow_mut().const_unification_table().find(ct_vid).vid),
225-
),
226-
};
227-
228-
let mut generalizer = Generalizer {
229-
infcx,
230-
delegate,
231-
ambient_variance,
232-
root_vid,
233-
for_universe,
234-
root_term: term.into(),
235-
in_alias: false,
236-
has_unconstrained_ty_var: false,
237-
cache: Default::default(),
238-
};
239-
240-
assert!(!term.has_escaping_bound_vars());
241-
let value_may_be_infer = generalizer.relate(term, term)?;
242-
let has_unconstrained_ty_var = generalizer.has_unconstrained_ty_var;
243-
Ok(Generalization { value_may_be_infer, has_unconstrained_ty_var })
244-
}
245-
246-
/// Abstracts the handling of region vars between HIR and MIR/NLL typechecking
247-
/// in the generalizer code.
248-
pub trait GeneralizerDelegate<'tcx> {
249-
fn forbid_inference_vars() -> bool;
250-
251-
fn span(&self) -> Span;
252-
253-
fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>;
254-
}
255-
256-
pub struct CombineDelegate<'cx, 'tcx> {
257-
pub infcx: &'cx InferCtxt<'tcx>,
258-
pub span: Span,
259-
}
260-
261-
impl<'tcx> GeneralizerDelegate<'tcx> for CombineDelegate<'_, 'tcx> {
262-
fn forbid_inference_vars() -> bool {
263-
false
264-
}
265-
266-
fn span(&self) -> Span {
267-
self.span
268-
}
269-
270-
fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
271-
// FIXME: This is non-ideal because we don't give a
272-
// very descriptive origin for this region variable.
273-
self.infcx
274-
.next_region_var_in_universe(RegionVariableOrigin::MiscVariable(self.span), universe)
275-
}
276-
}
277192

278-
impl<'tcx, T> GeneralizerDelegate<'tcx> for T
279-
where
280-
T: TypeRelatingDelegate<'tcx>,
281-
{
282-
fn forbid_inference_vars() -> bool {
283-
<Self as TypeRelatingDelegate<'tcx>>::forbid_inference_vars()
284-
}
193+
/// Attempts to generalize `source_term` for the type variable `target_vid`.
194+
/// This checks for cycles -- that is, whether `source_term` references `target_vid`.
195+
fn generalize<T: Into<Term<'tcx>> + Relate<'tcx>>(
196+
&self,
197+
span: Span,
198+
target_vid: impl Into<ty::TermVid>,
199+
ambient_variance: ty::Variance,
200+
source_term: T,
201+
) -> RelateResult<'tcx, Generalization<T>> {
202+
assert!(!source_term.has_escaping_bound_vars());
203+
let (for_universe, root_vid) = match target_vid.into() {
204+
ty::TermVid::Ty(ty_vid) => (
205+
self.probe_ty_var(ty_vid).unwrap_err(),
206+
ty::TermVid::Ty(self.inner.borrow_mut().type_variables().sub_root_var(ty_vid)),
207+
),
208+
ty::TermVid::Const(ct_vid) => (
209+
self.probe_const_var(ct_vid).unwrap_err(),
210+
ty::TermVid::Const(
211+
self.inner.borrow_mut().const_unification_table().find(ct_vid).vid,
212+
),
213+
),
214+
};
285215

286-
fn span(&self) -> Span {
287-
<Self as TypeRelatingDelegate<'tcx>>::span(&self)
288-
}
216+
let mut generalizer = Generalizer {
217+
infcx: self,
218+
span,
219+
root_vid,
220+
for_universe,
221+
ambient_variance,
222+
root_term: source_term.into(),
223+
in_alias: false,
224+
has_unconstrained_ty_var: false,
225+
cache: Default::default(),
226+
};
289227

290-
fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
291-
<Self as TypeRelatingDelegate<'tcx>>::generalize_existential(self, universe)
228+
let value_may_be_infer = generalizer.relate(source_term, source_term)?;
229+
let has_unconstrained_ty_var = generalizer.has_unconstrained_ty_var;
230+
Ok(Generalization { value_may_be_infer, has_unconstrained_ty_var })
292231
}
293232
}
294233

@@ -305,18 +244,10 @@ where
305244
/// establishes `'0: 'x` as a constraint.
306245
///
307246
/// [blog post]: https://is.gd/0hKvIr
308-
struct Generalizer<'me, 'tcx, D> {
247+
struct Generalizer<'me, 'tcx> {
309248
infcx: &'me InferCtxt<'tcx>,
310249

311-
/// This is used to abstract the behaviors of the three previous
312-
/// generalizer-like implementations (`Generalizer`, `TypeGeneralizer`,
313-
/// and `ConstInferUnifier`). See [`GeneralizerDelegate`] for more
314-
/// information.
315-
delegate: &'me mut D,
316-
317-
/// After we generalize this type, we are going to relate it to
318-
/// some other type. What will be the variance at this point?
319-
ambient_variance: ty::Variance,
250+
span: Span,
320251

321252
/// The vid of the type variable that is in the process of being
322253
/// instantiated. If we find this within the value we are folding,
@@ -328,6 +259,10 @@ struct Generalizer<'me, 'tcx, D> {
328259
/// we reject the relation.
329260
for_universe: ty::UniverseIndex,
330261

262+
/// After we generalize this type, we are going to relate it to
263+
/// some other type. What will be the variance at this point?
264+
ambient_variance: ty::Variance,
265+
331266
/// The root term (const or type) we're generalizing. Used for cycle errors.
332267
root_term: Term<'tcx>,
333268

@@ -344,7 +279,7 @@ struct Generalizer<'me, 'tcx, D> {
344279
has_unconstrained_ty_var: bool,
345280
}
346281

347-
impl<'tcx, D> Generalizer<'_, 'tcx, D> {
282+
impl<'tcx> Generalizer<'_, 'tcx> {
348283
/// Create an error that corresponds to the term kind in `root_term`
349284
fn cyclic_term_error(&self) -> TypeError<'tcx> {
350285
match self.root_term.unpack() {
@@ -354,10 +289,7 @@ impl<'tcx, D> Generalizer<'_, 'tcx, D> {
354289
}
355290
}
356291

357-
impl<'tcx, D> TypeRelation<'tcx> for Generalizer<'_, 'tcx, D>
358-
where
359-
D: GeneralizerDelegate<'tcx>,
360-
{
292+
impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
361293
fn tcx(&self) -> TyCtxt<'tcx> {
362294
self.infcx.tcx
363295
}
@@ -426,12 +358,6 @@ where
426358
// subtyping. This is basically our "occurs check", preventing
427359
// us from creating infinitely sized types.
428360
let g = match *t.kind() {
429-
ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_))
430-
if D::forbid_inference_vars() =>
431-
{
432-
bug!("unexpected inference variable encountered in NLL generalization: {t}");
433-
}
434-
435361
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
436362
bug!("unexpected infer type: {t}")
437363
}
@@ -534,7 +460,7 @@ where
534460
Ok(self.infcx.next_ty_var_in_universe(
535461
TypeVariableOrigin {
536462
kind: TypeVariableOriginKind::MiscVariable,
537-
span: self.delegate.span(),
463+
span: self.span,
538464
},
539465
self.for_universe,
540466
))
@@ -592,7 +518,10 @@ where
592518
}
593519
}
594520

595-
Ok(self.delegate.generalize_region(self.for_universe))
521+
Ok(self.infcx.next_region_var_in_universe(
522+
RegionVariableOrigin::MiscVariable(self.span),
523+
self.for_universe,
524+
))
596525
}
597526

598527
#[instrument(level = "debug", skip(self, c2), ret)]
@@ -604,9 +533,6 @@ where
604533
assert_eq!(c, c2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
605534

606535
match c.kind() {
607-
ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
608-
bug!("unexpected inference variable encountered in NLL generalization: {:?}", c);
609-
}
610536
ty::ConstKind::Infer(InferConst::Var(vid)) => {
611537
// If root const vids are equal, then `root_vid` and
612538
// `vid` are related and we'd be inferring an infinitely

0 commit comments

Comments
 (0)