Skip to content

Commit ae6d470

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 0f0f5db commit ae6d470

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
@@ -757,7 +757,7 @@ impl fmt::Debug for Stmt {
757757
}
758758

759759

760-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
760+
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
761761
pub enum StmtKind {
762762
/// A local (let) binding.
763763
Local(P<Local>),

src/libsyntax/parse/parser.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -3670,7 +3670,9 @@ impl<'a> Parser<'a> {
36703670
} else {
36713671
None
36723672
};
3673+
debug!("parse_local ty {:?}", ty);
36733674
let init = self.parse_initializer()?;
3675+
debug!("parse_local init {:?}", init);
36743676
Ok(P(ast::Local {
36753677
ty,
36763678
pat,
@@ -4190,7 +4192,29 @@ impl<'a> Parser<'a> {
41904192
if macro_legacy_warnings && self.token != token::Semi {
41914193
self.warn_missing_semicolon();
41924194
} else {
4193-
self.expect_one_of(&[token::Semi], &[])?;
4195+
match self.expect_one_of(&[token::Semi], &[]) {
4196+
Ok(_) => (),
4197+
Err(mut err) => {
4198+
if let (token::ModSep, StmtKind::Local(local)) = (self.token,
4199+
stmt.node) {
4200+
if let Some(ref init) = local.init {
4201+
// We have an initializer for the `let` binding, which means
4202+
// that "something" was parsed correctly as a value there, but
4203+
// was followed by more code.
4204+
if let ExprKind::Repeat(_, _) = init.node {
4205+
let expr_str = self.sess.codemap()
4206+
.span_to_snippet(init.span)
4207+
.unwrap_or(pprust::expr_to_string(init));
4208+
err.span_suggestion(init.span.to(self.span),
4209+
"did you mean to use an associated \
4210+
type instead?",
4211+
format!("<{}>::", expr_str));
4212+
}
4213+
}
4214+
}
4215+
return Err(err);
4216+
}
4217+
}
41944218
}
41954219
}
41964220
_ => {}
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)