Skip to content

Commit dd2e1a3

Browse files
authored
Rollup merge of #126022 - lcnr:generalize-alias-bivariant, r=compiler-errors
set `has_unconstrained_ty_var` when generalizing aliases in bivariant contexts this previously prevented the `regression-31157` benchmark from building r? `@compiler-errors`
2 parents 808ad60 + a8e091d commit dd2e1a3

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,14 @@ impl<'tcx> Generalizer<'_, 'tcx> {
329329
}
330330
}
331331

332+
/// Create a new type variable in the universe of the target when
333+
/// generalizing an alias. This has to set `has_unconstrained_ty_var`
334+
/// if we're currently in a bivariant context.
335+
fn next_ty_var_for_alias(&mut self) -> Ty<'tcx> {
336+
self.has_unconstrained_ty_var |= self.ambient_variance == ty::Bivariant;
337+
self.infcx.next_ty_var_in_universe(self.span, self.for_universe)
338+
}
339+
332340
/// An occurs check failure inside of an alias does not mean
333341
/// that the types definitely don't unify. We may be able
334342
/// to normalize the alias after all.
@@ -358,7 +366,7 @@ impl<'tcx> Generalizer<'_, 'tcx> {
358366
//
359367
// cc trait-system-refactor-initiative#110
360368
if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() && !self.in_alias {
361-
return Ok(self.infcx.next_ty_var_in_universe(self.span, self.for_universe));
369+
return Ok(self.next_ty_var_for_alias());
362370
}
363371

364372
let is_nested_alias = mem::replace(&mut self.in_alias, true);
@@ -378,7 +386,7 @@ impl<'tcx> Generalizer<'_, 'tcx> {
378386
}
379387

380388
debug!("generalization failure in alias");
381-
Ok(self.infcx.next_ty_var_in_universe(self.span, self.for_universe))
389+
Ok(self.next_ty_var_for_alias())
382390
}
383391
}
384392
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ revisions: old next
2+
//@[next] compile-flags: -Znext-solver
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@ check-pass
5+
6+
// When generalizing an alias in a bivariant context, we have to set
7+
// `has_unconstrained_ty_var` as we may otherwise never check for
8+
// well-formedness of the generalized type, causing us to error due
9+
// to ambiguity.
10+
trait Trait {
11+
type Assoc;
12+
}
13+
14+
struct BivariantArg<I, T: Trait<Assoc = I>>(T);
15+
16+
fn generalize<T: Trait>(input: BivariantArg<T::Assoc, T>) {
17+
let _generalized = input;
18+
}
19+
20+
pub fn main() {}

0 commit comments

Comments
 (0)