Skip to content

Commit 5c88efc

Browse files
committed
Properly enforce the "patterns aren't allowed in foreign functions" check
Apply the same check to function pointer types
1 parent e5cc046 commit 5c88efc

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

src/librustc_passes/ast_validation.rs

+36-6
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ impl<'a> AstValidator<'a> {
5555
err.emit();
5656
}
5757
}
58+
59+
fn check_decl_no_pat<ReportFn: Fn(Span, bool)>(&self, decl: &FnDecl, report_err: ReportFn) {
60+
for arg in &decl.inputs {
61+
match arg.pat.node {
62+
PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), _, None) |
63+
PatKind::Wild => {}
64+
PatKind::Ident(..) => report_err(arg.pat.span, true),
65+
_ => report_err(arg.pat.span, false),
66+
}
67+
}
68+
}
5869
}
5970

6071
impl<'a> Visitor for AstValidator<'a> {
@@ -82,6 +93,23 @@ impl<'a> Visitor for AstValidator<'a> {
8293
visit::walk_expr(self, expr)
8394
}
8495

96+
fn visit_ty(&mut self, ty: &Ty) {
97+
match ty.node {
98+
TyKind::BareFn(ref bfty) => {
99+
self.check_decl_no_pat(&bfty.decl, |span, _| {
100+
let mut err = struct_span_err!(self.session, span, E0561,
101+
"patterns aren't allowed in function pointer types");
102+
err.span_note(span, "this is a recent error, see \
103+
issue #35203 for more details");
104+
err.emit();
105+
});
106+
}
107+
_ => {}
108+
}
109+
110+
visit::walk_ty(self, ty)
111+
}
112+
85113
fn visit_path(&mut self, path: &Path, id: NodeId) {
86114
if path.global && path.segments.len() > 0 {
87115
let ident = path.segments[0].identifier;
@@ -138,13 +166,15 @@ impl<'a> Visitor for AstValidator<'a> {
138166
fn visit_foreign_item(&mut self, fi: &ForeignItem) {
139167
match fi.node {
140168
ForeignItemKind::Fn(ref decl, _) => {
141-
for arg in &decl.inputs {
142-
match arg.pat.node {
143-
PatKind::Ident(..) | PatKind::Wild => {}
144-
_ => span_err!(self.session, arg.pat.span, E0130,
145-
"patterns aren't allowed in foreign function declarations")
169+
self.check_decl_no_pat(decl, |span, is_recent| {
170+
let mut err = struct_span_err!(self.session, span, E0130,
171+
"patterns aren't allowed in foreign function declarations");
172+
if is_recent {
173+
err.span_note(span, "this is a recent error, see \
174+
issue #35203 for more details");
146175
}
147-
}
176+
err.emit();
177+
});
148178
}
149179
ForeignItemKind::Static(..) => {}
150180
}

src/librustc_passes/diagnostics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,5 @@ pub impl Foo for Bar {
220220

221221
register_diagnostics! {
222222
E0472, // asm! is unsupported on this target
223+
E0561, // patterns aren't allowed in function pointer types
223224
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern {
12+
fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations
13+
//~^ NOTE this is a recent error
14+
fn f2(&arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations
15+
fn f3(arg @ _: u8); //~ ERROR patterns aren't allowed in foreign function declarations
16+
//~^ NOTE this is a recent error
17+
fn g1(arg: u8); // OK
18+
fn g2(_: u8); // OK
19+
// fn g3(u8); // Not yet
20+
}
21+
22+
type A1 = fn(mut arg: u8); //~ ERROR patterns aren't allowed in function pointer types
23+
//~^ NOTE this is a recent error
24+
type A2 = fn(&arg: u8); //~ ERROR patterns aren't allowed in function pointer types
25+
//~^ NOTE this is a recent error
26+
type B1 = fn(arg: u8); // OK
27+
type B2 = fn(_: u8); // OK
28+
type B3 = fn(u8); // OK
29+
30+
fn main() {}

0 commit comments

Comments
 (0)