@@ -14,6 +14,7 @@ use rustc::session::Session;
14
14
use rustc_data_structures:: fx:: FxHashMap ;
15
15
use syntax:: ast:: * ;
16
16
use syntax:: attr;
17
+ use syntax:: feature_gate:: is_builtin_attr;
17
18
use syntax:: source_map:: Spanned ;
18
19
use syntax:: symbol:: { kw, sym} ;
19
20
use syntax:: ptr:: P ;
@@ -365,6 +366,29 @@ impl<'a> AstValidator<'a> {
365
366
_ => None ,
366
367
}
367
368
}
369
+
370
+ fn check_fn_decl ( & self , fn_decl : & FnDecl ) {
371
+ fn_decl
372
+ . inputs
373
+ . iter ( )
374
+ . flat_map ( |i| i. attrs . as_ref ( ) )
375
+ . filter ( |attr| {
376
+ let arr = [ sym:: allow, sym:: cfg, sym:: cfg_attr, sym:: deny, sym:: forbid, sym:: warn] ;
377
+ !arr. contains ( & attr. name_or_empty ( ) ) && is_builtin_attr ( attr)
378
+ } )
379
+ . for_each ( |attr| if attr. is_sugared_doc {
380
+ let mut err = self . err_handler ( ) . struct_span_err (
381
+ attr. span ,
382
+ "documentation comments cannot be applied to function parameters"
383
+ ) ;
384
+ err. span_label ( attr. span , "doc comments are not allowed here" ) ;
385
+ err. emit ( ) ;
386
+ }
387
+ else {
388
+ self . err_handler ( ) . span_err ( attr. span , "allow, cfg, cfg_attr, deny, \
389
+ forbid, and warn are the only allowed built-in attributes in function parameters")
390
+ } ) ;
391
+ }
368
392
}
369
393
370
394
enum GenericPosition {
@@ -470,6 +494,9 @@ fn validate_generics_order<'a>(
470
494
impl < ' a > Visitor < ' a > for AstValidator < ' a > {
471
495
fn visit_expr ( & mut self , expr : & ' a Expr ) {
472
496
match expr. node {
497
+ ExprKind :: Closure ( _, _, _, ref fn_decl, _, _) => {
498
+ self . check_fn_decl ( fn_decl) ;
499
+ }
473
500
ExprKind :: IfLet ( _, ref expr, _, _) | ExprKind :: WhileLet ( _, ref expr, _, _) =>
474
501
self . while_if_let_ambiguity ( & expr) ,
475
502
ExprKind :: InlineAsm ( ..) if !self . session . target . target . options . allow_asm => {
@@ -484,6 +511,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
484
511
fn visit_ty ( & mut self , ty : & ' a Ty ) {
485
512
match ty. node {
486
513
TyKind :: BareFn ( ref bfty) => {
514
+ self . check_fn_decl ( & bfty. decl ) ;
487
515
self . check_decl_no_pat ( & bfty. decl , |span, _| {
488
516
struct_span_err ! ( self . session, span, E0561 ,
489
517
"patterns aren't allowed in function pointer types" ) . emit ( ) ;
@@ -601,10 +629,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
601
629
. note ( "only trait implementations may be annotated with default" ) . emit ( ) ;
602
630
}
603
631
}
604
- ItemKind :: Fn ( _, ref header, ref generics, _) => {
632
+ ItemKind :: Fn ( ref decl, ref header, ref generics, _) => {
633
+ self . visit_fn_header ( header) ;
634
+ self . check_fn_decl ( decl) ;
605
635
// We currently do not permit const generics in `const fn`, as
606
636
// this is tantamount to allowing compile-time dependent typing.
607
- self . visit_fn_header ( header) ;
608
637
if header. constness . node == Constness :: Const {
609
638
// Look for const generics and error if we find any.
610
639
for param in & generics. params {
@@ -657,6 +686,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
657
686
self . no_questions_in_bounds ( bounds, "supertraits" , true ) ;
658
687
for trait_item in trait_items {
659
688
if let TraitItemKind :: Method ( ref sig, ref block) = trait_item. node {
689
+ self . check_fn_decl ( & sig. decl ) ;
660
690
self . check_trait_fn_not_async ( trait_item. span , sig. header . asyncness . node ) ;
661
691
self . check_trait_fn_not_const ( sig. header . constness ) ;
662
692
if block. is_none ( ) {
@@ -711,6 +741,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
711
741
fn visit_foreign_item ( & mut self , fi : & ' a ForeignItem ) {
712
742
match fi. node {
713
743
ForeignItemKind :: Fn ( ref decl, _) => {
744
+ self . check_fn_decl ( decl) ;
714
745
self . check_decl_no_pat ( decl, |span, _| {
715
746
struct_span_err ! ( self . session, span, E0130 ,
716
747
"patterns aren't allowed in foreign function declarations" )
@@ -864,6 +895,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
864
895
"`async fn` is not permitted in the 2015 edition" ) . emit ( ) ;
865
896
}
866
897
}
898
+
899
+ fn visit_impl_item ( & mut self , ii : & ' a ImplItem ) {
900
+ match ii. node {
901
+ ImplItemKind :: Method ( ref sig, _) => {
902
+ self . check_fn_decl ( & sig. decl ) ;
903
+ }
904
+ _ => { }
905
+ }
906
+ visit:: walk_impl_item ( self , ii) ;
907
+ }
867
908
}
868
909
869
910
pub fn check_crate ( session : & Session , krate : & Crate ) -> ( bool , bool ) {
0 commit comments