New users might attempt to write something like this, (e.g. if they're coming from Java):
fn main() {
let _ = String.new();
}
This will not compile since they're not using ::. This is what the compiler outputs when compiling:
~ $ rustc program.rs
program.rs:2:13: 2:19 error: unresolved name `String`
program.rs:2 let _ = String.new();
^~~~~~
I find this error message pretty misleading. It'd be great if there was a lint that would check the available static methods of a struct/enum and if there's one that matches, suggest it instead (in the case above, suggest using String::new()).
Current error:
<anon>:2:13: 2:19 error: `String` is the name of a struct or struct variant, but this expression uses it like a function name [E0423]
<anon>:2 let _ = String.new();
^~~~~~
<anon>:2:13: 2:19 help: see the detailed explanation for E0423
<anon>:2:13: 2:19 help: did you mean to write: `String { /* fields */ }`?
Not ideal either...
Current output:
error[E0423]: expected value, found struct `String`
--> src/main.rs:2:13
|
2 | let _ = String.new();
| ^^^^^^ did you mean `String { /* fields */ }`?
I believe the following would be appropriate output:
error[E0423]: expected value, found struct `String`
--> src/main.rs:2:13
|
2 | let _ = String.new();
| ^^^^^^---- help: did you mean to call static method `new`?: `String::new`
I'd like to work on this. I think I can see where to change it. If someone wants to mentor let me know, otherwise I might ask on IRC or Discourse if I get stuck.
@sourcefrog feel free to do so and to reach out to anyone in the team! As soon as you have some code written, make an early PR so that we can take a look at it and provide feedback on the code itself.
Also, you should probably be looking at librustc_resolve/lib.rs:smart_resolve_path_fragment, which is where the suggestion is being provided. The only problem I see is that because this happens before typecheck, I don't think you can verify wether new is a method of String yet, but you can still provide it as a suggestion as a best effort guess.
For the code String.new(), smart_resolve_path_fragment's argument source will be Expr(Some(expr(10: String.new()))). In the suggestion path you would need to check if source is an Expr and that it is a method call. If it is, instead of suggesting $Type { /* fields */ } suggest $Type::$method_name on the Expr's span.
@estebank
$Type::? a substring of String.new(), or is $Type a type?source is a method call? is $method_name then the other part of the string String.new()?$Type is just a way to refer to String (or any type that appears in the code). $method_name would be new in String.new().
You need to check that source is PathSource::Expr(Expr { kind: ExprKind::Call { ty, fun, args}, .. }), where ty is the self type, fun is an ExprRef containing an Expr. I'm not sure about the exact Expr tree for the method call without looking at a running example, but this should give you an idea of the direction to take (and I would just add some debug statements or start up the debugger to see it).
Most helpful comment
Current output:
I believe the following would be appropriate output: