From ff65bffe2b143528ff90d5226b18ceca750d7c02 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 11 Mar 2020 15:35:46 -0400 Subject: [PATCH] Fix cycle error when emitting suggestion for mismatched `fn` type 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 | 26 ++------- .../issues/issue-66667-function-cmp-cycle.rs | 16 ++++++ .../issue-66667-function-cmp-cycle.stderr | 55 +++++++++++++++++++ 3 files changed, 75 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/issues/issue-66667-function-cmp-cycle.rs create mode 100644 src/test/ui/issues/issue-66667-function-cmp-cycle.stderr diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index bf3511a26143c..3648a99abc259 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -491,36 +491,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 index 0000000000000..7b025be11a09e --- /dev/null +++ b/src/test/ui/issues/issue-66667-function-cmp-cycle.rs @@ -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 index 0000000000000..887699ef5ce85 --- /dev/null +++ b/src/test/ui/issues/issue-66667-function-cmp-cycle.stderr @@ -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`.