mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-23 12:23:22 +00:00
Fix canonicalizer bug for int/float vars too
This commit is contained in:
parent
3aea46979a
commit
1b6d6f92d1
@ -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")
|
||||
|
@ -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
|
||||
|
@ -278,16 +278,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
|
||||
Err(ui) => CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::IntVar(_)) => {
|
||||
let nt = self.infcx.shallow_resolve(t);
|
||||
ty::Infer(ty::IntVar(vid)) => {
|
||||
let nt = self.infcx.opportunistic_resolve_int_var(vid);
|
||||
if nt != t {
|
||||
return self.fold_ty(nt);
|
||||
} else {
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::Int)
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::FloatVar(_)) => {
|
||||
let nt = self.infcx.shallow_resolve(t);
|
||||
ty::Infer(ty::FloatVar(vid)) => {
|
||||
let nt = self.infcx.opportunistic_resolve_float_var(vid);
|
||||
if nt != t {
|
||||
return self.fold_ty(nt);
|
||||
} else {
|
||||
|
@ -0,0 +1,21 @@
|
||||
// check-pass
|
||||
|
||||
trait Mirror {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl<T> Mirror for T {
|
||||
type Assoc = T;
|
||||
}
|
||||
|
||||
trait Test {}
|
||||
impl Test for i64 {}
|
||||
impl Test for u64 {}
|
||||
|
||||
fn mirror_me<T: Mirror>(t: T, s: <T as Mirror>::Assoc) where <T as Mirror>::Assoc: Test {}
|
||||
|
||||
fn main() {
|
||||
let mut x = 0;
|
||||
mirror_me(x, 1);
|
||||
x = 1i64;
|
||||
}
|
Loading…
Reference in New Issue
Block a user