diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-07-17 00:15:15 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-08-03 01:29:53 +0300 |
| commit | 5c88efc0da9d5222965fe8eaeb1bf48897da7ec1 (patch) | |
| tree | 2633404c8d12fda51b46cf4556dfdfb6d408df42 | |
| parent | e5cc04665924c73c94e1de071135247102d76865 (diff) | |
| download | rust-5c88efc0da9d5222965fe8eaeb1bf48897da7ec1.tar.gz rust-5c88efc0da9d5222965fe8eaeb1bf48897da7ec1.zip | |
Properly enforce the "patterns aren't allowed in foreign functions" check
Apply the same check to function pointer types
| -rw-r--r-- | src/librustc_passes/ast_validation.rs | 42 | ||||
| -rw-r--r-- | src/librustc_passes/diagnostics.rs | 1 | ||||
| -rw-r--r-- | src/test/compile-fail/no-patterns-in-args.rs | 30 |
3 files changed, 67 insertions, 6 deletions
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 300750a625d..d2cf48eddeb 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -55,6 +55,17 @@ impl<'a> AstValidator<'a> { err.emit(); } } + + fn check_decl_no_pat<ReportFn: Fn(Span, bool)>(&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), + } + } + } } impl<'a> Visitor for AstValidator<'a> { @@ -82,6 +93,23 @@ impl<'a> Visitor for AstValidator<'a> { visit::walk_expr(self, expr) } + fn visit_ty(&mut self, ty: &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(); + }); + } + _ => {} + } + + visit::walk_ty(self, ty) + } + fn visit_path(&mut self, path: &Path, id: NodeId) { if path.global && path.segments.len() > 0 { let ident = path.segments[0].identifier; @@ -138,13 +166,15 @@ impl<'a> Visitor for AstValidator<'a> { fn visit_foreign_item(&mut self, fi: &ForeignItem) { match fi.node { ForeignItemKind::Fn(ref decl, _) => { - for arg in &decl.inputs { - match arg.pat.node { - PatKind::Ident(..) | PatKind::Wild => {} - _ => span_err!(self.session, arg.pat.span, E0130, - "patterns aren't allowed in foreign function declarations") + 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"); + if is_recent { + err.span_note(span, "this is a recent error, see \ + issue #35203 for more details"); } - } + err.emit(); + }); } ForeignItemKind::Static(..) => {} } diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index d6865ba13fc..3e2dd477bcc 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -220,4 +220,5 @@ pub impl Foo for Bar { register_diagnostics! { E0472, // asm! is unsupported on this target + E0561, // patterns aren't allowed in function pointer types } diff --git a/src/test/compile-fail/no-patterns-in-args.rs b/src/test/compile-fail/no-patterns-in-args.rs new file mode 100644 index 00000000000..3edbdf4ebc9 --- /dev/null +++ b/src/test/compile-fail/no-patterns-in-args.rs @@ -0,0 +1,30 @@ +// Copyright 2016 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. + +extern { + fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations + //~^ NOTE this is a recent error + fn f2(&arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations + fn f3(arg @ _: u8); //~ ERROR patterns aren't allowed in foreign function declarations + //~^ 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 + +fn main() {} |
