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.
This commit is contained in:
parent
c20d7eecbc
commit
ff65bffe2b
@ -491,36 +491,18 @@ fn add_type_neq_err_label(
|
|||||||
err.span_label(span, ty.to_string());
|
err.span_label(span, ty.to_string());
|
||||||
if let FnDef(def_id, _) = ty.kind {
|
if let FnDef(def_id, _) = ty.kind {
|
||||||
let source_map = self.tcx.sess.source_map();
|
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) {
|
if !self.tcx.has_typeck_tables(def_id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let fn_sig = {
|
// We're emitting a suggestion, so we can just ignore regions
|
||||||
match self.tcx.typeck_tables_of(def_id).liberated_fn_sigs().get(hir_id) {
|
let fn_sig = *self.tcx.fn_sig(def_id).skip_binder();
|
||||||
Some(f) => *f,
|
|
||||||
None => {
|
|
||||||
bug!("No fn-sig entry for def_id={:?}", def_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let other_ty = if let FnDef(def_id, _) = other_ty.kind {
|
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) {
|
if !self.tcx.has_typeck_tables(def_id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
match self.tcx.typeck_tables_of(def_id).liberated_fn_sigs().get(hir_id) {
|
// We're emitting a suggestion, so we can just ignore regions
|
||||||
Some(f) => f.clone().output(),
|
self.tcx.fn_sig(def_id).skip_binder().output()
|
||||||
None => {
|
|
||||||
bug!("No fn-sig entry for def_id={:?}", def_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
other_ty
|
other_ty
|
||||||
};
|
};
|
||||||
|
16
src/test/ui/issues/issue-66667-function-cmp-cycle.rs
Normal file
16
src/test/ui/issues/issue-66667-function-cmp-cycle.rs
Normal file
@ -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
src/test/ui/issues/issue-66667-function-cmp-cycle.stderr
Normal file
55
src/test/ui/issues/issue-66667-function-cmp-cycle.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user