mirror of https://github.com/rust-lang/rust.git
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:
commit
5a2dd7d4f3
|
@ -259,11 +259,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
structurally_relate_aliases,
|
structurally_relate_aliases,
|
||||||
root_vid,
|
root_vid,
|
||||||
for_universe,
|
for_universe,
|
||||||
ambient_variance,
|
|
||||||
root_term: source_term.into(),
|
root_term: source_term.into(),
|
||||||
|
ambient_variance,
|
||||||
in_alias: false,
|
in_alias: false,
|
||||||
has_unconstrained_ty_var: false,
|
|
||||||
cache: Default::default(),
|
cache: Default::default(),
|
||||||
|
has_unconstrained_ty_var: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let value_may_be_infer = generalizer.relate(source_term, source_term)?;
|
let value_may_be_infer = generalizer.relate(source_term, source_term)?;
|
||||||
|
@ -304,14 +304,12 @@ struct Generalizer<'me, 'tcx> {
|
||||||
/// we reject the relation.
|
/// we reject the relation.
|
||||||
for_universe: ty::UniverseIndex,
|
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.
|
/// The root term (const or type) we're generalizing. Used for cycle errors.
|
||||||
root_term: Term<'tcx>,
|
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.
|
/// 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.
|
/// hold by either normalizing the outer or the inner associated type.
|
||||||
in_alias: bool,
|
in_alias: bool,
|
||||||
|
|
||||||
|
cache: SsoHashMap<(Ty<'tcx>, ty::Variance, bool), Ty<'tcx>>,
|
||||||
|
|
||||||
/// See the field `has_unconstrained_ty_var` in `Generalization`.
|
/// See the field `has_unconstrained_ty_var` in `Generalization`.
|
||||||
has_unconstrained_ty_var: bool,
|
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>> {
|
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 ==
|
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);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +557,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
||||||
_ => relate::structurally_relate_tys(self, t, t),
|
_ => 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)
|
Ok(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,11 @@ fn bind<T>() -> (T, [u8; 6 + 1]) {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (mut t, foo) = bind();
|
let (mut t, foo) = bind();
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| NOTE cyclic type
|
||||||
|
|
||||||
// `t` is `ty::Infer(TyVar(?1t))`
|
// `t` is `ty::Infer(TyVar(?1t))`
|
||||||
// `foo` contains `ty::Infer(TyVar(?1t))` in its substs
|
// `foo` contains `ty::Infer(TyVar(?1t))` in its substs
|
||||||
t = foo;
|
t = foo;
|
||||||
//~^ ERROR mismatched types
|
|
||||||
//~| NOTE cyclic type
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/unused-substs-3.rs:16:9
|
--> $DIR/unused-substs-3.rs:13:24
|
||||||
|
|
|
|
||||||
LL | t = foo;
|
LL | let (mut t, foo) = bind();
|
||||||
| ^^^- help: try using a conversion method: `.to_vec()`
|
| ^^^^^^ cyclic type of infinite size
|
||||||
| |
|
|
||||||
| cyclic type of infinite size
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue