]> git.lizzy.rs Git - rust.git/commitdiff
Properly enforce the "patterns aren't allowed in foreign functions" check
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 16 Jul 2016 21:15:15 +0000 (00:15 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Tue, 2 Aug 2016 22:29:53 +0000 (01:29 +0300)
Apply the same check to function pointer types

src/librustc_passes/ast_validation.rs
src/librustc_passes/diagnostics.rs
src/test/compile-fail/no-patterns-in-args.rs [new file with mode: 0644]

index 300750a625d5b057930a64e299d179e3d9206bff..d2cf48eddebac2de42b84571262075df045d4af7 100644 (file)
@@ -55,6 +55,17 @@ fn invalid_visibility(&self, vis: &Visibility, span: Span, note: Option<&str>) {
             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 @@ fn visit_expr(&mut self, expr: &Expr) {
         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 @@ fn visit_item(&mut self, item: &Item) {
     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(..) => {}
         }
index d6865ba13fc274ecc8021d521c4daa86831c5d07..3e2dd477bccf089f0e40b0598246ce9c120b39e2 100644 (file)
@@ -220,4 +220,5 @@ pub fn foo() {}
 
 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 (file)
index 0000000..3edbdf4
--- /dev/null
@@ -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() {}