Properly enforce the "patterns aren't allowed in foreign functions" check

Apply the same check to function pointer types
This commit is contained in:
Vadim Petrochenkov 2016-07-17 00:15:15 +03:00
parent e5cc046659
commit 5c88efc0da
3 changed files with 67 additions and 6 deletions

View File

@ -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(..) => {}
}

View File

@ -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
}

View File

@ -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() {}