@@ -337,8 +337,16 @@ pub struct Late;
337337/// Gives [`AttributeParser`]s enough information to create errors, for example.
338338pub struct AcceptContext < ' f , ' sess , S : Stage > {
339339 pub ( crate ) shared : SharedContext < ' f , ' sess , S > ,
340- /// The span of the attribute currently being parsed
340+
341+ /// The outer span of the attribute currently being parsed
342+ /// #[attribute(...)]
343+ /// ^^^^^^^^^^^^^^^^^ outer span
344+ /// For attributes in `cfg_attr`, the outer span and inner spans are equal.
341345 pub ( crate ) attr_span : Span ,
346+ /// The inner span of the attribute currently being parsed
347+ /// #[attribute(...)]
348+ /// ^^^^^^^^^^^^^^ inner span
349+ pub ( crate ) inner_span : Span ,
342350
343351 /// Whether it is an inner or outer attribute
344352 pub ( crate ) attr_style : AttrStyle ,
@@ -427,7 +435,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
427435 i. kind . is_bytestr ( ) . then ( || self . sess ( ) . source_map ( ) . start_point ( i. span ) )
428436 } ) ,
429437 } ,
430- attr_style : self . attr_style ,
438+ suggestions : self . suggestions ( ) ,
431439 } )
432440 }
433441
@@ -438,7 +446,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
438446 template : self . template . clone ( ) ,
439447 attribute : self . attr_path . clone ( ) ,
440448 reason : AttributeParseErrorReason :: ExpectedIntegerLiteral ,
441- attr_style : self . attr_style ,
449+ suggestions : self . suggestions ( ) ,
442450 } )
443451 }
444452
@@ -449,7 +457,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
449457 template : self . template . clone ( ) ,
450458 attribute : self . attr_path . clone ( ) ,
451459 reason : AttributeParseErrorReason :: ExpectedList ,
452- attr_style : self . attr_style ,
460+ suggestions : self . suggestions ( ) ,
453461 } )
454462 }
455463
@@ -460,7 +468,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
460468 template : self . template . clone ( ) ,
461469 attribute : self . attr_path . clone ( ) ,
462470 reason : AttributeParseErrorReason :: ExpectedNoArgs ,
463- attr_style : self . attr_style ,
471+ suggestions : self . suggestions ( ) ,
464472 } )
465473 }
466474
@@ -472,7 +480,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
472480 template : self . template . clone ( ) ,
473481 attribute : self . attr_path . clone ( ) ,
474482 reason : AttributeParseErrorReason :: ExpectedIdentifier ,
475- attr_style : self . attr_style ,
483+ suggestions : self . suggestions ( ) ,
476484 } )
477485 }
478486
@@ -485,7 +493,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
485493 template : self . template . clone ( ) ,
486494 attribute : self . attr_path . clone ( ) ,
487495 reason : AttributeParseErrorReason :: ExpectedNameValue ( name) ,
488- attr_style : self . attr_style ,
496+ suggestions : self . suggestions ( ) ,
489497 } )
490498 }
491499
@@ -497,7 +505,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
497505 template : self . template . clone ( ) ,
498506 attribute : self . attr_path . clone ( ) ,
499507 reason : AttributeParseErrorReason :: DuplicateKey ( key) ,
500- attr_style : self . attr_style ,
508+ suggestions : self . suggestions ( ) ,
501509 } )
502510 }
503511
@@ -510,7 +518,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
510518 template : self . template . clone ( ) ,
511519 attribute : self . attr_path . clone ( ) ,
512520 reason : AttributeParseErrorReason :: UnexpectedLiteral ,
513- attr_style : self . attr_style ,
521+ suggestions : self . suggestions ( ) ,
514522 } )
515523 }
516524
@@ -521,7 +529,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
521529 template : self . template . clone ( ) ,
522530 attribute : self . attr_path . clone ( ) ,
523531 reason : AttributeParseErrorReason :: ExpectedSingleArgument ,
524- attr_style : self . attr_style ,
532+ suggestions : self . suggestions ( ) ,
525533 } )
526534 }
527535
@@ -532,7 +540,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
532540 template : self . template . clone ( ) ,
533541 attribute : self . attr_path . clone ( ) ,
534542 reason : AttributeParseErrorReason :: ExpectedAtLeastOneArgument ,
535- attr_style : self . attr_style ,
543+ suggestions : self . suggestions ( ) ,
536544 } )
537545 }
538546
@@ -552,7 +560,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
552560 strings : false ,
553561 list : false ,
554562 } ,
555- attr_style : self . attr_style ,
563+ suggestions : self . suggestions ( ) ,
556564 } )
557565 }
558566
@@ -573,7 +581,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
573581 strings : false ,
574582 list : true ,
575583 } ,
576- attr_style : self . attr_style ,
584+ suggestions : self . suggestions ( ) ,
577585 } )
578586 }
579587
@@ -593,7 +601,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
593601 strings : true ,
594602 list : false ,
595603 } ,
596- attr_style : self . attr_style ,
604+ suggestions : self . suggestions ( ) ,
597605 } )
598606 }
599607
@@ -605,6 +613,13 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
605613 span,
606614 ) ;
607615 }
616+
617+ pub ( crate ) fn suggestions ( & self ) -> Vec < String > {
618+ // If the outer and inner spans are equal, we are parsing an attribute from `cfg_attr`,
619+ // So don't display an attribute style in the suggestions
620+ let style = ( self . attr_span != self . inner_span ) . then_some ( self . attr_style ) ;
621+ self . template . suggestions ( style, & self . attr_path )
622+ }
608623}
609624
610625impl < ' f , ' sess , S : Stage > Deref for AcceptContext < ' f , ' sess , S > {
0 commit comments