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
841b007
ast: Preserve the star symbol span in glob delegation items
petrochenkov Mar 18, 2026
a47a772
expand: More precise location for glob delegation
petrochenkov Mar 18, 2026
db6a037
delegation: Give declaration of `self` syntax context of the delegati…
petrochenkov Mar 18, 2026
66cf18e
Update some tests after rebase
petrochenkov Apr 8, 2026
e756d16
Add `eii_impls` argument to `StaticItem`
JonathanBrouwer Mar 26, 2026
607b062
Analysis for externally implementable statics
JonathanBrouwer Mar 27, 2026
c7e194f
Fix codegen for `add_static_aliases`
JonathanBrouwer Mar 26, 2026
fca29ad
Uitests for external statics
JonathanBrouwer Mar 26, 2026
59ed245
Reject mutable externally implementable statics
JonathanBrouwer Apr 10, 2026
1f2b090
Reject multiple EII implementations on one static
JonathanBrouwer Apr 10, 2026
21925e9
Lazily check diagnostic namespace features
mejrs Apr 11, 2026
d69403a
Properly emit diagnostic for diagnostic::on_move being used without f…
mejrs Apr 11, 2026
55cd476
Change edit distance to not suggest `on_move` and `on_const` against …
mejrs Apr 11, 2026
106b16c
Add support for static EIIs in late resolution
JonathanBrouwer Apr 12, 2026
08a12dc
Add feature hint for unstable diagnostic attributes
mejrs Apr 12, 2026
ecd2b10
Rollup merge of #154049 - petrochenkov:deleglobspan, r=jackh726
JonathanBrouwer Apr 12, 2026
025342e
Rollup merge of #154193 - JonathanBrouwer:external-static, r=jdonszel…
JonathanBrouwer Apr 12, 2026
6fbb2dd
Rollup merge of #155174 - mejrs:on_move_gating, r=JonathanBrouwer
JonathanBrouwer Apr 12, 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
16 changes: 14 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3901,12 +3901,17 @@ pub struct Delegation {
pub from_glob: bool,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum DelegationSuffixes {
List(ThinVec<(Ident, Option<Ident>)>),
Glob(Span),
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct DelegationMac {
pub qself: Option<Box<QSelf>>,
pub prefix: Path,
// Some for list delegation, and None for glob delegation.
pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
pub suffixes: DelegationSuffixes,
pub body: Option<Box<Block>>,
}

Expand All @@ -3918,6 +3923,13 @@ pub struct StaticItem {
pub mutability: Mutability,
pub expr: Option<Box<Expr>>,
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,

/// This static is an implementation of an externally implementable item (EII).
/// This means, there was an EII declared somewhere and this static is the
/// implementation that should be used for the declaration.
///
/// For statics, there may be at most one `EiiImpl`, but this is a `ThinVec` to make usages of this field nicer.
pub eii_impls: ThinVec<EiiImpl>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ macro_rules! common_visitor_and_walkers {
Defaultness,
Delegation,
DelegationMac,
DelegationSuffixes,
DelimArgs,
DelimSpan,
EnumDef,
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,14 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
i: &ItemKind,
) -> Vec<hir::Attribute> {
match i {
ItemKind::Fn(box Fn { eii_impls, .. }) if eii_impls.is_empty() => Vec::new(),
ItemKind::Fn(box Fn { eii_impls, .. }) => {
ItemKind::Fn(box Fn { eii_impls, .. })
| ItemKind::Static(box StaticItem { eii_impls, .. })
if eii_impls.is_empty() =>
{
Vec::new()
}
ItemKind::Fn(box Fn { eii_impls, .. })
| ItemKind::Static(box StaticItem { eii_impls, .. }) => {
vec![hir::Attribute::Parsed(AttributeKind::EiiImpls(
eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(),
))]
Expand All @@ -226,7 +232,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {

ItemKind::ExternCrate(..)
| ItemKind::Use(..)
| ItemKind::Static(..)
| ItemKind::Const(..)
| ItemKind::ConstBlock(..)
| ItemKind::Mod(..)
Expand Down Expand Up @@ -302,6 +307,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
mutability: m,
expr: e,
define_opaque,
eii_impls: _,
}) => {
let ident = self.lower_ident(*ident);
let ty = self
Expand Down Expand Up @@ -826,6 +832,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
expr: _,
safety,
define_opaque,
eii_impls: _,
}) => {
let ty = self
.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
Expand Down
48 changes: 34 additions & 14 deletions compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl<'a> State<'a> {
expr,
safety,
define_opaque,
eii_impls,
}) => self.print_item_const(
*ident,
Some(*mutability),
Expand All @@ -53,6 +54,7 @@ impl<'a> State<'a> {
*safety,
ast::Defaultness::Implicit,
define_opaque.as_deref(),
eii_impls,
),
ast::ForeignItemKind::TyAlias(box ast::TyAlias {
defaultness,
Expand Down Expand Up @@ -93,8 +95,12 @@ impl<'a> State<'a> {
safety: ast::Safety,
defaultness: ast::Defaultness,
define_opaque: Option<&[(ast::NodeId, ast::Path)]>,
eii_impls: &[EiiImpl],
) {
self.print_define_opaques(define_opaque);
for eii_impl in eii_impls {
self.print_eii_impl(eii_impl);
}
let (cb, ib) = self.head("");
self.print_visibility(vis);
self.print_safety(safety);
Expand Down Expand Up @@ -191,6 +197,7 @@ impl<'a> State<'a> {
mutability: mutbl,
expr: body,
define_opaque,
eii_impls,
}) => {
self.print_safety(*safety);
self.print_item_const(
Expand All @@ -203,6 +210,7 @@ impl<'a> State<'a> {
ast::Safety::Default,
ast::Defaultness::Implicit,
define_opaque.as_deref(),
eii_impls,
);
}
ast::ItemKind::ConstBlock(ast::ConstBlockItem { id: _, span: _, block }) => {
Expand Down Expand Up @@ -234,6 +242,7 @@ impl<'a> State<'a> {
ast::Safety::Default,
*defaultness,
define_opaque.as_deref(),
&[],
);
}
ast::ItemKind::Fn(func) => {
Expand Down Expand Up @@ -435,7 +444,10 @@ impl<'a> State<'a> {
&item.vis,
&deleg.qself,
&deleg.prefix,
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
match &deleg.suffixes {
ast::DelegationSuffixes::List(s) => DelegationKind::List(s),
ast::DelegationSuffixes::Glob(_) => DelegationKind::Glob,
},
&deleg.body,
),
}
Expand Down Expand Up @@ -602,6 +614,7 @@ impl<'a> State<'a> {
ast::Safety::Default,
*defaultness,
define_opaque.as_deref(),
&[],
);
}
ast::AssocItemKind::Type(box ast::TyAlias {
Expand Down Expand Up @@ -641,7 +654,10 @@ impl<'a> State<'a> {
vis,
&deleg.qself,
&deleg.prefix,
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
match &deleg.suffixes {
ast::DelegationSuffixes::List(s) => DelegationKind::List(s),
ast::DelegationSuffixes::Glob(_) => DelegationKind::Glob,
},
&deleg.body,
),
}
Expand Down Expand Up @@ -703,18 +719,8 @@ impl<'a> State<'a> {

self.print_define_opaques(define_opaque.as_deref());

for EiiImpl { eii_macro_path, impl_safety, .. } in eii_impls {
self.word("#[");
if let Safety::Unsafe(..) = impl_safety {
self.word("unsafe");
self.popen();
}
self.print_path(eii_macro_path, false, 0);
if let Safety::Unsafe(..) = impl_safety {
self.pclose();
}
self.word("]");
self.hardbreak();
for eii_impl in eii_impls {
self.print_eii_impl(eii_impl);
}

let body_cb_ib = body.as_ref().map(|body| (body, self.head("")));
Expand All @@ -741,6 +747,20 @@ impl<'a> State<'a> {
}
}

fn print_eii_impl(&mut self, eii: &ast::EiiImpl) {
self.word("#[");
if let Safety::Unsafe(..) = eii.impl_safety {
self.word("unsafe");
self.popen();
}
self.print_path(&eii.eii_macro_path, false, 0);
if let Safety::Unsafe(..) = eii.impl_safety {
self.pclose();
}
self.word("]");
self.hardbreak();
}

fn print_define_opaques(&mut self, define_opaque: Option<&[(ast::NodeId, ast::Path)]>) {
if let Some(define_opaque) = define_opaque {
self.word("#[define_opaque(");
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,8 @@ pub(crate) struct RustcEiiForeignItemParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcEiiForeignItemParser {
const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
|this, cx, args| {
if !cx.features().diagnostic_on_const() {
// `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl OnMoveParser {
mode: Mode,
) {
if !cx.features().diagnostic_on_move() {
// `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ impl OnUnknownParser {
mode: Mode,
) {
if !cx.features().diagnostic_on_unknown() {
// `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
return;
}
let span = cx.attr_span;
Expand Down
Loading
Loading