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,
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue