Skip to content

Commit a1f3b0f

Browse files
authored
Rollup merge of rust-lang#54308 - dsciarra:issue-22692, r=estebank
Better user experience when attempting to call associated functions with dot notation Closes rust-lang#22692
2 parents 818a05d + 0390736 commit a1f3b0f

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
@@ -3147,11 +3147,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
31473147
// parser issue where a struct literal is being used on an expression
31483148
// where a brace being opened means a block is being started. Look
31493149
// ahead for the next text to see if `span` is followed by a `{`.
3150-
let cm = this.session.source_map();
3150+
let sm = this.session.source_map();
31513151
let mut sp = span;
31523152
loop {
3153-
sp = cm.next_point(sp);
3154-
match cm.span_to_snippet(sp) {
3153+
sp = sm.next_point(sp);
3154+
match sm.span_to_snippet(sp) {
31553155
Ok(ref snippet) => {
31563156
if snippet.chars().any(|c| { !c.is_whitespace() }) {
31573157
break;
@@ -3160,20 +3160,51 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
31603160
_ => break,
31613161
}
31623162
}
3163-
let followed_by_brace = match cm.span_to_snippet(sp) {
3163+
let followed_by_brace = match sm.span_to_snippet(sp) {
31643164
Ok(ref snippet) if snippet == "{" => true,
31653165
_ => false,
31663166
};
3167-
if let (PathSource::Expr(None), true) = (source, followed_by_brace) {
3168-
err.span_label(
3169-
span,
3170-
format!("did you mean `({} {{ /* fields */ }})`?", path_str),
3171-
);
3172-
} else {
3173-
err.span_label(
3174-
span,
3175-
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
3176-
);
3167+
match source {
3168+
PathSource::Expr(Some(parent)) => {
3169+
match parent.node {
3170+
ExprKind::MethodCall(ref path_assignment, _) => {
3171+
err.span_suggestion_with_applicability(
3172+
sm.start_point(parent.span)
3173+
.to(path_assignment.ident.span),
3174+
"use `::` to access an associated function",
3175+
format!("{}::{}",
3176+
path_str,
3177+
path_assignment.ident),
3178+
Applicability::MaybeIncorrect
3179+
);
3180+
return (err, candidates);
3181+
},
3182+
_ => {
3183+
err.span_label(
3184+
span,
3185+
format!("did you mean `{} {{ /* fields */ }}`?",
3186+
path_str),
3187+
);
3188+
return (err, candidates);
3189+
},
3190+
}
3191+
},
3192+
PathSource::Expr(None) if followed_by_brace == true => {
3193+
err.span_label(
3194+
span,
3195+
format!("did you mean `({} {{ /* fields */ }})`?",
3196+
path_str),
3197+
);
3198+
return (err, candidates);
3199+
},
3200+
_ => {
3201+
err.span_label(
3202+
span,
3203+
format!("did you mean `{} {{ /* fields */ }}`?",
3204+
path_str),
3205+
);
3206+
return (err, candidates);
3207+
},
31773208
}
31783209
}
31793210
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)