Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c1472c5
Add const cloning of slices and tests
Randl Dec 12, 2025
2b597f5
feat: invisible character help string
GenericNerd Jan 10, 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
d772c3d
add freeze file times on Windows
tguichaoua Jan 11, 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
8d1d88b
ui: add test for normalizing const projections with assoc const equality
vsriramv Jan 11, 2026
807a5ce
Rollup merge of #147938 - const-clone-slice, r=tgross35
matthiaskrgr Jan 11, 2026
e1c13ff
Rollup merge of #149718 - windows_freeze_file_times, r=ChrisDenton
matthiaskrgr Jan 11, 2026
0a7d5f9
Rollup merge of #150438 - m68k-elf-platform-doc-update, r=Noratrieb
matthiaskrgr Jan 11, 2026
66d1844
Rollup merge of #150790 - lexer/help-invisible-character, r=Kivooeo,t…
matthiaskrgr Jan 11, 2026
a44a2d3
Rollup merge of #150906 - eii-ecx-mehods, r=Kivooeo
matthiaskrgr Jan 11, 2026
d6621f0
Rollup merge of #150938 - collapse_debuginfo, r=jdonszelmann
matthiaskrgr Jan 11, 2026
4ea3e90
Rollup merge of #150953 - uefi-fs-copy, r=joboet
matthiaskrgr Jan 11, 2026
565c663
Rollup merge of #150964 - list_all_attrs, r=jdonszelmann
matthiaskrgr Jan 11, 2026
c31e68f
Rollup merge of #150975 - add-test-norm-const-projections-mgca, r=fmease
matthiaskrgr 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