@@ -11,6 +11,7 @@ use rustc_hir::attrs::AttributeKind;
1111use rustc_hir:: lints:: { AttributeLint , AttributeLintKind } ;
1212use rustc_hir:: { AttrArgs , AttrItem , AttrPath , Attribute , HashIgnoredAttrId , HirId } ;
1313use rustc_session:: Session ;
14+ use rustc_session:: lint:: BuiltinLintDiag ;
1415use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span , Symbol , sym} ;
1516
1617use crate :: attributes:: allow_unstable:: {
@@ -22,6 +23,7 @@ use crate::attributes::codegen_attrs::{
2223 TargetFeatureParser , TrackCallerParser , UsedParser ,
2324} ;
2425use crate :: attributes:: confusables:: ConfusablesParser ;
26+ use crate :: attributes:: crate_level:: CrateNameParser ;
2527use crate :: attributes:: deprecation:: DeprecationParser ;
2628use crate :: attributes:: dummy:: DummyParser ;
2729use crate :: attributes:: inline:: { InlineParser , RustcForceInlineParser } ;
@@ -59,6 +61,7 @@ use crate::attributes::traits::{
5961} ;
6062use crate :: attributes:: transparency:: TransparencyParser ;
6163use crate :: attributes:: { AttributeParser as _, Combine , Single , WithoutArgs } ;
64+ use crate :: lints:: lint_name;
6265use crate :: parser:: { ArgParser , MetaItemParser , PathParser } ;
6366use crate :: session_diagnostics:: { AttributeParseError , AttributeParseErrorReason , UnknownMetaItem } ;
6467
@@ -157,6 +160,7 @@ attribute_parsers!(
157160
158161 // tidy-alphabetical-start
159162 Single <CoverageParser >,
163+ Single <CrateNameParser >,
160164 Single <DeprecationParser >,
161165 Single <DummyParser >,
162166 Single <ExportNameParser >,
@@ -301,7 +305,9 @@ pub struct AcceptContext<'f, 'sess, S: Stage> {
301305 /// The span of the attribute currently being parsed
302306 pub ( crate ) attr_span : Span ,
303307
308+ /// Whether it is an inner or outer attribute
304309 pub ( crate ) attr_style : AttrStyle ,
310+
305311 /// The expected structure of the attribute.
306312 ///
307313 /// Used in reporting errors to give a hint to users what the attribute *should* look like.
@@ -689,22 +695,48 @@ impl<'sess> AttributeParser<'sess, Early> {
689695 target_span : Span ,
690696 target_node_id : NodeId ,
691697 features : Option < & ' sess Features > ,
698+ ) -> Option < Attribute > {
699+ Self :: parse_limited_should_emit (
700+ sess,
701+ attrs,
702+ sym,
703+ target_span,
704+ target_node_id,
705+ features,
706+ ShouldEmit :: Nothing ,
707+ )
708+ }
709+
710+ /// Usually you want `parse_limited`, which defaults to no errors.
711+ pub fn parse_limited_should_emit (
712+ sess : & ' sess Session ,
713+ attrs : & [ ast:: Attribute ] ,
714+ sym : Symbol ,
715+ target_span : Span ,
716+ target_node_id : NodeId ,
717+ features : Option < & ' sess Features > ,
718+ should_emit : ShouldEmit ,
692719 ) -> Option < Attribute > {
693720 let mut p = Self {
694721 features,
695722 tools : Vec :: new ( ) ,
696723 parse_only : Some ( sym) ,
697724 sess,
698- stage : Early { emit_errors : ShouldEmit :: Nothing } ,
725+ stage : Early { emit_errors : should_emit } ,
699726 } ;
700727 let mut parsed = p. parse_attribute_list (
701728 attrs,
702729 target_span,
703730 target_node_id,
704731 OmitDoc :: Skip ,
705732 std:: convert:: identity,
706- |_lint| {
707- panic ! ( "can't emit lints here for now (nothing uses this atm)" ) ;
733+ |AttributeLint { id, span, kind } | {
734+ sess. psess . buffer_lint (
735+ lint_name ( & kind) ,
736+ span,
737+ id,
738+ BuiltinLintDiag :: AttributeLint ( kind) ,
739+ ) ;
708740 } ,
709741 ) ;
710742 assert ! ( parsed. len( ) <= 1 ) ;
0 commit comments