Skip to content

Commit

Permalink
Properly enforce the "patterns aren't allowed in foreign functions" c…
Browse files Browse the repository at this point in the history
…heck

Apply the same check to function pointer types
  • Loading branch information
petrochenkov committed Aug 2, 2016
1 parent e5cc046 commit 5c88efc
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 6 deletions.
42 changes: 36 additions & 6 deletions src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(..) => {}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_passes/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
30 changes: 30 additions & 0 deletions src/test/compile-fail/no-patterns-in-args.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 5c88efc

Please sign in to comment.