generalize hr alias: avoid unconstrainable infer vars
This commit is contained in:
parent
31110152e2
commit
690d5aa417
7 changed files with 175 additions and 26 deletions
|
@ -350,7 +350,13 @@ impl<'tcx> Generalizer<'_, 'tcx> {
|
|||
&mut self,
|
||||
alias: ty::AliasTy<'tcx>,
|
||||
) -> Result<Ty<'tcx>, TypeError<'tcx>> {
|
||||
if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() {
|
||||
// We do not eagerly replace aliases with inference variables if they have
|
||||
// escaping bound vars, see the method comment for details. However, when we
|
||||
// are inside of an alias with escaping bound vars replacing nested aliases
|
||||
// with inference variables can cause incorrect ambiguity.
|
||||
//
|
||||
// cc trait-system-refactor-initiative#110
|
||||
if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() && !self.in_alias {
|
||||
return Ok(self.infcx.next_ty_var_in_universe(
|
||||
TypeVariableOrigin { param_def_id: None, span: self.span },
|
||||
self.for_universe,
|
||||
|
@ -492,9 +498,30 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||
let origin = inner.type_variables().var_origin(vid);
|
||||
let new_var_id =
|
||||
inner.type_variables().new_var(self.for_universe, origin);
|
||||
let u = Ty::new_var(self.tcx(), new_var_id);
|
||||
debug!("replacing original vid={:?} with new={:?}", vid, u);
|
||||
Ok(u)
|
||||
// If we're in the new solver and create a new inference
|
||||
// variable inside of an alias we eagerly constrain that
|
||||
// inference variable to prevent unexpected ambiguity errors.
|
||||
//
|
||||
// This is incomplete as it pulls down the universe of the
|
||||
// original inference variable, even though the alias could
|
||||
// normalize to a type which does not refer to that type at
|
||||
// all. I don't expect this to cause unexpected errors in
|
||||
// practice.
|
||||
//
|
||||
// We only need to do so for type and const variables, as
|
||||
// region variables do not impact normalization, and will get
|
||||
// correctly constrained by `AliasRelate` later on.
|
||||
//
|
||||
// cc trait-system-refactor-initiative#108
|
||||
if self.infcx.next_trait_solver()
|
||||
&& !self.infcx.intercrate
|
||||
&& self.in_alias
|
||||
{
|
||||
inner.type_variables().equate(vid, new_var_id);
|
||||
}
|
||||
|
||||
debug!("replacing original vid={:?} with new={:?}", vid, new_var_id);
|
||||
Ok(Ty::new_var(self.tcx(), new_var_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -614,6 +641,15 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||
universe: self.for_universe,
|
||||
})
|
||||
.vid;
|
||||
|
||||
// See the comment for type inference variables
|
||||
// for more details.
|
||||
if self.infcx.next_trait_solver()
|
||||
&& !self.infcx.intercrate
|
||||
&& self.in_alias
|
||||
{
|
||||
variable_table.union(vid, new_var_id);
|
||||
}
|
||||
Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty()))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue