Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
99821e1
Fix ICE when combining #[eii] with #[core::contracts::ensures]
GokhanKabar Mar 12, 2026
b544edd
Preserve EII link through AttrProcMacro token roundtrip and add run-p…
GokhanKabar Apr 7, 2026
48eced8
Fix platform-specific stderr mismatch in ice_contract_attr_on_eii_gen…
GokhanKabar Apr 7, 2026
1e59341
Fix code block whitespace handling
yalagadapavankumar Apr 9, 2026
ef3a89c
Fix tabs in test file to satisfy tidy check
yalagadapavankumar Apr 9, 2026
3afb618
Move the `cache_on_disk` check out of `try_load_from_disk_fn`.
nnethercote Apr 10, 2026
4fb83f6
Move profiling of query loading outwards.
nnethercote Apr 10, 2026
9e8069f
Fix unelided lifetime ICE, refactoring of GenericArgPosition
aerooneqq Apr 10, 2026
357f670
Rename `#[rustc_layout]` to `#[rustc_dump_layout]`
fmease Apr 9, 2026
7025605
Rename `#[rustc_dump_layout]`'s `abi` option to `backend_repr`
fmease Apr 9, 2026
dda1ea0
Rename `#[rustc_hidden_type_of_opaques]` to `#[rustc_dump_hidden_type…
fmease Apr 9, 2026
0a59706
Rename `#[rustc_def_path]` to `#[rustc_dump_def_path]`
fmease Apr 9, 2026
cb4a7f4
Rename `#[rustc_symbol_name]` to `#[rustc_dump_symbol_name]`
fmease Apr 9, 2026
64b4284
Simplify impl of `dump_symbol_names_and_def_paths`
fmease Apr 9, 2026
a24108c
Rollup merge of #155080 - nnethercote:salvage, r=petrochenkov
JonathanBrouwer Apr 10, 2026
39aa71c
Rollup merge of #153796 - GokhanKabar:fix-ice-missing-tokens-eii-attr…
JonathanBrouwer Apr 10, 2026
8799db7
Rollup merge of #155027 - fmease:more-test-attr-renamings, r=Jonathan…
JonathanBrouwer Apr 10, 2026
03d273f
Rollup merge of #155031 - aerooneqq:delegation-generic-args-lowering-…
JonathanBrouwer Apr 10, 2026
f848054
Rollup merge of #155040 - yalagadapavankumar:fix-whitespace, r=JohnTitor
JonathanBrouwer Apr 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4692,7 +4692,6 @@ dependencies = [
"rustc-demangle",
"rustc_abi",
"rustc_data_structures",
"rustc_errors",
"rustc_hashes",
"rustc_hir",
"rustc_middle",
Expand Down
126 changes: 123 additions & 3 deletions compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use rustc_hir::attrs::AttributeKind;
use rustc_hir::attrs::{AttributeKind, RustcDumpLayoutKind};
use rustc_hir::{MethodKind, Target};
use rustc_span::{Span, Symbol, sym};

use crate::attributes::prelude::Allow;
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
use super::prelude::*;
use crate::context::Stage;
use crate::target_checking::AllowedTargets;

Expand All @@ -25,6 +24,39 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpDefParentsParser {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents;
}

pub(crate) struct RustcDumpDefPathParser;

impl<S: Stage> SingleAttributeParser<S> for RustcDumpDefPathParser {
const PATH: &[Symbol] = &[sym::rustc_dump_def_path];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
Allow(Target::Impl { of_trait: false }),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
cx.adcx().expected_no_args(span);
return None;
}
Some(AttributeKind::RustcDumpDefPath(cx.attr_span))
}
}

pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser;

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

pub(crate) struct RustcDumpInferredOutlivesParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpInferredOutlivesParser {
Expand All @@ -48,6 +80,70 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpItemBoundsParser {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
}

pub(crate) struct RustcDumpLayoutParser;

impl<S: Stage> CombineAttributeParser<S> for RustcDumpLayoutParser {
const PATH: &[Symbol] = &[sym::rustc_dump_layout];

type Item = RustcDumpLayoutKind;

const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcDumpLayout(items);

const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
Allow(Target::Union),
Allow(Target::TyAlias),
]);

const TEMPLATE: AttributeTemplate =
template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]);
fn extend(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser,
) -> impl IntoIterator<Item = Self::Item> {
let ArgParser::List(items) = args else {
let attr_span = cx.attr_span;
cx.adcx().expected_list(attr_span, args);
return vec![];
};

let mut result = Vec::new();
for item in items.mixed() {
let Some(arg) = item.meta_item() else {
cx.adcx().expected_not_literal(item.span());
continue;
};
let Some(ident) = arg.ident() else {
cx.adcx().expected_identifier(arg.span());
return vec![];
};
let kind = match ident.name {
sym::align => RustcDumpLayoutKind::Align,
sym::backend_repr => RustcDumpLayoutKind::BackendRepr,
sym::debug => RustcDumpLayoutKind::Debug,
sym::homogeneous_aggregate => RustcDumpLayoutKind::HomogenousAggregate,
sym::size => RustcDumpLayoutKind::Size,
_ => {
cx.adcx().expected_specific_argument(
ident.span,
&[
sym::align,
sym::backend_repr,
sym::debug,
sym::homogeneous_aggregate,
sym::size,
],
);
continue;
}
};
result.push(kind);
}
result
}
}

pub(crate) struct RustcDumpObjectLifetimeDefaultsParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpObjectLifetimeDefaultsParser {
Expand Down Expand Up @@ -103,6 +199,30 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpPredicatesParser {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates;
}

pub(crate) struct RustcDumpSymbolNameParser;

impl<S: Stage> SingleAttributeParser<S> for RustcDumpSymbolNameParser {
const PATH: &[Symbol] = &[sym::rustc_dump_symbol_name];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
Allow(Target::Impl { of_trait: false }),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
cx.adcx().expected_no_args(span);
return None;
}
Some(AttributeKind::RustcDumpSymbolName(cx.attr_span))
}
}

pub(crate) struct RustcDumpVariancesParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesParser {
Expand Down
117 changes: 1 addition & 116 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use rustc_ast::{LitIntType, LitKind, MetaItemLit};
use rustc_hir::LangItem;
use rustc_hir::attrs::{
BorrowckGraphvizFormatKind, CguFields, CguKind, DivergingBlockBehavior,
DivergingFallbackBehavior, RustcCleanAttribute, RustcCleanQueries, RustcLayoutType,
RustcMirKind,
DivergingFallbackBehavior, RustcCleanAttribute, RustcCleanQueries, RustcMirKind,
};
use rustc_session::errors;
use rustc_span::Symbol;
Expand Down Expand Up @@ -681,14 +680,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for PanicHandlerParser {
const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::Lang(LangItem::PanicImpl, span);
}

pub(crate) struct RustcHiddenTypeOfOpaquesParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcHiddenTypeOfOpaquesParser {
const PATH: &[Symbol] = &[sym::rustc_hidden_type_of_opaques];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHiddenTypeOfOpaques;
}
pub(crate) struct RustcNounwindParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcNounwindParser {
Expand All @@ -713,64 +704,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcOffloadKernelParser {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel;
}

pub(crate) struct RustcLayoutParser;

impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
const PATH: &[Symbol] = &[sym::rustc_layout];

type Item = RustcLayoutType;

const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcLayout(items);

const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
Allow(Target::Union),
Allow(Target::TyAlias),
]);

const TEMPLATE: AttributeTemplate =
template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]);
fn extend(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser,
) -> impl IntoIterator<Item = Self::Item> {
let ArgParser::List(items) = args else {
let attr_span = cx.attr_span;
cx.adcx().expected_list(attr_span, args);
return vec![];
};

let mut result = Vec::new();
for item in items.mixed() {
let Some(arg) = item.meta_item() else {
cx.adcx().expected_not_literal(item.span());
continue;
};
let Some(ident) = arg.ident() else {
cx.adcx().expected_identifier(arg.span());
return vec![];
};
let ty = match ident.name {
sym::abi => RustcLayoutType::Abi,
sym::align => RustcLayoutType::Align,
sym::size => RustcLayoutType::Size,
sym::homogeneous_aggregate => RustcLayoutType::HomogenousAggregate,
sym::debug => RustcLayoutType::Debug,
_ => {
cx.adcx().expected_specific_argument(
ident.span,
&[sym::abi, sym::align, sym::size, sym::homogeneous_aggregate, sym::debug],
);
continue;
}
};
result.push(ty);
}
result
}
}

pub(crate) struct RustcMirParser;

impl<S: Stage> CombineAttributeParser<S> for RustcMirParser {
Expand Down Expand Up @@ -1210,54 +1143,6 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNonnullOptimizationGuaranteedPa
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonnullOptimizationGuaranteed;
}

pub(crate) struct RustcSymbolNameParser;

impl<S: Stage> SingleAttributeParser<S> for RustcSymbolNameParser {
const PATH: &[Symbol] = &[sym::rustc_symbol_name];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
Allow(Target::Impl { of_trait: false }),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
cx.adcx().expected_no_args(span);
return None;
}
Some(AttributeKind::RustcSymbolName(cx.attr_span))
}
}

pub(crate) struct RustcDefPathParser;

impl<S: Stage> SingleAttributeParser<S> for RustcDefPathParser {
const PATH: &[Symbol] = &[sym::rustc_def_path];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
Allow(Target::Impl { of_trait: false }),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
cx.adcx().expected_no_args(span);
return None;
}
Some(AttributeKind::RustcDefPath(cx.attr_span))
}
}

pub(crate) struct RustcStrictCoherenceParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcStrictCoherenceParser {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ attribute_parsers!(
Combine<ReprParser>,
Combine<RustcAllowConstFnUnstableParser>,
Combine<RustcCleanParser>,
Combine<RustcLayoutParser>,
Combine<RustcDumpLayoutParser>,
Combine<RustcMirParser>,
Combine<RustcThenThisWouldNeedParser>,
Combine<TargetFeatureParser>,
Expand Down Expand Up @@ -211,11 +211,12 @@ attribute_parsers!(
Single<RustcAllocatorZeroedVariantParser>,
Single<RustcAutodiffParser>,
Single<RustcBuiltinMacroParser>,
Single<RustcDefPathParser>,
Single<RustcDeprecatedSafe2024Parser>,
Single<RustcDiagnosticItemParser>,
Single<RustcDocPrimitiveParser>,
Single<RustcDummyParser>,
Single<RustcDumpDefPathParser>,
Single<RustcDumpSymbolNameParser>,
Single<RustcForceInlineParser>,
Single<RustcIfThisChangedParser>,
Single<RustcLayoutScalarValidRangeEndParser>,
Expand All @@ -231,7 +232,6 @@ attribute_parsers!(
Single<RustcScalableVectorParser>,
Single<RustcSimdMonomorphizeLaneLimitParser>,
Single<RustcSkipDuringMethodDispatchParser>,
Single<RustcSymbolNameParser>,
Single<RustcTestMarkerParser>,
Single<SanitizeParser>,
Single<ShouldPanicParser>,
Expand Down Expand Up @@ -285,6 +285,7 @@ attribute_parsers!(
Single<WithoutArgs<RustcDenyExplicitImplParser>>,
Single<WithoutArgs<RustcDoNotConstCheckParser>>,
Single<WithoutArgs<RustcDumpDefParentsParser>>,
Single<WithoutArgs<RustcDumpHiddenTypeOfOpaquesParser>>,
Single<WithoutArgs<RustcDumpInferredOutlivesParser>>,
Single<WithoutArgs<RustcDumpItemBoundsParser>>,
Single<WithoutArgs<RustcDumpObjectLifetimeDefaultsParser>>,
Expand All @@ -298,7 +299,6 @@ attribute_parsers!(
Single<WithoutArgs<RustcEiiForeignItemParser>>,
Single<WithoutArgs<RustcEvaluateWhereClausesParser>>,
Single<WithoutArgs<RustcHasIncoherentInherentImplsParser>>,
Single<WithoutArgs<RustcHiddenTypeOfOpaquesParser>>,
Single<WithoutArgs<RustcInheritOverflowChecksParser>>,
Single<WithoutArgs<RustcInsignificantDtorParser>>,
Single<WithoutArgs<RustcIntrinsicConstStableIndirectParser>>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/markdown/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ fn parse_codeblock(buf: &[u8]) -> Parsed<'_> {
let mut found = None;
for idx in (0..working.len()).filter(|idx| working[*idx..].starts_with(&end_pat)) {
let (eol_txt, rest) = parse_to_newline(&working[(idx + end_pat.len())..]);
if !eol_txt.iter().any(u8::is_ascii_whitespace) {
if eol_txt.iter().all(u8::is_ascii_whitespace) {
found = Some((&working[..idx], rest));
break;
}
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_errors/src/markdown/tests/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,16 @@ fn test_snake_case() {
let res = entrypoint(SNAKE_CASE);
assert_eq!(res, expected);
}

#[test]
fn test_codeblock_trailing_whitespace() {
let buf = "```rust\ncode\n``` \nrest";
let (t, r) = parse_codeblock(buf.as_bytes());
assert_eq!(t, MdTree::CodeBlock { txt: "code", lang: Some("rust") });
assert_eq!(r, b"\nrest");

let buf = "```rust\ncode\n```abc\nrest";
let (t, r) = parse_codeblock(buf.as_bytes());
assert_eq!(t, MdTree::CodeBlock { txt: "code\n```abc\nrest", lang: Some("rust") });
assert_eq!(r, b"");
}
Loading
Loading