Skip to content

Commit 2a81c5d

Browse files
authored
Rollup merge of rust-lang#152081 - clubby789:port-depgraph-attrs, r=JonathanBrouwer
Port depgraph testing attributes to parser Tracking issue: rust-lang#131229 Ports `#[rustc_clean]`, `#[rustc_if_this_changed]` and `#[rustc_then_this_would_need]` attributes. Removes references to `rustc_dirty` as that attribute was folded into `rustc_clean` some time ago and rename some code accordingly. r? JonathanBrouwer
2 parents 9a6e969 + 522778e commit 2a81c5d

31 files changed

+485
-338
lines changed

Cargo.lock

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4037,7 +4037,6 @@ name = "rustc_incremental"
40374037
version = "0.0.0"
40384038
dependencies = [
40394039
"rand 0.9.2",
4040-
"rustc_ast",
40414040
"rustc_data_structures",
40424041
"rustc_errors",
40434042
"rustc_fs_util",
@@ -4049,7 +4048,6 @@ dependencies = [
40494048
"rustc_serialize",
40504049
"rustc_session",
40514050
"rustc_span",
4052-
"thin-vec",
40534051
"tracing",
40544052
]
40554053

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 230 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
use std::path::PathBuf;
22

33
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
4-
use rustc_hir::attrs::{BorrowckGraphvizFormatKind, RustcLayoutType, RustcMirKind};
4+
use rustc_hir::attrs::{
5+
BorrowckGraphvizFormatKind, RustcCleanAttribute, RustcCleanQueries, RustcLayoutType,
6+
RustcMirKind,
7+
};
58
use rustc_session::errors;
9+
use rustc_span::Symbol;
610

711
use super::prelude::*;
812
use super::util::parse_single_integer;
9-
use crate::session_diagnostics::RustcScalableVectorCountOutOfRange;
13+
use crate::session_diagnostics::{AttributeRequiresOpt, RustcScalableVectorCountOutOfRange};
1014

1115
pub(crate) struct RustcMainParser;
1216

@@ -234,7 +238,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcLintUntrackedQueryInformationPa
234238
pub(crate) struct RustcObjectLifetimeDefaultParser;
235239

236240
impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {
237-
const PATH: &[rustc_span::Symbol] = &[sym::rustc_object_lifetime_default];
241+
const PATH: &[Symbol] = &[sym::rustc_object_lifetime_default];
238242
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
239243
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
240244
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
@@ -271,7 +275,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcSimdMonomorphizeLaneLimitParser
271275
pub(crate) struct RustcScalableVectorParser;
272276

273277
impl<S: Stage> SingleAttributeParser<S> for RustcScalableVectorParser {
274-
const PATH: &[rustc_span::Symbol] = &[sym::rustc_scalable_vector];
278+
const PATH: &[Symbol] = &[sym::rustc_scalable_vector];
275279
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
276280
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
277281
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
@@ -344,7 +348,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcOffloadKernelParser {
344348
pub(crate) struct RustcLayoutParser;
345349

346350
impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
347-
const PATH: &[rustc_span::Symbol] = &[sym::rustc_layout];
351+
const PATH: &[Symbol] = &[sym::rustc_layout];
348352

349353
type Item = RustcLayoutType;
350354

@@ -401,7 +405,7 @@ impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
401405
pub(crate) struct RustcMirParser;
402406

403407
impl<S: Stage> CombineAttributeParser<S> for RustcMirParser {
404-
const PATH: &[rustc_span::Symbol] = &[sym::rustc_mir];
408+
const PATH: &[Symbol] = &[sym::rustc_mir];
405409

406410
type Item = RustcMirKind;
407411

@@ -497,3 +501,223 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
497501
]);
498502
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonConstTraitMethod;
499503
}
504+
505+
pub(crate) struct RustcCleanParser;
506+
507+
impl<S: Stage> CombineAttributeParser<S> for RustcCleanParser {
508+
const PATH: &[Symbol] = &[sym::rustc_clean];
509+
510+
type Item = RustcCleanAttribute;
511+
512+
const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcClean(items);
513+
514+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
515+
// tidy-alphabetical-start
516+
Allow(Target::AssocConst),
517+
Allow(Target::AssocTy),
518+
Allow(Target::Const),
519+
Allow(Target::Enum),
520+
Allow(Target::Expression),
521+
Allow(Target::Field),
522+
Allow(Target::Fn),
523+
Allow(Target::ForeignMod),
524+
Allow(Target::Impl { of_trait: false }),
525+
Allow(Target::Impl { of_trait: true }),
526+
Allow(Target::Method(MethodKind::Inherent)),
527+
Allow(Target::Method(MethodKind::Trait { body: false })),
528+
Allow(Target::Method(MethodKind::Trait { body: true })),
529+
Allow(Target::Method(MethodKind::TraitImpl)),
530+
Allow(Target::Mod),
531+
Allow(Target::Static),
532+
Allow(Target::Struct),
533+
Allow(Target::Trait),
534+
Allow(Target::TyAlias),
535+
Allow(Target::Union),
536+
// tidy-alphabetical-end
537+
]);
538+
539+
const TEMPLATE: AttributeTemplate =
540+
template!(List: &[r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#]);
541+
542+
fn extend(
543+
cx: &mut AcceptContext<'_, '_, S>,
544+
args: &ArgParser,
545+
) -> impl IntoIterator<Item = Self::Item> {
546+
if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
547+
cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
548+
}
549+
let Some(list) = args.list() else {
550+
cx.expected_list(cx.attr_span, args);
551+
return None;
552+
};
553+
let mut except = None;
554+
let mut loaded_from_disk = None;
555+
let mut cfg = None;
556+
557+
for item in list.mixed() {
558+
let Some((value, name)) =
559+
item.meta_item().and_then(|m| Option::zip(m.args().name_value(), m.ident()))
560+
else {
561+
cx.expected_name_value(item.span(), None);
562+
continue;
563+
};
564+
let value_span = value.value_span;
565+
let Some(value) = value.value_as_str() else {
566+
cx.expected_string_literal(value_span, None);
567+
continue;
568+
};
569+
match name.name {
570+
sym::cfg if cfg.is_some() => {
571+
cx.duplicate_key(item.span(), sym::cfg);
572+
}
573+
574+
sym::cfg => {
575+
cfg = Some(value);
576+
}
577+
sym::except if except.is_some() => {
578+
cx.duplicate_key(item.span(), sym::except);
579+
}
580+
sym::except => {
581+
let entries =
582+
value.as_str().split(',').map(|s| Symbol::intern(s.trim())).collect();
583+
except = Some(RustcCleanQueries { entries, span: value_span });
584+
}
585+
sym::loaded_from_disk if loaded_from_disk.is_some() => {
586+
cx.duplicate_key(item.span(), sym::loaded_from_disk);
587+
}
588+
sym::loaded_from_disk => {
589+
let entries =
590+
value.as_str().split(',').map(|s| Symbol::intern(s.trim())).collect();
591+
loaded_from_disk = Some(RustcCleanQueries { entries, span: value_span });
592+
}
593+
_ => {
594+
cx.expected_specific_argument(
595+
name.span,
596+
&[sym::cfg, sym::except, sym::loaded_from_disk],
597+
);
598+
}
599+
}
600+
}
601+
let Some(cfg) = cfg else {
602+
cx.expected_specific_argument(list.span, &[sym::cfg]);
603+
return None;
604+
};
605+
606+
Some(RustcCleanAttribute { span: cx.attr_span, cfg, except, loaded_from_disk })
607+
}
608+
}
609+
610+
pub(crate) struct RustcIfThisChangedParser;
611+
612+
impl<S: Stage> SingleAttributeParser<S> for RustcIfThisChangedParser {
613+
const PATH: &[Symbol] = &[sym::rustc_if_this_changed];
614+
615+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
616+
617+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
618+
619+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
620+
// tidy-alphabetical-start
621+
Allow(Target::AssocConst),
622+
Allow(Target::AssocTy),
623+
Allow(Target::Const),
624+
Allow(Target::Enum),
625+
Allow(Target::Expression),
626+
Allow(Target::Field),
627+
Allow(Target::Fn),
628+
Allow(Target::ForeignMod),
629+
Allow(Target::Impl { of_trait: false }),
630+
Allow(Target::Impl { of_trait: true }),
631+
Allow(Target::Method(MethodKind::Inherent)),
632+
Allow(Target::Method(MethodKind::Trait { body: false })),
633+
Allow(Target::Method(MethodKind::Trait { body: true })),
634+
Allow(Target::Method(MethodKind::TraitImpl)),
635+
Allow(Target::Mod),
636+
Allow(Target::Static),
637+
Allow(Target::Struct),
638+
Allow(Target::Trait),
639+
Allow(Target::TyAlias),
640+
Allow(Target::Union),
641+
// tidy-alphabetical-end
642+
]);
643+
644+
const TEMPLATE: AttributeTemplate = template!(Word, List: &["DepNode"]);
645+
646+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
647+
if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
648+
cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
649+
}
650+
match args {
651+
ArgParser::NoArgs => Some(AttributeKind::RustcIfThisChanged(cx.attr_span, None)),
652+
ArgParser::List(list) => {
653+
let Some(item) = list.single() else {
654+
cx.expected_single_argument(list.span);
655+
return None;
656+
};
657+
let Some(ident) = item.meta_item().and_then(|item| item.ident()) else {
658+
cx.expected_identifier(item.span());
659+
return None;
660+
};
661+
Some(AttributeKind::RustcIfThisChanged(cx.attr_span, Some(ident.name)))
662+
}
663+
ArgParser::NameValue(_) => {
664+
cx.expected_list_or_no_args(cx.inner_span);
665+
None
666+
}
667+
}
668+
}
669+
}
670+
671+
pub(crate) struct RustcThenThisWouldNeedParser;
672+
673+
impl<S: Stage> CombineAttributeParser<S> for RustcThenThisWouldNeedParser {
674+
const PATH: &[Symbol] = &[sym::rustc_then_this_would_need];
675+
type Item = Ident;
676+
677+
const CONVERT: ConvertFn<Self::Item> =
678+
|items, span| AttributeKind::RustcThenThisWouldNeed(span, items);
679+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
680+
// tidy-alphabetical-start
681+
Allow(Target::AssocConst),
682+
Allow(Target::AssocTy),
683+
Allow(Target::Const),
684+
Allow(Target::Enum),
685+
Allow(Target::Expression),
686+
Allow(Target::Field),
687+
Allow(Target::Fn),
688+
Allow(Target::ForeignMod),
689+
Allow(Target::Impl { of_trait: false }),
690+
Allow(Target::Impl { of_trait: true }),
691+
Allow(Target::Method(MethodKind::Inherent)),
692+
Allow(Target::Method(MethodKind::Trait { body: false })),
693+
Allow(Target::Method(MethodKind::Trait { body: true })),
694+
Allow(Target::Method(MethodKind::TraitImpl)),
695+
Allow(Target::Mod),
696+
Allow(Target::Static),
697+
Allow(Target::Struct),
698+
Allow(Target::Trait),
699+
Allow(Target::TyAlias),
700+
Allow(Target::Union),
701+
// tidy-alphabetical-end
702+
]);
703+
704+
const TEMPLATE: AttributeTemplate = template!(List: &["DepNode"]);
705+
706+
fn extend(
707+
cx: &mut AcceptContext<'_, '_, S>,
708+
args: &ArgParser,
709+
) -> impl IntoIterator<Item = Self::Item> {
710+
if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
711+
cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
712+
}
713+
let Some(item) = args.list().and_then(|l| l.single()) else {
714+
cx.expected_single_argument(cx.inner_span);
715+
return None;
716+
};
717+
let Some(ident) = item.meta_item().and_then(|item| item.ident()) else {
718+
cx.expected_identifier(item.span());
719+
return None;
720+
};
721+
Some(ident)
722+
}
723+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,10 @@ attribute_parsers!(
153153
Combine<ForceTargetFeatureParser>,
154154
Combine<LinkParser>,
155155
Combine<ReprParser>,
156+
Combine<RustcCleanParser>,
156157
Combine<RustcLayoutParser>,
157158
Combine<RustcMirParser>,
159+
Combine<RustcThenThisWouldNeedParser>,
158160
Combine<TargetFeatureParser>,
159161
Combine<UnstableFeatureBoundParser>,
160162
// tidy-alphabetical-end
@@ -191,6 +193,7 @@ attribute_parsers!(
191193
Single<RustcAllocatorZeroedVariantParser>,
192194
Single<RustcBuiltinMacroParser>,
193195
Single<RustcForceInlineParser>,
196+
Single<RustcIfThisChangedParser>,
194197
Single<RustcLayoutScalarValidRangeEndParser>,
195198
Single<RustcLayoutScalarValidRangeStartParser>,
196199
Single<RustcLegacyConstGenericsParser>,

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,14 @@ pub(crate) struct RustcScalableVectorCountOutOfRange {
532532
pub n: u128,
533533
}
534534

535+
#[derive(Diagnostic)]
536+
#[diag("attribute requires {$opt} to be enabled")]
537+
pub(crate) struct AttributeRequiresOpt {
538+
#[primary_span]
539+
pub span: Span,
540+
pub opt: &'static str,
541+
}
542+
535543
pub(crate) enum AttributeParseErrorReason<'a> {
536544
ExpectedNoArgs,
537545
ExpectedStringLiteral {

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,23 @@ pub enum BorrowckGraphvizFormatKind {
716716
TwoPhase,
717717
}
718718

719+
#[derive(Clone, Debug, PartialEq, Eq)]
720+
#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)]
721+
pub struct RustcCleanAttribute {
722+
pub span: Span,
723+
pub cfg: Symbol,
724+
pub except: Option<RustcCleanQueries>,
725+
pub loaded_from_disk: Option<RustcCleanQueries>,
726+
}
727+
728+
/// Represents the `except=` or `loaded_from_disk=` argument of `#[rustc_clean]`
729+
#[derive(Clone, Debug, PartialEq, Eq)]
730+
#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)]
731+
pub struct RustcCleanQueries {
732+
pub entries: ThinVec<Symbol>,
733+
pub span: Span,
734+
}
735+
719736
/// Represents parsed *built-in* inert attributes.
720737
///
721738
/// ## Overview
@@ -1022,6 +1039,9 @@ pub enum AttributeKind {
10221039
/// Represents `#[rustc_builtin_macro]`.
10231040
RustcBuiltinMacro { builtin_name: Option<Symbol>, helper_attrs: ThinVec<Symbol>, span: Span },
10241041

1042+
/// Represents `#[rustc_clean]`
1043+
RustcClean(ThinVec<RustcCleanAttribute>),
1044+
10251045
/// Represents `#[rustc_coherence_is_core]`
10261046
RustcCoherenceIsCore(Span),
10271047

@@ -1077,6 +1097,9 @@ pub enum AttributeKind {
10771097
/// Represents `#[rustc_hidden_type_of_opaques]`
10781098
RustcHiddenTypeOfOpaques,
10791099

1100+
/// Represents `#[rustc_if_this_changed]`
1101+
RustcIfThisChanged(Span, Option<Symbol>),
1102+
10801103
/// Represents `#[rustc_layout]`
10811104
RustcLayout(ThinVec<RustcLayoutType>),
10821105

@@ -1178,6 +1201,9 @@ pub enum AttributeKind {
11781201
/// Represents `#[rustc_std_internal_symbol]`.
11791202
RustcStdInternalSymbol(Span),
11801203

1204+
/// Represents `#[rustc_then_this_would_need]`
1205+
RustcThenThisWouldNeed(Span, ThinVec<Ident>),
1206+
11811207
/// Represents `#[rustc_unsafe_specialization_marker]`.
11821208
RustcUnsafeSpecializationMarker(Span),
11831209

0 commit comments

Comments
 (0)