Rollup merge of #108828 - compiler-errors:new-solver-alias-eq-on-num-var, r=lcnr
Emit alias-eq when equating numeric var and projection This doesn't fix everything having to do with projections and infer vars, but it does fix a common case I saw in HIR typeck. r? `@lcnr`
This commit is contained in:
commit
233ed35e84
12 changed files with 144 additions and 41 deletions
|
@ -411,15 +411,28 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
|
||||
t,
|
||||
),
|
||||
|
||||
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
|
||||
t,
|
||||
),
|
||||
ty::Infer(ty::IntVar(vid)) => {
|
||||
let nt = self.infcx.opportunistic_resolve_int_var(vid);
|
||||
if nt != t {
|
||||
return self.fold_ty(nt);
|
||||
} else {
|
||||
self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
|
||||
t,
|
||||
)
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::FloatVar(vid)) => {
|
||||
let nt = self.infcx.opportunistic_resolve_float_var(vid);
|
||||
if nt != t {
|
||||
return self.fold_ty(nt);
|
||||
} else {
|
||||
self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
|
||||
t,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||
bug!("encountered a fresh type during canonicalization")
|
||||
|
|
|
@ -119,20 +119,30 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
self.unify_float_variable(!a_is_expected, v_id, v)
|
||||
}
|
||||
|
||||
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
|
||||
(
|
||||
ty::Alias(AliasKind::Projection, _),
|
||||
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
|
||||
)
|
||||
| (
|
||||
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
|
||||
ty::Alias(AliasKind::Projection, _),
|
||||
) if self.tcx.trait_solver_next() => {
|
||||
bug!()
|
||||
}
|
||||
|
||||
(_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _)
|
||||
if self.tcx.trait_solver_next() =>
|
||||
{
|
||||
relation.register_type_equate_obligation(a, b);
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
// All other cases of inference are errors
|
||||
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
|
||||
Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
|
||||
}
|
||||
|
||||
(ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => {
|
||||
relation.register_type_equate_obligation(a, b);
|
||||
Ok(b)
|
||||
}
|
||||
(_, ty::Alias(AliasKind::Projection, _)) if self.tcx.trait_solver_next() => {
|
||||
relation.register_type_equate_obligation(b, a);
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
_ => ty::relate::super_relate_tys(relation, a, b),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1363,6 +1363,28 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
self.inner.borrow_mut().const_unification_table().find(var)
|
||||
}
|
||||
|
||||
/// Resolves an int var to a rigid int type, if it was constrained to one,
|
||||
/// or else the root int var in the unification table.
|
||||
pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
if let Some(value) = inner.int_unification_table().probe_value(vid) {
|
||||
value.to_type(self.tcx)
|
||||
} else {
|
||||
self.tcx.mk_int_var(inner.int_unification_table().find(vid))
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves a float var to a rigid int type, if it was constrained to one,
|
||||
/// or else the root float var in the unification table.
|
||||
pub fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
if let Some(value) = inner.float_unification_table().probe_value(vid) {
|
||||
value.to_type(self.tcx)
|
||||
} else {
|
||||
self.tcx.mk_float_var(inner.float_unification_table().find(vid))
|
||||
}
|
||||
}
|
||||
|
||||
/// Where possible, replaces type/const variables in
|
||||
/// `value` with their final value. Note that region variables
|
||||
/// are unaffected. If a type/const variable has not been unified, it
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue