Skip to content

Commit 0390736

Browse files
committed
Improve ux when calling associated functions with dot notation
Issue: 22692
1 parent eb50e75 commit 0390736

File tree

3 files changed

+69
-14
lines changed

3 files changed

+69
-14
lines changed

src/librustc_resolve/lib.rs

+45-14
Original file line numberDiff line numberDiff line change
@@ -3160,11 +3160,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
31603160
// parser issue where a struct literal is being used on an expression
31613161
// where a brace being opened means a block is being started. Look
31623162
// ahead for the next text to see if `span` is followed by a `{`.
3163-
let cm = this.session.source_map();
3163+
let sm = this.session.source_map();
31643164
let mut sp = span;
31653165
loop {
3166-
sp = cm.next_point(sp);
3167-
match cm.span_to_snippet(sp) {
3166+
sp = sm.next_point(sp);
3167+
match sm.span_to_snippet(sp) {
31683168
Ok(ref snippet) => {
31693169
if snippet.chars().any(|c| { !c.is_whitespace() }) {
31703170
break;
@@ -3173,20 +3173,51 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
31733173
_ => break,
31743174
}
31753175
}
3176-
let followed_by_brace = match cm.span_to_snippet(sp) {
3176+
let followed_by_brace = match sm.span_to_snippet(sp) {
31773177
Ok(ref snippet) if snippet == "{" => true,
31783178
_ => false,
31793179
};
3180-
if let (PathSource::Expr(None), true) = (source, followed_by_brace) {
3181-
err.span_label(
3182-
span,
3183-
format!("did you mean `({} {{ /* fields */ }})`?", path_str),
3184-
);
3185-
} else {
3186-
err.span_label(
3187-
span,
3188-
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
3189-
);
3180+
match source {
3181+
PathSource::Expr(Some(parent)) => {
3182+
match parent.node {
3183+
ExprKind::MethodCall(ref path_assignment, _) => {
3184+
err.span_suggestion_with_applicability(
3185+
sm.start_point(parent.span)
3186+
.to(path_assignment.ident.span),
3187+
"use `::` to access an associated function",
3188+
format!("{}::{}",
3189+
path_str,
3190+
path_assignment.ident),
3191+
Applicability::MaybeIncorrect
3192+
);
3193+
return (err, candidates);
3194+
},
3195+
_ => {
3196+
err.span_label(
3197+
span,
3198+
format!("did you mean `{} {{ /* fields */ }}`?",
3199+
path_str),
3200+
);
3201+
return (err, candidates);
3202+
},
3203+
}
3204+
},
3205+
PathSource::Expr(None) if followed_by_brace == true => {
3206+
err.span_label(
3207+
span,
3208+
format!("did you mean `({} {{ /* fields */ }})`?",
3209+
path_str),
3210+
);
3211+
return (err, candidates);
3212+
},
3213+
_ => {
3214+
err.span_label(
3215+
span,
3216+
format!("did you mean `{} {{ /* fields */ }}`?",
3217+
path_str),
3218+
);
3219+
return (err, candidates);
3220+
},
31903221
}
31913222
}
31923223
return (err, candidates);

src/test/ui/resolve/issue-22692.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let _ = String.new();
13+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0423]: expected value, found struct `String`
2+
--> $DIR/issue-22692.rs:12:13
3+
|
4+
LL | let _ = String.new();
5+
| ^^^^^^----
6+
| |
7+
| help: use `::` to access an associated function: `String::new`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0423`.

0 commit comments

Comments
 (0)