Skip to content

Commit

Permalink
Fix cycle error when emitting suggestion for mismatched fn type
Browse files Browse the repository at this point in the history
Fixes rust-lang#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.
  • Loading branch information
Aaron1011 committed Mar 11, 2020
1 parent c20d7ee commit ff65bff
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 22 deletions.
26 changes: 4 additions & 22 deletions src/librustc_typeck/check/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/issues/issue-66667-function-cmp-cycle.rs
Original file line number Diff line number Diff line change
@@ -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() {}
55 changes: 55 additions & 0 deletions src/test/ui/issues/issue-66667-function-cmp-cycle.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit ff65bff

Please sign in to comment.