diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-11-05 04:22:18 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-11-11 15:44:19 +0300 |
| commit | 1055bdfb2a5ced99bb47c344c91af2f324ebbb6d (patch) | |
| tree | 085fbbd4b5015fa5cd63f1b5c26e9e52771db301 | |
| parent | 69ee5a8a9787336f8635ec12ed0c6199a70505e0 (diff) | |
| download | rust-1055bdfb2a5ced99bb47c344c91af2f324ebbb6d.tar.gz rust-1055bdfb2a5ced99bb47c344c91af2f324ebbb6d.zip | |
Accept interpolated patterns in trait method parameters
Remove some outdated messages from "no patterns allowed" errors
| -rw-r--r-- | src/librustc_passes/ast_validation.rs | 35 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 26 | ||||
| -rw-r--r-- | src/test/compile-fail/no-patterns-in-args-macro.rs | 37 | ||||
| -rw-r--r-- | src/test/compile-fail/no-patterns-in-args.rs | 4 |
4 files changed, 56 insertions, 46 deletions
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 6d9c2948841..afa704025b9 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -67,13 +67,12 @@ impl<'a> AstValidator<'a> { } } - fn check_decl_no_pat<ReportFn: Fn(Span, bool)>(&self, decl: &FnDecl, report_err: ReportFn) { + fn check_decl_no_pat<ReportFn: Fn(Span)>(&self, decl: &FnDecl, report_err: ReportFn) { for arg in &decl.inputs { match arg.pat.node { PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), _, None) | PatKind::Wild => {} - PatKind::Ident(..) => report_err(arg.pat.span, true), - _ => report_err(arg.pat.span, false), + _ => report_err(arg.pat.span), } } } @@ -150,15 +149,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_ty(&mut self, ty: &'a Ty) { match ty.node { TyKind::BareFn(ref bfty) => { - self.check_decl_no_pat(&bfty.decl, |span, _| { - let mut err = struct_span_err!(self.session, - span, - E0561, - "patterns aren't allowed in function pointer \ - types"); - err.span_note(span, - "this is a recent error, see issue #35203 for more details"); - err.emit(); + self.check_decl_no_pat(&bfty.decl, |span| { + struct_span_err!(self.session, span, E0561, + "patterns aren't allowed in function pointer types").emit(); }); } TyKind::TraitObject(ref bounds, ..) => { @@ -260,7 +253,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let TraitItemKind::Method(ref sig, ref block) = trait_item.node { self.check_trait_fn_not_const(sig.constness); if block.is_none() { - self.check_decl_no_pat(&sig.decl, |span, _| { + self.check_decl_no_pat(&sig.decl, |span| { self.session.buffer_lint( lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY, trait_item.id, span, @@ -299,18 +292,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { match fi.node { ForeignItemKind::Fn(ref decl, _) => { - self.check_decl_no_pat(decl, |span, is_recent| { - let mut err = struct_span_err!(self.session, - span, - E0130, - "patterns aren't allowed in foreign function \ - declarations"); - err.span_label(span, "pattern not allowed in foreign function"); - if is_recent { - err.span_note(span, - "this is a recent error, see issue #35203 for more details"); - } - err.emit(); + self.check_decl_no_pat(decl, |span| { + struct_span_err!(self.session, span, E0130, + "patterns aren't allowed in foreign function declarations") + .span_label(span, "pattern not allowed in foreign function").emit(); }); } ForeignItemKind::Static(..) | ForeignItemKind::Ty => {} diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e583981d981..c1819307928 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -360,10 +360,6 @@ impl TokenType { } } -fn is_ident_or_underscore(t: &token::Token) -> bool { - t.is_ident() || *t == token::Underscore -} - // Returns true if `IDENT t` can start a type - `IDENT::a::b`, `IDENT<u8, u8>`, // `IDENT<<u8 as Trait>::AssocTy>`, `IDENT(u8, u8) -> u8`. fn can_continue_type_after_ident(t: &token::Token) -> bool { @@ -1625,23 +1621,19 @@ impl<'a> Parser<'a> { Ok(MutTy { ty: t, mutbl: mutbl }) } - pub fn is_named_argument(&mut self) -> bool { + fn is_named_argument(&mut self) -> bool { let offset = match self.token { - token::BinOp(token::And) | - token::AndAnd => 1, + token::Interpolated(ref nt) => match nt.0 { + token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon), + _ => 0, + } + token::BinOp(token::And) | token::AndAnd => 1, _ if self.token.is_keyword(keywords::Mut) => 1, - _ => 0 + _ => 0, }; - debug!("parser is_named_argument offset:{}", offset); - - if offset == 0 { - is_ident_or_underscore(&self.token) - && self.look_ahead(1, |t| *t == token::Colon) - } else { - self.look_ahead(offset, |t| is_ident_or_underscore(t)) - && self.look_ahead(offset + 1, |t| *t == token::Colon) - } + self.look_ahead(offset, |t| t.is_ident() || t == &token::Underscore) && + self.look_ahead(offset + 1, |t| t == &token::Colon) } /// This version of parse arg doesn't necessarily require diff --git a/src/test/compile-fail/no-patterns-in-args-macro.rs b/src/test/compile-fail/no-patterns-in-args-macro.rs new file mode 100644 index 00000000000..3aabd19f6e6 --- /dev/null +++ b/src/test/compile-fail/no-patterns-in-args-macro.rs @@ -0,0 +1,37 @@ +// 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 <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. + +macro_rules! m { + ($pat: pat) => { + trait Tr { + fn trait_method($pat: u8); + } + + type A = fn($pat: u8); + + extern { + fn foreign_fn($pat: u8); + } + } +} + +mod good_pat { + m!(good_pat); // OK +} + +mod bad_pat { + m!((bad, pat)); + //~^ ERROR patterns aren't allowed in function pointer types + //~| ERROR patterns aren't allowed in foreign function declarations + //~| WARN patterns aren't allowed in methods without bodies + //~| WARN this was previously accepted +} + +fn main() {} diff --git a/src/test/compile-fail/no-patterns-in-args.rs b/src/test/compile-fail/no-patterns-in-args.rs index b0278476998..081d6caaa13 100644 --- a/src/test/compile-fail/no-patterns-in-args.rs +++ b/src/test/compile-fail/no-patterns-in-args.rs @@ -11,21 +11,17 @@ extern { fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations //~^ NOTE pattern not allowed in foreign function - //~| NOTE this is a recent error fn f2(&arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations //~^ NOTE pattern not allowed in foreign function fn f3(arg @ _: u8); //~ ERROR patterns aren't allowed in foreign function declarations //~^ NOTE pattern not allowed in foreign function - //~| NOTE this is a recent error fn g1(arg: u8); // OK fn g2(_: u8); // OK // fn g3(u8); // Not yet } type A1 = fn(mut arg: u8); //~ ERROR patterns aren't allowed in function pointer types - //~^ NOTE this is a recent error type A2 = fn(&arg: u8); //~ ERROR patterns aren't allowed in function pointer types - //~^ NOTE this is a recent error type B1 = fn(arg: u8); // OK type B2 = fn(_: u8); // OK type B3 = fn(u8); // OK |
