@@ -4,15 +4,12 @@ use std::ops::{Deref, DerefMut};
44use  std:: sync:: LazyLock ; 
55
66use  private:: Sealed ; 
7- use  rustc_ast:: { self  as  ast,  LitKind ,  MetaItemLit ,  NodeId ,   Safety } ; 
7+ use  rustc_ast:: { self  as  ast,  LitKind ,  MetaItemLit ,  NodeId } ; 
88use  rustc_attr_data_structures:: AttributeKind ; 
99use  rustc_attr_data_structures:: lints:: { AttributeLint ,  AttributeLintKind } ; 
10- use  rustc_errors:: { Applicability ,  DiagCtxtHandle ,  Diagnostic } ; 
11- use  rustc_feature:: { 
12-     AttributeSafety ,  AttributeTemplate ,  BUILTIN_ATTRIBUTE_MAP ,  BuiltinAttribute ,  Features , 
13- } ; 
10+ use  rustc_errors:: { DiagCtxtHandle ,  Diagnostic } ; 
11+ use  rustc_feature:: { AttributeTemplate ,  Features } ; 
1412use  rustc_hir:: { AttrArgs ,  AttrItem ,  AttrPath ,  Attribute ,  HashIgnoredAttrId ,  HirId } ; 
15- use  rustc_parse:: validate_attr:: { is_attr_template_compatible,  parse_meta} ; 
1613use  rustc_session:: Session ; 
1714use  rustc_span:: { DUMMY_SP ,  ErrorGuaranteed ,  Span ,  Symbol ,  sym} ; 
1815
@@ -59,10 +56,7 @@ use crate::attributes::traits::{
5956use  crate :: attributes:: transparency:: TransparencyParser ; 
6057use  crate :: attributes:: { AttributeParser  as  _,  Combine ,  Single ,  WithoutArgs } ; 
6158use  crate :: parser:: { ArgParser ,  MetaItemParser ,  PathParser } ; 
62- use  crate :: session_diagnostics:: { 
63-     AttributeParseError ,  AttributeParseErrorReason ,  InvalidAttrUnsafe ,  UnknownMetaItem , 
64-     UnsafeAttrOutsideUnsafe ,  UnsafeAttrOutsideUnsafeSuggestion , 
65- } ; 
59+ use  crate :: session_diagnostics:: { AttributeParseError ,  AttributeParseErrorReason ,  UnknownMetaItem } ; 
6660
6761macro_rules!  group_type { 
6862    ( $stage:  ty)  => { 
@@ -753,6 +747,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
753747        & self . sess 
754748    } 
755749
750+     pub ( crate )  fn  stage ( & self )  -> & S  { 
751+         & self . stage 
752+     } 
753+ 
756754    pub ( crate )  fn  features ( & self )  -> & ' sess  Features  { 
757755        self . features . expect ( "features not available at this point in the compiler" ) 
758756    } 
@@ -897,201 +895,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
897895        attributes
898896    } 
899897
900-     fn  validate_attribute ( 
901-         & self , 
902-         attr :  & ast:: Attribute , 
903-         target_id :  S :: Id , 
904-         emit_lint :  & mut  impl  FnMut ( AttributeLint < S :: Id > ) , 
905-         check_attr_template :  bool , 
906-     )  -> bool  { 
907-         if  !self . stage . should_emit_errors ( )  { 
908-             return  true ; 
909-         } 
910-         let  ast:: AttrKind :: Normal ( normal)  = & attr. kind  else  {  return  true  } ; 
911-         if  attr. has_name ( sym:: cfg_trace)  || attr. has_name ( sym:: cfg_attr_trace)  { 
912-             return  true ; 
913-         } 
914-         self . check_attribute_safety ( attr,  target_id,  emit_lint) ; 
915- 
916-         let  builtin_attr_info =
917-             attr. ident ( ) . and_then ( |ident| BUILTIN_ATTRIBUTE_MAP . get ( & ident. name ) ) ; 
918-         if  ( builtin_attr_info. is_none ( )  || attr. has_name ( sym:: rustc_dummy) ) 
919-             && !matches ! ( normal. item. args,  rustc_ast:: AttrArgs :: Eq  {  .. } ) 
920-         { 
921-             return  true ; 
922-         } 
923- 
924-         // FIXME 
925-         let  meta = match  parse_meta ( & self . sess . psess ,  attr)  { 
926-             Ok ( meta)  => meta, 
927-             Err ( err)  => { 
928-                 err. emit ( ) ; 
929-                 return  false ; 
930-             } 
931-         } ; 
932-         if  check_attr_template { 
933-             return  true ; 
934-         } 
935- 
936-         if  let  Some ( BuiltinAttribute  {  name,  template,  .. } )  = builtin_attr_info { 
937-             // FIXME when all attributes are parsed, this check can be removed 
938-             if  !is_attr_template_compatible ( & template,  & meta. kind )  { 
939-                 self . emit_malformed_unparsed_attribute ( 
940-                     attr. style ,  meta. span ,  * name,  * template,  target_id,  emit_lint, 
941-                 ) ; 
942-                 return  false 
943-             } 
944-         } 
945- 
946-         true 
947-     } 
948- 
949-     fn  check_attribute_safety ( 
950-         & self , 
951-         attr :  & ast:: Attribute , 
952-         id :  S :: Id , 
953-         emit_lint :  & mut  impl  FnMut ( AttributeLint < S :: Id > ) , 
954-     )  { 
955-         let  builtin_attr_info =
956-             attr. ident ( ) . and_then ( |ident| BUILTIN_ATTRIBUTE_MAP . get ( & ident. name ) ) ; 
957- 
958-         let  builtin_attr_safety = builtin_attr_info. map ( |x| x. safety ) ; 
959- 
960-         let  attr_item = attr. get_normal_item ( ) ; 
961-         match  ( builtin_attr_safety,  attr_item. unsafety )  { 
962-             // - Unsafe builtin attribute 
963-             // - User wrote `#[unsafe(..)]`, which is permitted on any edition 
964-             ( Some ( AttributeSafety :: Unsafe  {  .. } ) ,  Safety :: Unsafe ( ..) )  => { 
965-                 // OK 
966-             } 
967- 
968-             // - Unsafe builtin attribute 
969-             // - User did not write `#[unsafe(..)]` 
970-             ( Some ( AttributeSafety :: Unsafe  {  unsafe_since } ) ,  Safety :: Default )  => { 
971-                 let  path_span = attr_item. path . span ; 
972- 
973-                 // If the `attr_item`'s span is not from a macro, then just suggest 
974-                 // wrapping it in `unsafe(...)`. Otherwise, we suggest putting the 
975-                 // `unsafe(`, `)` right after and right before the opening and closing 
976-                 // square bracket respectively. 
977-                 let  diag_span = attr_item. span ( ) ; 
978- 
979-                 // Attributes can be safe in earlier editions, and become unsafe in later ones. 
980-                 // 
981-                 // Use the span of the attribute's name to determine the edition: the span of the 
982-                 // attribute as a whole may be inaccurate if it was emitted by a macro. 
983-                 // 
984-                 // See https://github.com/rust-lang/rust/issues/142182. 
985-                 let  emit_error = match  unsafe_since { 
986-                     None  => true , 
987-                     Some ( unsafe_since)  => path_span. edition ( )  >= unsafe_since, 
988-                 } ; 
989- 
990-                 if  emit_error { 
991-                     self . dcx ( ) . emit_err ( UnsafeAttrOutsideUnsafe  { 
992-                         span :  path_span, 
993-                         suggestion :  UnsafeAttrOutsideUnsafeSuggestion  { 
994-                             left :  diag_span. shrink_to_lo ( ) , 
995-                             right :  diag_span. shrink_to_hi ( ) , 
996-                         } , 
997-                     } ) ; 
998-                 }  else  { 
999-                     emit_lint ( AttributeLint  { 
1000-                         id, 
1001-                         span :  path_span, 
1002-                         kind :  AttributeLintKind :: UnsafeAttrOutsideUnsafe  { 
1003-                             attribute_name_span :  path_span, 
1004-                             sugg_spans :  ( diag_span. shrink_to_lo ( ) ,  diag_span. shrink_to_hi ( ) ) , 
1005-                         } , 
1006-                     } ) ; 
1007-                 } 
1008-             } 
1009- 
1010-             // - Normal builtin attribute, or any non-builtin attribute 
1011-             // - All non-builtin attributes are currently considered safe; writing `#[unsafe(..)]` is 
1012-             //   not permitted on non-builtin attributes or normal builtin attributes 
1013-             ( Some ( AttributeSafety :: Normal )  | None ,  Safety :: Unsafe ( unsafe_span) )  => { 
1014-                 self . dcx ( ) . emit_err ( InvalidAttrUnsafe  { 
1015-                     span :  unsafe_span, 
1016-                     name :  attr_item. path . clone ( ) , 
1017-                 } ) ; 
1018-             } 
1019- 
1020-             // - Normal builtin attribute 
1021-             // - No explicit `#[unsafe(..)]` written. 
1022-             ( Some ( AttributeSafety :: Normal ) ,  Safety :: Default )  => { 
1023-                 // OK 
1024-             } 
1025- 
1026-             // - Non-builtin attribute 
1027-             // - No explicit `#[unsafe(..)]` written. 
1028-             ( None ,  Safety :: Default )  => { 
1029-                 // OK 
1030-             } 
1031- 
1032-             ( 
1033-                 Some ( AttributeSafety :: Unsafe  {  .. }  | AttributeSafety :: Normal )  | None , 
1034-                 Safety :: Safe ( ..) , 
1035-             )  => { 
1036-                 self . sess . psess . dcx ( ) . span_delayed_bug ( 
1037-                     attr_item. span ( ) , 
1038-                     "`check_attribute_safety` does not expect `Safety::Safe` on attributes" , 
1039-                 ) ; 
1040-             } 
1041-         } 
1042-     } 
1043- 
1044-     fn  emit_malformed_unparsed_attribute ( 
1045-         & self , 
1046-         style :  ast:: AttrStyle , 
1047-         span :  Span , 
1048-         name :  Symbol , 
1049-         template :  AttributeTemplate , 
1050-         target_id :  S :: Id , 
1051-         emit_lint :  & mut  impl  FnMut ( AttributeLint < S :: Id > ) , 
1052-     )  { 
1053-         // Some of previously accepted forms were used in practice, 
1054-         // report them as warnings for now. 
1055-         let  should_warn = |name| matches ! ( name,  sym:: doc | sym:: link | sym:: test | sym:: bench) ; 
1056- 
1057-         let  error_msg = format ! ( "malformed `{name}` attribute input" ) ; 
1058-         let  mut  suggestions = vec ! [ ] ; 
1059-         let  inner = if  style == ast:: AttrStyle :: Inner  {  "!"  }  else  {  ""  } ; 
1060-         if  template. word  { 
1061-             suggestions. push ( format ! ( "#{inner}[{name}]" ) ) ; 
1062-         } 
1063-         if  let  Some ( descr)  = template. list  { 
1064-             suggestions. push ( format ! ( "#{inner}[{name}({descr})]" ) ) ; 
1065-         } 
1066-         suggestions. extend ( template. one_of . iter ( ) . map ( |& word| format ! ( "#{inner}[{name}({word})]" ) ) ) ; 
1067-         if  let  Some ( descr)  = template. name_value_str  { 
1068-             suggestions. push ( format ! ( "#{inner}[{name} = \" {descr}\" ]" ) ) ; 
1069-         } 
1070-         if  should_warn ( name)  { 
1071-             emit_lint ( AttributeLint  { 
1072-                 id :  target_id, 
1073-                 span, 
1074-                 kind :  AttributeLintKind :: IllFormedAttributeInput  {  suggestions } , 
1075-             } ) ; 
1076-         }  else  { 
1077-             suggestions. sort ( ) ; 
1078-             self . sess 
1079-                 . dcx ( ) 
1080-                 . struct_span_err ( span,  error_msg) 
1081-                 . with_span_suggestions ( 
1082-                     span, 
1083-                     if  suggestions. len ( )  == 1  { 
1084-                         "must be of the form" 
1085-                     }  else  { 
1086-                         "the following are the possible correct uses" 
1087-                     } , 
1088-                     suggestions, 
1089-                     Applicability :: HasPlaceholders , 
1090-                 ) 
1091-                 . emit ( ) ; 
1092-         } 
1093-     } 
1094- 
1095898    /// Returns whether there is a parser for an attribute with this name 
1096899pub  fn  is_parsed_attribute ( path :  & [ Symbol ] )  -> bool  { 
1097900        Late :: parsers ( ) . 0 . contains_key ( path) 
0 commit comments