about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs7
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs31
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs26
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs22
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs8
-rw-r--r--tests/ui/issues/issue-66667-function-cmp-cycle.rs3
-rw-r--r--tests/ui/issues/issue-66667-function-cmp-cycle.stderr34
-rw-r--r--tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs21
-rw-r--r--tests/ui/traits/new-solver/int-var-alias-eq.rs18
-rw-r--r--tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs2
-rw-r--r--tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr9
12 files changed, 143 insertions, 40 deletions
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index eecded557a5..37783bc91bb 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -148,10 +148,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         rhs_ty,
                         op,
                     );
-                    self.demand_suptype(expr.span, builtin_return_ty, return_ty);
+                    self.demand_eqtype(expr.span, builtin_return_ty, return_ty);
+                    builtin_return_ty
+                } else {
+                    return_ty
                 }
-
-                return_ty
             }
         }
     }
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index a43330e2d4e..8ac82653c0e 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -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")
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 33292e871b1..b0613abeb48 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -119,20 +119,30 @@ impl<'tcx> InferCtxt<'tcx> {
                 self.unify_float_variable(!a_is_expected, v_id, v)
             }
 
-            // All other cases of inference are errors
-            (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
-                Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
+            // 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, _), _) if self.tcx.trait_solver_next() => {
+            (_, ty::Alias(AliasKind::Projection, _)) | (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)
             }
 
+            // All other cases of inference are errors
+            (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
+                Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
+            }
+
             _ => ty::relate::super_relate_tys(relation, a, b),
         }
     }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 4a2a5557313..4a834957959 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -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
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 8cc8a0573bb..d9bfacd6e3c 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -995,7 +995,7 @@ impl<'tcx> Term<'tcx> {
 
     pub fn is_infer(&self) -> bool {
         match self.unpack() {
-            TermKind::Ty(ty) => ty.is_ty_or_numeric_infer(),
+            TermKind::Ty(ty) => ty.is_ty_var(),
             TermKind::Const(ct) => ct.is_ct_infer(),
         }
     }
diff --git a/compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs
index 981a8f45e45..7ee4f332306 100644
--- a/compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs
@@ -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 {
diff --git a/tests/ui/issues/issue-66667-function-cmp-cycle.rs b/tests/ui/issues/issue-66667-function-cmp-cycle.rs
index 7b025be11a0..b4f09fbbb04 100644
--- a/tests/ui/issues/issue-66667-function-cmp-cycle.rs
+++ b/tests/ui/issues/issue-66667-function-cmp-cycle.rs
@@ -1,16 +1,19 @@
 fn first() {
     second == 1 //~ ERROR binary operation
     //~^ ERROR mismatched types
+    //~| ERROR mismatched types
 }
 
 fn second() {
     first == 1 //~ ERROR binary operation
     //~^ ERROR mismatched types
+    //~| ERROR mismatched types
 }
 
 fn bar() {
     bar == 1 //~ ERROR binary operation
     //~^ ERROR mismatched types
+    //~| ERROR mismatched types
 }
 
 fn main() {}
diff --git a/tests/ui/issues/issue-66667-function-cmp-cycle.stderr b/tests/ui/issues/issue-66667-function-cmp-cycle.stderr
index 887699ef5ce..d9a960ce197 100644
--- a/tests/ui/issues/issue-66667-function-cmp-cycle.stderr
+++ b/tests/ui/issues/issue-66667-function-cmp-cycle.stderr
@@ -15,8 +15,16 @@ LL |     second == 1
    = note: expected fn item `fn() {second}`
                  found type `{integer}`
 
+error[E0308]: mismatched types
+  --> $DIR/issue-66667-function-cmp-cycle.rs:2:5
+   |
+LL | fn first() {
+   |            - help: try adding a return type: `-> bool`
+LL |     second == 1
+   |     ^^^^^^^^^^^ expected `()`, found `bool`
+
 error[E0369]: binary operation `==` cannot be applied to type `fn() {first}`
-  --> $DIR/issue-66667-function-cmp-cycle.rs:7:11
+  --> $DIR/issue-66667-function-cmp-cycle.rs:8:11
    |
 LL |     first == 1
    |     ----- ^^ - {integer}
@@ -24,7 +32,7 @@ LL |     first == 1
    |     fn() {first}
 
 error[E0308]: mismatched types
-  --> $DIR/issue-66667-function-cmp-cycle.rs:7:14
+  --> $DIR/issue-66667-function-cmp-cycle.rs:8:14
    |
 LL |     first == 1
    |              ^ expected fn item, found integer
@@ -32,8 +40,16 @@ LL |     first == 1
    = note: expected fn item `fn() {first}`
                  found type `{integer}`
 
+error[E0308]: mismatched types
+  --> $DIR/issue-66667-function-cmp-cycle.rs:8:5
+   |
+LL | fn second() {
+   |             - help: try adding a return type: `-> bool`
+LL |     first == 1
+   |     ^^^^^^^^^^ expected `()`, found `bool`
+
 error[E0369]: binary operation `==` cannot be applied to type `fn() {bar}`
-  --> $DIR/issue-66667-function-cmp-cycle.rs:12:9
+  --> $DIR/issue-66667-function-cmp-cycle.rs:14:9
    |
 LL |     bar == 1
    |     --- ^^ - {integer}
@@ -41,7 +57,7 @@ LL |     bar == 1
    |     fn() {bar}
 
 error[E0308]: mismatched types
-  --> $DIR/issue-66667-function-cmp-cycle.rs:12:12
+  --> $DIR/issue-66667-function-cmp-cycle.rs:14:12
    |
 LL |     bar == 1
    |            ^ expected fn item, found integer
@@ -49,7 +65,15 @@ LL |     bar == 1
    = note: expected fn item `fn() {bar}`
                  found type `{integer}`
 
-error: aborting due to 6 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-66667-function-cmp-cycle.rs:14:5
+   |
+LL | fn bar() {
+   |          - help: try adding a return type: `-> bool`
+LL |     bar == 1
+   |     ^^^^^^^^ expected `()`, found `bool`
+
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0308, E0369.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs b/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs
new file mode 100644
index 00000000000..3f7316a2279
--- /dev/null
+++ b/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs
@@ -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;
+}
diff --git a/tests/ui/traits/new-solver/int-var-alias-eq.rs b/tests/ui/traits/new-solver/int-var-alias-eq.rs
new file mode 100644
index 00000000000..2da387db4a9
--- /dev/null
+++ b/tests/ui/traits/new-solver/int-var-alias-eq.rs
@@ -0,0 +1,18 @@
+// check-pass
+// compile-flags: -Ztrait-solver=next
+
+// HIR typeck ends up equating `<_#0i as Add>::Output == _#0i`.
+// Want to make sure that we emit an alias-eq goal for this,
+// instead of treating it as a type error and bailing.
+
+fn test() {
+    // fallback
+    let x = 1 + 2;
+}
+
+fn test2() -> u32 {
+    // expectation from return ty
+    1 + 2
+}
+
+fn main() {}
diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs
index 5ff567cd07c..3b261062f78 100644
--- a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs
+++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs
@@ -1,5 +1,5 @@
 // compile-flags: -Ztrait-solver=next
-// known-bug: unknown
+// check-pass
 
 fn main() {
     (0u8 + 0u8) as char;
diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr
deleted file mode 100644
index 6b09ccd5214..00000000000
--- a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0271]: type mismatch resolving `char == <u8 as Add>::Output`
-  --> $DIR/cast-checks-handling-projections.rs:5:5
-   |
-LL |     (0u8 + 0u8) as char;
-   |     ^^^^^^^^^^^ types differ
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0271`.