]> git.lizzy.rs Git - rust.git/commitdiff
Fix cycle error when emitting suggestion for mismatched `fn` type
authorAaron Hill <aa1ronham@gmail.com>
Wed, 11 Mar 2020 19:35:46 +0000 (15:35 -0400)
committerAaron Hill <aa1ronham@gmail.com>
Wed, 11 Mar 2020 19:35:46 +0000 (15:35 -0400)
Fixes #66667

Previously, we called `tcx.typeck_tables_of` when determining whether or
not to emit a suggestion for a type error. However, we might already be
type-checking the `DefId` we pass to `typeck_tables_of` (it could be
anywhere in the query stack).

Fortunately, we only need the function signature, not the entire
`TypeckTables`. By using `tcx.fn_sig`, we avoid the possibility of cycle
errors while retaining the ability to emit a suggestion.

src/librustc_typeck/check/op.rs
src/test/ui/issues/issue-66667-function-cmp-cycle.rs [new file with mode: 0644]
src/test/ui/issues/issue-66667-function-cmp-cycle.stderr [new file with mode: 0644]

index bf3511a26143cc1d1ef40b46dbe51f2022675e2d..3648a99abc259414dcb8a2ee600a606dd11c85d3 100644 (file)
@@ -491,36 +491,18 @@ fn add_type_neq_err_label(
         err.span_label(span, ty.to_string());
         if let FnDef(def_id, _) = ty.kind {
             let source_map = self.tcx.sess.source_map();
-            let hir_id = match self.tcx.hir().as_local_hir_id(def_id) {
-                Some(hir_id) => hir_id,
-                None => return false,
-            };
             if !self.tcx.has_typeck_tables(def_id) {
                 return false;
             }
-            let fn_sig = {
-                match self.tcx.typeck_tables_of(def_id).liberated_fn_sigs().get(hir_id) {
-                    Some(f) => *f,
-                    None => {
-                        bug!("No fn-sig entry for def_id={:?}", def_id);
-                    }
-                }
-            };
+            // We're emitting a suggestion, so we can just ignore regions
+            let fn_sig = *self.tcx.fn_sig(def_id).skip_binder();
 
             let other_ty = if let FnDef(def_id, _) = other_ty.kind {
-                let hir_id = match self.tcx.hir().as_local_hir_id(def_id) {
-                    Some(hir_id) => hir_id,
-                    None => return false,
-                };
                 if !self.tcx.has_typeck_tables(def_id) {
                     return false;
                 }
-                match self.tcx.typeck_tables_of(def_id).liberated_fn_sigs().get(hir_id) {
-                    Some(f) => f.clone().output(),
-                    None => {
-                        bug!("No fn-sig entry for def_id={:?}", def_id);
-                    }
-                }
+                // We're emitting a suggestion, so we can just ignore regions
+                self.tcx.fn_sig(def_id).skip_binder().output()
             } else {
                 other_ty
             };
diff --git a/src/test/ui/issues/issue-66667-function-cmp-cycle.rs b/src/test/ui/issues/issue-66667-function-cmp-cycle.rs
new file mode 100644 (file)
index 0000000..7b025be
--- /dev/null
@@ -0,0 +1,16 @@
+fn first() {
+    second == 1 //~ ERROR binary operation
+    //~^ ERROR mismatched types
+}
+
+fn second() {
+    first == 1 //~ ERROR binary operation
+    //~^ ERROR mismatched types
+}
+
+fn bar() {
+    bar == 1 //~ ERROR binary operation
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-66667-function-cmp-cycle.stderr b/src/test/ui/issues/issue-66667-function-cmp-cycle.stderr
new file mode 100644 (file)
index 0000000..887699e
--- /dev/null
@@ -0,0 +1,55 @@
+error[E0369]: binary operation `==` cannot be applied to type `fn() {second}`
+  --> $DIR/issue-66667-function-cmp-cycle.rs:2:12
+   |
+LL |     second == 1
+   |     ------ ^^ - {integer}
+   |     |
+   |     fn() {second}
+
+error[E0308]: mismatched types
+  --> $DIR/issue-66667-function-cmp-cycle.rs:2:15
+   |
+LL |     second == 1
+   |               ^ expected fn item, found integer
+   |
+   = note: expected fn item `fn() {second}`
+                 found type `{integer}`
+
+error[E0369]: binary operation `==` cannot be applied to type `fn() {first}`
+  --> $DIR/issue-66667-function-cmp-cycle.rs:7:11
+   |
+LL |     first == 1
+   |     ----- ^^ - {integer}
+   |     |
+   |     fn() {first}
+
+error[E0308]: mismatched types
+  --> $DIR/issue-66667-function-cmp-cycle.rs:7:14
+   |
+LL |     first == 1
+   |              ^ expected fn item, found integer
+   |
+   = note: expected fn item `fn() {first}`
+                 found type `{integer}`
+
+error[E0369]: binary operation `==` cannot be applied to type `fn() {bar}`
+  --> $DIR/issue-66667-function-cmp-cycle.rs:12:9
+   |
+LL |     bar == 1
+   |     --- ^^ - {integer}
+   |     |
+   |     fn() {bar}
+
+error[E0308]: mismatched types
+  --> $DIR/issue-66667-function-cmp-cycle.rs:12:12
+   |
+LL |     bar == 1
+   |            ^ expected fn item, found integer
+   |
+   = note: expected fn item `fn() {bar}`
+                 found type `{integer}`
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0308, E0369.
+For more information about an error, try `rustc --explain E0308`.