diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 496be8b3eb23e..79d06263d7338 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -751,7 +751,7 @@ impl fmt::Debug for Stmt { } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] pub enum StmtKind { /// A local (let) binding. Local(P), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a2514a0425429..05b6e536d72e3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3653,7 +3653,9 @@ impl<'a> Parser<'a> { } else { None }; + debug!("parse_local ty {:?}", ty); let init = self.parse_initializer()?; + debug!("parse_local init {:?}", init); Ok(P(ast::Local { ty, pat, @@ -4173,7 +4175,29 @@ impl<'a> Parser<'a> { if macro_legacy_warnings && self.token != token::Semi { self.warn_missing_semicolon(); } else { - self.expect_one_of(&[token::Semi], &[])?; + match self.expect_one_of(&[token::Semi], &[]) { + Ok(_) => (), + Err(mut err) => { + if let (token::ModSep, StmtKind::Local(local)) = (self.token, + stmt.node) { + if let Some(ref init) = local.init { + // We have an initializer for the `let` binding, which means + // that "something" was parsed correctly as a value there, but + // was followed by more code. + if let ExprKind::Repeat(_, _) = init.node { + let expr_str = self.sess.codemap() + .span_to_snippet(init.span) + .unwrap_or(pprust::expr_to_string(init)); + err.span_suggestion(init.span.to(self.span), + "did you mean to use an associated \ + type instead?", + format!("<{}>::", expr_str)); + } + } + } + return Err(err); + } + } } } _ => {} diff --git a/src/test/ui/suggestions/associated-item-from-array.rs b/src/test/ui/suggestions/associated-item-from-array.rs new file mode 100644 index 0000000000000..7c20db1e411fe --- /dev/null +++ b/src/test/ui/suggestions/associated-item-from-array.rs @@ -0,0 +1,14 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let a = [1, 2, 3]; + let _ = [i32; 3]::clone(&a); +} diff --git a/src/test/ui/suggestions/associated-item-from-array.stderr b/src/test/ui/suggestions/associated-item-from-array.stderr new file mode 100644 index 0000000000000..f09521e26e0ea --- /dev/null +++ b/src/test/ui/suggestions/associated-item-from-array.stderr @@ -0,0 +1,11 @@ +error: expected one of `.`, `;`, `?`, or an operator, found `::` + --> $DIR/associated-item-from-array.rs:13:21 + | +13 | let _ = [i32; 3]::clone(&a); + | --------^^ + | | | + | | expected one of `.`, `;`, `?`, or an operator here + | help: did you mean to use an associated type?: `<[i32; 3]>::` + +error: aborting due to previous error +