about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDonato Sciarra <sciarp@gmail.com>2018-09-17 23:37:20 +0200
committerDonato Sciarra <sciarp@gmail.com>2018-09-29 21:36:58 +0200
commit0390736dce86cb97880e3eb144de9ec5759bec14 (patch)
tree862190a5888b452c7ceae0082fcb413e3a73db32
parenteb50e75729bce449272ffb3bfbca2f7234f2ae13 (diff)
downloadrust-0390736dce86cb97880e3eb144de9ec5759bec14.tar.gz
rust-0390736dce86cb97880e3eb144de9ec5759bec14.zip
Improve ux when calling associated functions with dot notation
Issue: 22692
-rw-r--r--src/librustc_resolve/lib.rs59
-rw-r--r--src/test/ui/resolve/issue-22692.rs13
-rw-r--r--src/test/ui/resolve/issue-22692.stderr11
3 files changed, 69 insertions, 14 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 5e3f7470099..0bccf5292d9 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3160,11 +3160,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                             // parser issue where a struct literal is being used on an expression
                             // where a brace being opened means a block is being started. Look
                             // ahead for the next text to see if `span` is followed by a `{`.
-                            let cm = this.session.source_map();
+                            let sm = this.session.source_map();
                             let mut sp = span;
                             loop {
-                                sp = cm.next_point(sp);
-                                match cm.span_to_snippet(sp) {
+                                sp = sm.next_point(sp);
+                                match sm.span_to_snippet(sp) {
                                     Ok(ref snippet) => {
                                         if snippet.chars().any(|c| { !c.is_whitespace() }) {
                                             break;
@@ -3173,20 +3173,51 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                                     _ => break,
                                 }
                             }
-                            let followed_by_brace = match cm.span_to_snippet(sp) {
+                            let followed_by_brace = match sm.span_to_snippet(sp) {
                                 Ok(ref snippet) if snippet == "{" => true,
                                 _ => false,
                             };
-                            if let (PathSource::Expr(None), true) = (source, followed_by_brace) {
-                                err.span_label(
-                                    span,
-                                    format!("did you mean `({} {{ /* fields */ }})`?", path_str),
-                                );
-                            } else {
-                                err.span_label(
-                                    span,
-                                    format!("did you mean `{} {{ /* fields */ }}`?", path_str),
-                                );
+                            match source {
+                                PathSource::Expr(Some(parent)) => {
+                                    match parent.node {
+                                        ExprKind::MethodCall(ref path_assignment, _)  => {
+                                            err.span_suggestion_with_applicability(
+                                                sm.start_point(parent.span)
+                                                  .to(path_assignment.ident.span),
+                                                "use `::` to access an associated function",
+                                                format!("{}::{}",
+                                                        path_str,
+                                                        path_assignment.ident),
+                                                Applicability::MaybeIncorrect
+                                            );
+                                            return (err, candidates);
+                                        },
+                                        _ => {
+                                            err.span_label(
+                                                span,
+                                                format!("did you mean `{} {{ /* fields */ }}`?",
+                                                        path_str),
+                                            );
+                                            return (err, candidates);
+                                        },
+                                    }
+                                },
+                                PathSource::Expr(None) if followed_by_brace == true => {
+                                    err.span_label(
+                                        span,
+                                        format!("did you mean `({} {{ /* fields */ }})`?",
+                                                path_str),
+                                    );
+                                    return (err, candidates);
+                                },
+                                _ => {
+                                    err.span_label(
+                                        span,
+                                        format!("did you mean `{} {{ /* fields */ }}`?",
+                                                path_str),
+                                    );
+                                    return (err, candidates);
+                                },
                             }
                         }
                         return (err, candidates);
diff --git a/src/test/ui/resolve/issue-22692.rs b/src/test/ui/resolve/issue-22692.rs
new file mode 100644
index 00000000000..06648c59953
--- /dev/null
+++ b/src/test/ui/resolve/issue-22692.rs
@@ -0,0 +1,13 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let _ = String.new();
+}
diff --git a/src/test/ui/resolve/issue-22692.stderr b/src/test/ui/resolve/issue-22692.stderr
new file mode 100644
index 00000000000..ecdd4ff855f
--- /dev/null
+++ b/src/test/ui/resolve/issue-22692.stderr
@@ -0,0 +1,11 @@
+error[E0423]: expected value, found struct `String`
+  --> $DIR/issue-22692.rs:12:13
+   |
+LL |     let _ = String.new();
+   |             ^^^^^^----
+   |             |
+   |             help: use `::` to access an associated function: `String::new`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0423`.