Skip to content

Commit

Permalink
Do not suggest "is a function" for free variables
Browse files Browse the repository at this point in the history
Part of #82323
  • Loading branch information
notriddle committed Feb 16, 2022
1 parent 05d1652 commit 65fc705
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 0 deletions.
12 changes: 12 additions & 0 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Expand Up @@ -40,7 +40,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Err(..) => return false,
};

// This conditional prevents us from asking to call errors and unresolved types.
// It might seem that we can use `predicate_must_hold_modulo_regions`,
// but since a Dummy binder is used to fill in the FnOnce trait's arguments,
// type resolution always gives a "maybe" here.
if self.autoderef(span, ty).any(|(ty, _)| {
info!("check deref {:?} error", ty);
matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
}) {
return false;
}

self.autoderef(span, ty).any(|(ty, _)| {
info!("check deref {:?} impl FnOnce", ty);
self.probe(|_| {
let fn_once_substs = tcx.mk_substs_trait(
ty,
Expand Down
@@ -0,0 +1,22 @@
struct Struct<T>(T);
impl Struct<T>
//~^ ERROR cannot find type `T` in this scope
//~| NOTE not found in this scope
//~| HELP you might be missing a type parameter
where
T: Copy,
//~^ ERROR cannot find type `T` in this scope
//~| NOTE not found in this scope
{
// The part where it claims that there is no method named `len` is a bug. Feel free to fix it.
// This test is intended to ensure that a different bug, where it claimed
// that `v` was a function, does not regress.
fn method(v: Vec<u8>) { v.len(); }
//~^ ERROR type annotations needed
//~| NOTE cannot infer type
//~| NOTE type must be known at this point
//~| ERROR no method named `len`
//~| NOTE private field, not a method
}

fn main() {}
@@ -0,0 +1,32 @@
error[E0412]: cannot find type `T` in this scope
--> $DIR/fn-help-with-err-generic-is-not-function.rs:2:13
|
LL | impl Struct<T>
| - ^ not found in this scope
| |
| help: you might be missing a type parameter: `<T>`

error[E0412]: cannot find type `T` in this scope
--> $DIR/fn-help-with-err-generic-is-not-function.rs:7:5
|
LL | T: Copy,
| ^ not found in this scope

error[E0282]: type annotations needed
--> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31
|
LL | fn method(v: Vec<u8>) { v.len(); }
| ^^^ cannot infer type
|
= note: type must be known at this point

error[E0599]: no method named `len` found for struct `Vec<u8>` in the current scope
--> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31
|
LL | fn method(v: Vec<u8>) { v.len(); }
| ^^^ private field, not a method

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0282, E0412, E0599.
For more information about an error, try `rustc --explain E0282`.
16 changes: 16 additions & 0 deletions src/test/ui/functions-closures/fn-help-with-err.rs
@@ -0,0 +1,16 @@
// This test case checks the behavior of typeck::check::method::suggest::is_fn on Ty::Error.
fn main() {
let arc = std::sync::Arc::new(oops);
//~^ ERROR cannot find value `oops` in this scope
//~| NOTE not found
// The error "note: `arc` is a function, perhaps you wish to call it" MUST NOT appear.
arc.blablabla();
//~^ ERROR no method named `blablabla`
//~| NOTE method not found
let arc2 = std::sync::Arc::new(|| 1);
// The error "note: `arc2` is a function, perhaps you wish to call it" SHOULD appear
arc2.blablabla();
//~^ ERROR no method named `blablabla`
//~| NOTE method not found
//~| NOTE `arc2` is a function, perhaps you wish to call it
}
24 changes: 24 additions & 0 deletions src/test/ui/functions-closures/fn-help-with-err.stderr
@@ -0,0 +1,24 @@
error[E0425]: cannot find value `oops` in this scope
--> $DIR/fn-help-with-err.rs:3:35
|
LL | let arc = std::sync::Arc::new(oops);
| ^^^^ not found in this scope

error[E0599]: no method named `blablabla` found for struct `Arc<_>` in the current scope
--> $DIR/fn-help-with-err.rs:7:9
|
LL | arc.blablabla();
| ^^^^^^^^^ method not found in `Arc<_>`

error[E0599]: no method named `blablabla` found for struct `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:40]>` in the current scope
--> $DIR/fn-help-with-err.rs:12:10
|
LL | arc2.blablabla();
| ^^^^^^^^^ method not found in `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:40]>`
|
= note: `arc2` is a function, perhaps you wish to call it

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0425, E0599.
For more information about an error, try `rustc --explain E0425`.

0 comments on commit 65fc705

Please sign in to comment.