Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
c1472c5
Add const cloning of slices and tests
Randl Dec 12, 2025
4ed200f
std: move `errno` and related functions into `sys::io`
joboet Jan 6, 2026
5978980
update import in UI test
joboet Jan 6, 2026
7672916
Remove mentions of debootstrap and chroots from the m68k-unknown-none…
knickish Dec 27, 2025
ab1caae
move sentence about gnu ld from 'Building' to 'Requirements' section
knickish Dec 28, 2025
bd8c67c
std: sys: fs: uefi: Implement copy
Ayush1325 Jan 11, 2026
b5dd72d
Port `#[collapse_debuginfo]` to the new attribute parsing system
JonathanBrouwer Jan 10, 2026
f0da783
Update uitests
JonathanBrouwer Jan 10, 2026
6153fa0
Fix that `cfg` attribute was incorrectly not a parsed attribute
JonathanBrouwer Jan 11, 2026
eac7bda
Completely list all unparsed attributes
JonathanBrouwer Jan 11, 2026
d993bd1
improve eii macro by using ecx methods
jdonszelmann Jan 8, 2026
118e53b
Rollup merge of #147938 - const-clone-slice, r=tgross35
jdonszelmann Jan 11, 2026
6281811
Rollup merge of #150438 - m68k-elf-platform-doc-update, r=Noratrieb
jdonszelmann Jan 11, 2026
bd30062
Rollup merge of #150723 - move_pal_error, r=tgross35
jdonszelmann Jan 11, 2026
8e1c167
Rollup merge of #150906 - eii-ecx-mehods, r=Kivooeo
jdonszelmann Jan 11, 2026
aa83244
Rollup merge of #150938 - collapse_debuginfo, r=jdonszelmann
jdonszelmann Jan 11, 2026
dd88859
Rollup merge of #150953 - uefi-fs-copy, r=joboet
jdonszelmann Jan 11, 2026
86ab863
Rollup merge of #150964 - list_all_attrs, r=jdonszelmann
jdonszelmann Jan 11, 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
45 changes: 44 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rustc_hir::attrs::MacroUseArgs;
use rustc_hir::attrs::{CollapseMacroDebuginfo, MacroUseArgs};
use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS;

use super::prelude::*;
Expand Down Expand Up @@ -163,3 +163,46 @@ impl<S: Stage> SingleAttributeParser<S> for MacroExportParser {
Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros })
}
}

pub(crate) struct CollapseDebugInfoParser;

impl<S: Stage> SingleAttributeParser<S> for CollapseDebugInfoParser {
const PATH: &[Symbol] = &[sym::collapse_debuginfo];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(
List: &["no", "external", "yes"],
"https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute"
);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let Some(list) = args.list() else {
cx.expected_list(cx.attr_span, args);
return None;
};
let Some(single) = list.single() else {
cx.expected_single_argument(list.span);
return None;
};
let Some(mi) = single.meta_item() else {
cx.unexpected_literal(single.span());
return None;
};
if let Err(err) = mi.args().no_args() {
cx.expected_no_args(err);
}
let path = mi.path().word_sym();
let info = match path {
Some(sym::yes) => CollapseMacroDebuginfo::Yes,
Some(sym::no) => CollapseMacroDebuginfo::No,
Some(sym::external) => CollapseMacroDebuginfo::External,
_ => {
cx.expected_specific_argument(mi.span(), &[sym::yes, sym::no, sym::external]);
return None;
}
};

Some(AttributeKind::CollapseDebugInfo(info))
}
}
4 changes: 3 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ use crate::attributes::lint_helpers::{
};
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
use crate::attributes::macro_attrs::{
AllowInternalUnsafeParser, MacroEscapeParser, MacroExportParser, MacroUseParser,
AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser,
MacroUseParser,
};
use crate::attributes::must_use::MustUseParser;
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
Expand Down Expand Up @@ -191,6 +192,7 @@ attribute_parsers!(

// tidy-alphabetical-start
Single<CfiEncodingParser>,
Single<CollapseDebugInfoParser>,
Single<CoverageParser>,
Single<CrateNameParser>,
Single<CustomMirParser>,
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_attr_parsing/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,17 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {

/// Returns whether there is a parser for an attribute with this name
pub fn is_parsed_attribute(path: &[Symbol]) -> bool {
Late::parsers().accepters.contains_key(path) || EARLY_PARSED_ATTRIBUTES.contains(&path)
/// The list of attributes that are parsed attributes,
/// even though they don't have a parser in `Late::parsers()`
const SPECIAL_ATTRIBUTES: &[&[Symbol]] = &[
// Cfg attrs are removed after being early-parsed, so don't need to be in the parser list
&[sym::cfg],
&[sym::cfg_attr],
];

Late::parsers().accepters.contains_key(path)
|| EARLY_PARSED_ATTRIBUTES.contains(&path)
|| SPECIAL_ATTRIBUTES.contains(&path)
}

fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs {
Expand Down
214 changes: 78 additions & 136 deletions compiler/rustc_builtin_macros/src/eii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,33 +108,33 @@ fn eii_(
let mut return_items = Vec::new();

if func.body.is_some() {
return_items.push(Box::new(generate_default_impl(
return_items.push(generate_default_impl(
ecx,
&func,
impl_unsafe,
macro_name,
eii_attr_span,
item_span,
foreign_item_name,
)))
))
}

return_items.push(Box::new(generate_foreign_item(
return_items.push(generate_foreign_item(
ecx,
eii_attr_span,
item_span,
func,
vis,
&attrs_from_decl,
)));
return_items.push(Box::new(generate_attribute_macro_to_implement(
));
return_items.push(generate_attribute_macro_to_implement(
ecx,
eii_attr_span,
macro_name,
foreign_item_name,
impl_unsafe,
&attrs_from_decl,
)));
));

return_items.into_iter().map(wrap_item).collect()
}
Expand Down Expand Up @@ -194,7 +194,7 @@ fn generate_default_impl(
eii_attr_span: Span,
item_span: Span,
foreign_item_name: Ident,
) -> ast::Item {
) -> Box<ast::Item> {
// FIXME: re-add some original attrs
let attrs = ThinVec::new();

Expand All @@ -211,124 +211,72 @@ fn generate_default_impl(
span: eii_attr_span,
is_default: true,
known_eii_macro_resolution: Some(ast::EiiExternTarget {
extern_item_path: ast::Path {
span: foreign_item_name.span,
segments: thin_vec![
ast::PathSegment {
ident: Ident::from_str_and_span("super", foreign_item_name.span,),
id: DUMMY_NODE_ID,
args: None
},
ast::PathSegment { ident: foreign_item_name, id: DUMMY_NODE_ID, args: None },
],
tokens: None,
},
extern_item_path: ecx.path(
foreign_item_name.span,
// prefix super to escape the `dflt` module generated below
vec![Ident::from_str_and_span("super", foreign_item_name.span), foreign_item_name],
),
impl_unsafe,
}),
});

ast::Item {
attrs: ThinVec::new(),
id: ast::DUMMY_NODE_ID,
span: eii_attr_span,
vis: ast::Visibility {
span: eii_attr_span,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
kind: ast::ItemKind::Const(Box::new(ast::ConstItem {
ident: Ident { name: kw::Underscore, span: eii_attr_span },
defaultness: ast::Defaultness::Final,
generics: ast::Generics::default(),
ty: Box::new(ast::Ty {
id: DUMMY_NODE_ID,
kind: ast::TyKind::Tup(ThinVec::new()),
span: eii_attr_span,
tokens: None,
}),
rhs: Some(ast::ConstItemRhs::Body(Box::new(ast::Expr {
id: DUMMY_NODE_ID,
kind: ast::ExprKind::Block(
Box::new(ast::Block {
stmts: thin_vec![ast::Stmt {
id: DUMMY_NODE_ID,
kind: ast::StmtKind::Item(Box::new(ast::Item {
attrs: ThinVec::new(),
id: DUMMY_NODE_ID,
span: item_span,
vis: ast::Visibility {
span: item_span,
kind: ast::VisibilityKind::Inherited,
tokens: None
},
kind: ItemKind::Mod(
ast::Safety::Default,
Ident::from_str_and_span("dflt", item_span),
ast::ModKind::Loaded(
thin_vec![
Box::new(ast::Item {
attrs: thin_vec![ecx.attr_nested_word(
sym::allow,
sym::unused_imports,
item_span
),],
id: DUMMY_NODE_ID,
span: item_span,
vis: ast::Visibility {
span: eii_attr_span,
kind: ast::VisibilityKind::Inherited,
tokens: None
},
kind: ItemKind::Use(ast::UseTree {
prefix: ast::Path::from_ident(
Ident::from_str_and_span(
"super", item_span,
)
),
kind: ast::UseTreeKind::Glob,
span: item_span,
}),
tokens: None,
}),
Box::new(ast::Item {
attrs,
id: DUMMY_NODE_ID,
span: item_span,
vis: ast::Visibility {
span: eii_attr_span,
kind: ast::VisibilityKind::Inherited,
tokens: None
},
kind: ItemKind::Fn(Box::new(default_func)),
tokens: None,
}),
],
ast::Inline::Yes,
ast::ModSpans {
inner_span: item_span,
inject_use_span: item_span,
}
)
),
tokens: None,
})),
span: eii_attr_span,
}],
id: DUMMY_NODE_ID,
rules: ast::BlockCheckMode::Default,
span: eii_attr_span,
tokens: None,
}),
None,
let item_mod = |span: Span, name: Ident, items: ThinVec<Box<ast::Item>>| {
ecx.item(
item_span,
ThinVec::new(),
ItemKind::Mod(
ast::Safety::Default,
name,
ast::ModKind::Loaded(
items,
ast::Inline::Yes,
ast::ModSpans { inner_span: span, inject_use_span: span },
),
span: eii_attr_span,
attrs: ThinVec::new(),
tokens: None,
}))),
define_opaque: None,
})),
tokens: None,
}
),
)
};

let anon_mod = |span: Span, stmts: ThinVec<ast::Stmt>| {
let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new()));
let underscore = Ident::new(kw::Underscore, item_span);
ecx.item_const(
span,
underscore,
unit,
ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))),
)
};

// const _: () = {
// mod dflt {
// use super::*;
// <orig fn>
// }
// }
anon_mod(
item_span,
thin_vec![ecx.stmt_item(
item_span,
item_mod(
item_span,
Ident::from_str_and_span("dflt", item_span),
thin_vec![
ecx.item(
item_span,
thin_vec![ecx.attr_nested_word(sym::allow, sym::unused_imports, item_span)],
ItemKind::Use(ast::UseTree {
prefix: ast::Path::from_ident(Ident::from_str_and_span(
"super", item_span,
)),
kind: ast::UseTreeKind::Glob,
span: item_span,
})
),
ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func)))
]
)
),],
)
}

/// Generates a foreign item, like
Expand All @@ -343,7 +291,7 @@ fn generate_foreign_item(
mut func: ast::Fn,
vis: Visibility,
attrs_from_decl: &[Attribute],
) -> ast::Item {
) -> Box<ast::Item> {
let mut foreign_item_attrs = ThinVec::new();
foreign_item_attrs.extend_from_slice(attrs_from_decl);

Expand Down Expand Up @@ -375,16 +323,10 @@ fn generate_foreign_item(
func.sig.header.safety = ast::Safety::Safe(func.sig.span);
}

ast::Item {
attrs: ast::AttrVec::default(),
id: ast::DUMMY_NODE_ID,
span: eii_attr_span,
vis: ast::Visibility {
span: eii_attr_span,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
kind: ast::ItemKind::ForeignMod(ast::ForeignMod {
ecx.item(
eii_attr_span,
ThinVec::new(),
ast::ItemKind::ForeignMod(ast::ForeignMod {
extern_span: eii_attr_span,
safety: ast::Safety::Unsafe(eii_attr_span),
abi,
Expand All @@ -397,8 +339,7 @@ fn generate_foreign_item(
tokens: None,
})]),
}),
tokens: None,
}
)
}

/// Generate a stub macro (a bit like in core) that will roughly look like:
Expand All @@ -418,7 +359,7 @@ fn generate_attribute_macro_to_implement(
foreign_item_name: Ident,
impl_unsafe: bool,
attrs_from_decl: &[Attribute],
) -> ast::Item {
) -> Box<ast::Item> {
let mut macro_attrs = ThinVec::new();

// To avoid e.g. `error: attribute macro has missing stability attribute`
Expand All @@ -428,7 +369,8 @@ fn generate_attribute_macro_to_implement(
// #[builtin_macro(eii_shared_macro)]
macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span));

ast::Item {
// cant use ecx methods here to construct item since we need it to be public
Box::new(ast::Item {
attrs: macro_attrs,
id: ast::DUMMY_NODE_ID,
span,
Expand Down Expand Up @@ -467,7 +409,7 @@ fn generate_attribute_macro_to_implement(
},
),
tokens: None,
}
})
}

pub(crate) fn eii_extern_target(
Expand Down
Loading
Loading