Repository: rust-lang/rust
File: compiler/rustc_attr_parsing/src/attributes/test_attrs.rs (Rust)

Code before:
        })
    }
}

pub(crate) struct RustcVarianceParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcVarianceParser {
    const PATH: &[Symbol] = &[sym::rustc_variance];
    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
        Allow(Target::Struct),
        Allow(Target::Enum),
        Allow(Target::Union),
    ]);
    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVariance;
}

pub(crate) struct RustcVarianceOfOpaquesParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcVarianceOfOpaquesParser {
    const PATH: &[Symbol] = &[sym::rustc_variance_of_opaques];
    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVarianceOfOpaques;
}


Review comment (security):
Yes you can use the new parser in `test_harness.rs`!
You'll have to call `AttributeParser::parse_limited`, let me know if you need more information
@rustbot author

Code after:
        })
    }
}

pub(crate) struct RustcVarianceParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcVarianceParser {
    const PATH: &[Symbol] = &[sym::rustc_variance];
    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
        Allow(Target::Struct),
        Allow(Target::Enum),
        Allow(Target::Union),
    ]);
    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVariance;
}

pub(crate) struct RustcVarianceOfOpaquesParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcVarianceOfOpaquesParser {
    const PATH: &[Symbol] = &[sym::rustc_variance_of_opaques];
    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVarianceOfOpaques;
}

pub(crate) struct ReexportTestHarnessMainParser;

impl<S: Stage> SingleAttributeParser<S> for ReexportTestHarnessMainParser {
    const PATH: &[Symbol] = &[sym::reexport_test_harness_main];
    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
    const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");

    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
        let Some(nv) = args.name_value() else {
            cx.expected_name_value(
                args.span().unwrap_or(cx.inner_span),
                Some(sym::reexport_test_harness_main),
            );
            return None;
        };

        let Some(name) = nv.value_as_str() else {
            cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
            return None;
        };

        Some(AttributeKind::ReexportTestHarnessMain(name))
    }