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