Auto merge of #130194 - lcnr:generalize-cache, r=compiler-errors

generalize: track relevant info in cache key

This was previously theoretically incomplete as we could incorrectly generalize as if the type was in an invariant context even though we're in a covariant one. Similar with the `in_alias` flag.

r? `@compiler-errors`
This commit is contained in:
bors 2024-09-11 07:17:12 +00:00
commit 5a2dd7d4f3
3 changed files with 16 additions and 16 deletions

View File

@ -259,11 +259,11 @@ impl<'tcx> InferCtxt<'tcx> {
structurally_relate_aliases,
root_vid,
for_universe,
ambient_variance,
root_term: source_term.into(),
ambient_variance,
in_alias: false,
has_unconstrained_ty_var: false,
cache: Default::default(),
has_unconstrained_ty_var: false,
};
let value_may_be_infer = generalizer.relate(source_term, source_term)?;
@ -304,14 +304,12 @@ struct Generalizer<'me, 'tcx> {
/// we reject the relation.
for_universe: ty::UniverseIndex,
/// After we generalize this type, we are going to relate it to
/// some other type. What will be the variance at this point?
ambient_variance: ty::Variance,
/// The root term (const or type) we're generalizing. Used for cycle errors.
root_term: Term<'tcx>,
cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
/// After we generalize this type, we are going to relate it to
/// some other type. What will be the variance at this point?
ambient_variance: ty::Variance,
/// This is set once we're generalizing the arguments of an alias.
///
@ -320,6 +318,8 @@ struct Generalizer<'me, 'tcx> {
/// hold by either normalizing the outer or the inner associated type.
in_alias: bool,
cache: SsoHashMap<(Ty<'tcx>, ty::Variance, bool), Ty<'tcx>>,
/// See the field `has_unconstrained_ty_var` in `Generalization`.
has_unconstrained_ty_var: bool,
}
@ -451,7 +451,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
assert_eq!(t, t2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
if let Some(&result) = self.cache.get(&t) {
if let Some(&result) = self.cache.get(&(t, self.ambient_variance, self.in_alias)) {
return Ok(result);
}
@ -557,7 +557,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
_ => relate::structurally_relate_tys(self, t, t),
}?;
self.cache.insert(t, g);
self.cache.insert((t, self.ambient_variance, self.in_alias), g);
Ok(g)
}

View File

@ -11,9 +11,11 @@ fn bind<T>() -> (T, [u8; 6 + 1]) {
fn main() {
let (mut t, foo) = bind();
//~^ ERROR mismatched types
//~| NOTE cyclic type
// `t` is `ty::Infer(TyVar(?1t))`
// `foo` contains `ty::Infer(TyVar(?1t))` in its substs
t = foo;
//~^ ERROR mismatched types
//~| NOTE cyclic type
}

View File

@ -1,10 +1,8 @@
error[E0308]: mismatched types
--> $DIR/unused-substs-3.rs:16:9
--> $DIR/unused-substs-3.rs:13:24
|
LL | t = foo;
| ^^^- help: try using a conversion method: `.to_vec()`
| |
| cyclic type of infinite size
LL | let (mut t, foo) = bind();
| ^^^^^^ cyclic type of infinite size
error: aborting due to 1 previous error