Skip to content

Commit

Permalink
Auto merge of rust-lang#130194 - lcnr:generalize-cache, r=compiler-er…
Browse files Browse the repository at this point in the history
…rors

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`
  • Loading branch information
bors committed Sep 11, 2024
2 parents 4c5fc2c + 7a57a74 commit 5a2dd7d
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 16 deletions.
18 changes: 9 additions & 9 deletions compiler/rustc_infer/src/infer/relate/generalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down Expand Up @@ -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.
///
Expand All @@ -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,
}
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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)
}

Expand Down
6 changes: 4 additions & 2 deletions tests/ui/const-generics/occurs-check/unused-substs-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

}
8 changes: 3 additions & 5 deletions tests/ui/const-generics/occurs-check/unused-substs-3.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down

0 comments on commit 5a2dd7d

Please sign in to comment.