@@ -271,6 +271,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
271271 mut emit_lint : impl FnMut ( LintId , Span , AttributeLintKind ) ,
272272 ) -> Vec < Attribute > {
273273 let mut attributes = Vec :: new ( ) ;
274+ // We store the attributes we intend to discard at the end of this function in order to
275+ // check they are applied to the right target and error out if necessary. In practice, we
276+ // end up dropping only derive attributes and derive helpers, both being fully processed
277+ // at macro expansion.
278+ let mut dropped_attributes = Vec :: new ( ) ;
274279 let mut attr_paths: Vec < RefPathParser < ' _ > > = Vec :: new ( ) ;
275280 let mut early_parsed_state = EarlyParsedState :: default ( ) ;
276281
@@ -394,21 +399,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
394399 Self :: check_target ( & accept. allowed_targets , target, & mut cx) ;
395400 }
396401 } else {
397- // If we're here, we must be compiling a tool attribute... Or someone
398- // forgot to parse their fancy new attribute. Let's warn them in any case.
399- // If you are that person, and you really think your attribute should
400- // remain unparsed, carefully read the documentation in this module and if
401- // you still think so you can add an exception to this assertion.
402-
403- // FIXME(jdonszelmann): convert other attributes, and check with this that
404- // we caught em all
405- // const FIXME_TEMPORARY_ATTR_ALLOWLIST: &[Symbol] = &[sym::cfg];
406- // assert!(
407- // self.tools.contains(&parts[0]) || true,
408- // // || FIXME_TEMPORARY_ATTR_ALLOWLIST.contains(&parts[0]),
409- // "attribute {path} wasn't parsed and isn't a know tool attribute",
410- // );
411-
412402 let attr = AttrItem {
413403 path : attr_path. clone ( ) ,
414404 args : self
@@ -424,8 +414,19 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
424414 self . check_invalid_crate_level_attr_item ( & attr) ;
425415 }
426416
427- attributes. push ( Attribute :: Unparsed ( Box :: new ( attr) ) ) ;
428- } ;
417+ let attr = Attribute :: Unparsed ( Box :: new ( attr) ) ;
418+
419+ if self . tools . contains ( & parts[ 0 ] )
420+ // FIXME: this can be removed once #152369 has been merged.
421+ // https://github.com/rust-lang/rust/pull/152369
422+ || [ sym:: allow, sym:: deny, sym:: expect, sym:: forbid, sym:: warn]
423+ . contains ( & parts[ 0 ] )
424+ {
425+ attributes. push ( attr) ;
426+ } else {
427+ dropped_attributes. push ( attr) ;
428+ }
429+ }
429430 }
430431 }
431432 }
@@ -443,7 +444,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
443444 if !matches ! ( self . stage. should_emit( ) , ShouldEmit :: Nothing )
444445 && target == Target :: WherePredicate
445446 {
446- self . check_invalid_where_predicate_attrs ( attributes. iter ( ) ) ;
447+ self . check_invalid_where_predicate_attrs ( attributes. iter ( ) . chain ( & dropped_attributes ) ) ;
447448 }
448449
449450 attributes
0 commit comments