@@ -90,7 +90,7 @@ macro_rules! declare_features {
9090 self . macros_in_extern || self . proc_macro_path_invoc ||
9191 self . proc_macro_mod || self . proc_macro_expr ||
9292 self . proc_macro_non_items || self . proc_macro_gen ||
93- self . stmt_expr_attributes
93+ self . stmt_expr_attributes || self . unrestricted_attribute_tokens
9494 }
9595 }
9696 } ;
@@ -504,6 +504,9 @@ declare_features! (
504504 // impl<I:Iterator> Iterator for &mut Iterator
505505 // impl Debug for Foo<'_>
506506 ( active, impl_header_lifetime_elision, "1.30.0" , Some ( 15872 ) , Some ( Edition :: Edition2018 ) ) ,
507+
508+ // Support for arbitrary delimited token streams in non-macro attributes.
509+ ( active, unrestricted_attribute_tokens, "1.30.0" , Some ( 44690 ) , None ) ,
507510) ;
508511
509512declare_features ! (
@@ -721,8 +724,7 @@ pub fn is_builtin_attr_name(name: ast::Name) -> bool {
721724}
722725
723726pub fn is_builtin_attr ( attr : & ast:: Attribute ) -> bool {
724- BUILTIN_ATTRIBUTES . iter ( ) . any ( |& ( builtin_name, _, _) | attr. path == builtin_name) ||
725- attr. name ( ) . as_str ( ) . starts_with ( "rustc_" )
727+ BUILTIN_ATTRIBUTES . iter ( ) . any ( |& ( builtin_name, _, _) | attr. path == builtin_name)
726728}
727729
728730// Attributes that have a special meaning to rustc or rustdoc
@@ -1521,25 +1523,27 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
15211523 }
15221524 }
15231525
1524- // allow attr_literals in #[repr(align(x))] and #[repr(packed(n))]
1525- let mut allow_attr_literal = false ;
1526- if attr. path == "repr" {
1527- if let Some ( content) = attr. meta_item_list ( ) {
1528- allow_attr_literal = content. iter ( ) . any (
1529- |c| c. check_name ( "align" ) || c. check_name ( "packed" ) ) ;
1530- }
1531- }
1532-
1533- if self . context . features . use_extern_macros ( ) && attr:: is_known ( attr) {
1534- return
1535- }
1526+ match attr. parse_meta ( self . context . parse_sess ) {
1527+ Ok ( meta) => {
1528+ // allow attr_literals in #[repr(align(x))] and #[repr(packed(n))]
1529+ let mut allow_attr_literal = false ;
1530+ if attr. path == "repr" {
1531+ if let Some ( content) = meta. meta_item_list ( ) {
1532+ allow_attr_literal = content. iter ( ) . any (
1533+ |c| c. check_name ( "align" ) || c. check_name ( "packed" ) ) ;
1534+ }
1535+ }
15361536
1537- if !allow_attr_literal {
1538- let meta = panictry ! ( attr. parse_meta( self . context. parse_sess) ) ;
1539- if contains_novel_literal ( & meta) {
1540- gate_feature_post ! ( & self , attr_literals, attr. span,
1541- "non-string literals in attributes, or string \
1542- literals in top-level positions, are experimental") ;
1537+ if !allow_attr_literal && contains_novel_literal ( & meta) {
1538+ gate_feature_post ! ( & self , attr_literals, attr. span,
1539+ "non-string literals in attributes, or string \
1540+ literals in top-level positions, are experimental") ;
1541+ }
1542+ }
1543+ Err ( mut err) => {
1544+ err. cancel ( ) ;
1545+ gate_feature_post ! ( & self , unrestricted_attribute_tokens, attr. span,
1546+ "arbitrary tokens in non-macro attributes are unstable" ) ;
15431547 }
15441548 }
15451549 }
0 commit comments