@@ -267,6 +267,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
267267 mut emit_lint : impl FnMut ( LintId , Span , AttributeLintKind ) ,
268268 ) -> Vec < Attribute > {
269269 let mut attributes = Vec :: new ( ) ;
270+ // We store the attributes we intend to discard at the end of this function in order to
271+ // check they are applied to the right target and error out if necessary. In practice, we
272+ // end up dropping only derive attributes and derive helpers, both being fully processed
273+ // at macro expansion.
274+ let mut dropped_attributes = Vec :: new ( ) ;
270275 let mut attr_paths: Vec < RefPathParser < ' _ > > = Vec :: new ( ) ;
271276 let mut early_parsed_state = EarlyParsedState :: default ( ) ;
272277
@@ -390,21 +395,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
390395 Self :: check_target ( & accept. allowed_targets , target, & mut cx) ;
391396 }
392397 } else {
393- // If we're here, we must be compiling a tool attribute... Or someone
394- // forgot to parse their fancy new attribute. Let's warn them in any case.
395- // If you are that person, and you really think your attribute should
396- // remain unparsed, carefully read the documentation in this module and if
397- // you still think so you can add an exception to this assertion.
398-
399- // FIXME(jdonszelmann): convert other attributes, and check with this that
400- // we caught em all
401- // const FIXME_TEMPORARY_ATTR_ALLOWLIST: &[Symbol] = &[sym::cfg];
402- // assert!(
403- // self.tools.contains(&parts[0]) || true,
404- // // || FIXME_TEMPORARY_ATTR_ALLOWLIST.contains(&parts[0]),
405- // "attribute {path} wasn't parsed and isn't a know tool attribute",
406- // );
407-
408398 let attr = AttrItem {
409399 path : attr_path. clone ( ) ,
410400 args : self
@@ -420,8 +410,19 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
420410 self . check_invalid_crate_level_attr_item ( & attr, n. item . span ( ) ) ;
421411 }
422412
423- attributes. push ( Attribute :: Unparsed ( Box :: new ( attr) ) ) ;
424- } ;
413+ let attr = Attribute :: Unparsed ( Box :: new ( attr) ) ;
414+
415+ if self . tools . contains ( & parts[ 0 ] )
416+ // FIXME: this can be removed once #152369 has been merged.
417+ // https://github.com/rust-lang/rust/pull/152369
418+ || [ sym:: allow, sym:: deny, sym:: expect, sym:: forbid, sym:: warn]
419+ . contains ( & parts[ 0 ] )
420+ {
421+ attributes. push ( attr) ;
422+ } else {
423+ dropped_attributes. push ( attr) ;
424+ }
425+ }
425426 }
426427 }
427428 }
@@ -439,7 +440,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
439440 if !matches ! ( self . stage. should_emit( ) , ShouldEmit :: Nothing )
440441 && target == Target :: WherePredicate
441442 {
442- self . check_invalid_where_predicate_attrs ( attributes. iter ( ) ) ;
443+ self . check_invalid_where_predicate_attrs ( attributes. iter ( ) . chain ( & dropped_attributes ) ) ;
443444 }
444445
445446 attributes
0 commit comments