Skip to content

Commit 1b6d6f9

Browse files
Fix canonicalizer bug for int/float vars too
1 parent 3aea469 commit 1b6d6f9

File tree

4 files changed

+69
-13
lines changed

4 files changed

+69
-13
lines changed

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -411,15 +411,28 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
411411
}
412412
}
413413

414-
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
415-
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
416-
t,
417-
),
418-
419-
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
420-
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
421-
t,
422-
),
414+
ty::Infer(ty::IntVar(vid)) => {
415+
let nt = self.infcx.opportunistic_resolve_int_var(vid);
416+
if nt != t {
417+
return self.fold_ty(nt);
418+
} else {
419+
self.canonicalize_ty_var(
420+
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
421+
t,
422+
)
423+
}
424+
}
425+
ty::Infer(ty::FloatVar(vid)) => {
426+
let nt = self.infcx.opportunistic_resolve_float_var(vid);
427+
if nt != t {
428+
return self.fold_ty(nt);
429+
} else {
430+
self.canonicalize_ty_var(
431+
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
432+
t,
433+
)
434+
}
435+
}
423436

424437
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
425438
bug!("encountered a fresh type during canonicalization")

compiler/rustc_infer/src/infer/mod.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,28 @@ impl<'tcx> InferCtxt<'tcx> {
13631363
self.inner.borrow_mut().const_unification_table().find(var)
13641364
}
13651365

1366+
/// Resolves an int var to a rigid int type, if it was constrained to one,
1367+
/// or else the root int var in the unification table.
1368+
pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
1369+
let mut inner = self.inner.borrow_mut();
1370+
if let Some(value) = inner.int_unification_table().probe_value(vid) {
1371+
value.to_type(self.tcx)
1372+
} else {
1373+
self.tcx.mk_int_var(inner.int_unification_table().find(vid))
1374+
}
1375+
}
1376+
1377+
/// Resolves a float var to a rigid int type, if it was constrained to one,
1378+
/// or else the root float var in the unification table.
1379+
pub fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
1380+
let mut inner = self.inner.borrow_mut();
1381+
if let Some(value) = inner.float_unification_table().probe_value(vid) {
1382+
value.to_type(self.tcx)
1383+
} else {
1384+
self.tcx.mk_float_var(inner.float_unification_table().find(vid))
1385+
}
1386+
}
1387+
13661388
/// Where possible, replaces type/const variables in
13671389
/// `value` with their final value. Note that region variables
13681390
/// are unaffected. If a type/const variable has not been unified, it

compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -278,16 +278,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
278278
Err(ui) => CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
279279
}
280280
}
281-
ty::Infer(ty::IntVar(_)) => {
282-
let nt = self.infcx.shallow_resolve(t);
281+
ty::Infer(ty::IntVar(vid)) => {
282+
let nt = self.infcx.opportunistic_resolve_int_var(vid);
283283
if nt != t {
284284
return self.fold_ty(nt);
285285
} else {
286286
CanonicalVarKind::Ty(CanonicalTyVarKind::Int)
287287
}
288288
}
289-
ty::Infer(ty::FloatVar(_)) => {
290-
let nt = self.infcx.shallow_resolve(t);
289+
ty::Infer(ty::FloatVar(vid)) => {
290+
let nt = self.infcx.opportunistic_resolve_float_var(vid);
291291
if nt != t {
292292
return self.fold_ty(nt);
293293
} else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
3+
trait Mirror {
4+
type Assoc;
5+
}
6+
7+
impl<T> Mirror for T {
8+
type Assoc = T;
9+
}
10+
11+
trait Test {}
12+
impl Test for i64 {}
13+
impl Test for u64 {}
14+
15+
fn mirror_me<T: Mirror>(t: T, s: <T as Mirror>::Assoc) where <T as Mirror>::Assoc: Test {}
16+
17+
fn main() {
18+
let mut x = 0;
19+
mirror_me(x, 1);
20+
x = 1i64;
21+
}

0 commit comments

Comments
 (0)