Skip to content

Commit 78e7fa0

Browse files
committed
Suggest syntax when finding method on array
On a file like the following: ```rust fn main() { let a = [1, 2, 3]; let _ = [i32; 3]::clone(&a); } ``` it is a fair assumption that what was meant was to use an associated type on an array, so we suggest the correct syntax: ``` error: expected one of `.`, `;`, `?`, or an operator, found `::` --> file.rs:3:21 | 3 | let _ = [i32; 3]::clone(&a); | --------^^ | | | | | expected one of `.`, `;`, `?`, or an operator here | help: did you mean to use an associated type?: `<[i32; 3]>::` ```
1 parent 14039a4 commit 78e7fa0

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

src/libsyntax/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ impl fmt::Debug for Stmt {
751751
}
752752

753753

754-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
754+
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
755755
pub enum StmtKind {
756756
/// A local (let) binding.
757757
Local(P<Local>),

src/libsyntax/parse/parser.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -3653,7 +3653,9 @@ impl<'a> Parser<'a> {
36533653
} else {
36543654
None
36553655
};
3656+
debug!("parse_local ty {:?}", ty);
36563657
let init = self.parse_initializer()?;
3658+
debug!("parse_local init {:?}", init);
36573659
Ok(P(ast::Local {
36583660
ty,
36593661
pat,
@@ -4173,7 +4175,29 @@ impl<'a> Parser<'a> {
41734175
if macro_legacy_warnings && self.token != token::Semi {
41744176
self.warn_missing_semicolon();
41754177
} else {
4176-
self.expect_one_of(&[token::Semi], &[])?;
4178+
match self.expect_one_of(&[token::Semi], &[]) {
4179+
Ok(_) => (),
4180+
Err(mut err) => {
4181+
if let (token::ModSep, StmtKind::Local(local)) = (self.token,
4182+
stmt.node) {
4183+
if let Some(ref init) = local.init {
4184+
// We have an initializer for the `let` binding, which means
4185+
// that "something" was parsed correctly as a value there, but
4186+
// was followed by more code.
4187+
if let ExprKind::Repeat(_, _) = init.node {
4188+
let expr_str = self.sess.codemap()
4189+
.span_to_snippet(init.span)
4190+
.unwrap_or(pprust::expr_to_string(init));
4191+
err.span_suggestion(init.span.to(self.span),
4192+
"did you mean to use an associated \
4193+
type instead?",
4194+
format!("<{}>::", expr_str));
4195+
}
4196+
}
4197+
}
4198+
return Err(err);
4199+
}
4200+
}
41774201
}
41784202
}
41794203
_ => {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2017 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 a = [1, 2, 3];
13+
let _ = [i32; 3]::clone(&a);
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: expected one of `.`, `;`, `?`, or an operator, found `::`
2+
--> $DIR/associated-item-from-array.rs:13:21
3+
|
4+
13 | let _ = [i32; 3]::clone(&a);
5+
| --------^^
6+
| | |
7+
| | expected one of `.`, `;`, `?`, or an operator here
8+
| help: did you mean to use an associated type?: `<[i32; 3]>::`
9+
10+
error: aborting due to previous error
11+

0 commit comments

Comments
 (0)