Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 2 additions & 4 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3936,7 +3936,7 @@ pub struct Fn {
/// This function is an implementation of an externally implementable item (EII).
/// This means, there was an EII declared somewhere and this function is the
/// implementation that should be run when the declaration is called.
pub eii_impls: ThinVec<EiiImpl>,
pub eii_impl: Option<Box<EiiImpl>>,
}

impl Fn {
Expand Down Expand Up @@ -4028,9 +4028,7 @@ pub struct StaticItem {
/// 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>,
pub eii_impl: Option<Box<EiiImpl>>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -933,12 +933,12 @@ macro_rules! common_visitor_and_walkers {
_ctxt,
// Visibility is visited as a part of the item.
_vis,
Fn { defaultness, ident, sig, generics, contract, body, define_opaque, eii_impls },
Fn { defaultness, ident, sig, generics, contract, body, define_opaque, eii_impl },
) => {
let FnSig { header, decl, span } = sig;
visit_visitable!($($mut)? vis,
defaultness, ident, header, generics, decl,
contract, body, span, define_opaque, eii_impls
contract, body, span, define_opaque, eii_impl
);
}
FnKind::Closure(binder, coroutine_kind, decl, body) =>
Expand Down
22 changes: 9 additions & 13 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
i: &ItemKind,
) -> Vec<hir::Attribute> {
match i {
ItemKind::Fn(Fn { eii_impls, .. }) | ItemKind::Static(StaticItem { eii_impls, .. })
if eii_impls.is_empty() =>
{
Vec::new()
}
ItemKind::Fn(Fn { eii_impls, .. }) | ItemKind::Static(StaticItem { eii_impls, .. }) => {
vec![hir::Attribute::Parsed(AttributeKind::EiiImpls(
eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(),
))]
ItemKind::Fn(Fn { eii_impl: None, .. })
| ItemKind::Static(StaticItem { eii_impl: None, .. }) => Vec::new(),
ItemKind::Fn(Fn { eii_impl: Some(eii_impl), .. })
| ItemKind::Static(StaticItem { eii_impl: Some(eii_impl), .. }) => {
vec![hir::Attribute::Parsed(AttributeKind::EiiImpl(self.lower_eii_impl(eii_impl)))]
}
ItemKind::MacroDef(name, MacroDef { eii_declaration: Some(target), .. }) => self
.lower_eii_decl(id, *name, target)
Expand Down Expand Up @@ -223,7 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind,
vis_span,
span: self.lower_span(i.span),
eii: find_attr!(attrs, EiiImpls(..) | EiiDeclaration(..)),
eii: find_attr!(attrs, EiiImpl(..) | EiiDeclaration(..)),
};
self.arena.alloc(item)
}
Expand Down Expand Up @@ -256,7 +252,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
mutability: m,
expr: e,
define_opaque,
eii_impls: _,
eii_impl: _,
}) => {
let ident = self.lower_ident(*ident);
let ty = self
Expand Down Expand Up @@ -693,7 +689,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind,
vis_span,
span: this.lower_span(use_tree.span()),
eii: find_attr!(attrs, EiiImpls(..) | EiiDeclaration(..)),
eii: find_attr!(attrs, EiiImpl(..) | EiiDeclaration(..)),
};
hir::OwnerNode::Item(this.arena.alloc(item))
});
Expand Down Expand Up @@ -760,7 +756,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
expr: _,
safety,
define_opaque,
eii_impls: _,
eii_impl: _,
}) => {
let ty = self
.lower_ty_alloc(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
Expand Down
30 changes: 14 additions & 16 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,10 +1204,10 @@ impl<'a> AstValidator<'a> {
}

// Check EII implementation attributes against an allowlist.
fn check_eii_impl_attrs(&self, attrs: &[Attribute], eii_impls: &[EiiImpl]) {
if eii_impls.is_empty() {
fn check_eii_impl_attrs(&self, attrs: &[Attribute], eii_impl: &Option<Box<EiiImpl>>) {
let Some(eii_impl) = eii_impl else {
return;
}
};

let allowed_attrs: &[Symbol] = &[
sym::allow,
Expand All @@ -1234,14 +1234,12 @@ impl<'a> AstValidator<'a> {
}

let attr_name = pprust::path_to_string(&normal.item.path);
for eii_impl in eii_impls {
self.dcx().emit_err(diagnostics::EiiImplAttributeNotSupported {
attr_span: attr.span,
attr_name: &attr_name,
eii_span: eii_impl.span,
eii_name: pprust::path_to_string(&eii_impl.eii_macro_path),
});
}
self.dcx().emit_err(diagnostics::EiiImplAttributeNotSupported {
attr_span: attr.span,
attr_name: &attr_name,
eii_span: eii_impl.span,
eii_name: pprust::path_to_string(&eii_impl.eii_macro_path),
});
}
}
}
Expand Down Expand Up @@ -1424,16 +1422,16 @@ impl Visitor<'_> for AstValidator<'_> {
contract: _,
body,
define_opaque: _,
eii_impls,
eii_impl,
},
) => {
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
self.check_defaultness(item.span, *defaultness, AllowDefault::No, AllowFinal::No);

for EiiImpl { eii_macro_path, .. } in eii_impls {
if let Some(EiiImpl { eii_macro_path, .. }) = eii_impl {
self.visit_path(eii_macro_path);
}
self.check_eii_impl_attrs(&item.attrs, eii_impls);
self.check_eii_impl_attrs(&item.attrs, eii_impl);

let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic));
if body.is_none() && !is_intrinsic && !self.is_sdylib_interface {
Expand Down Expand Up @@ -1609,9 +1607,9 @@ impl Visitor<'_> for AstValidator<'_> {

visit::walk_item(self, item);
}
ItemKind::Static(StaticItem { expr, safety, eii_impls, .. }) => {
ItemKind::Static(StaticItem { expr, safety, eii_impl, .. }) => {
self.check_item_safety(item.span, *safety);
self.check_eii_impl_attrs(&item.attrs, eii_impls);
self.check_eii_impl_attrs(&item.attrs, eii_impl);
if matches!(safety, Safety::Unsafe(_)) {
self.dcx().emit_err(diagnostics::UnsafeStatic { span: item.span });
}
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl<'a> State<'a> {
expr,
safety,
define_opaque,
eii_impls,
eii_impl,
}) => self.print_item_const(
*ident,
Some(*mutability),
Expand All @@ -54,7 +54,7 @@ impl<'a> State<'a> {
*safety,
ast::Defaultness::Implicit,
define_opaque.as_deref(),
eii_impls,
eii_impl.as_deref(),
),
ast::ForeignItemKind::TyAlias(ast::TyAlias {
defaultness,
Expand Down Expand Up @@ -95,10 +95,10 @@ impl<'a> State<'a> {
safety: ast::Safety,
defaultness: ast::Defaultness,
define_opaque: Option<&[(ast::NodeId, ast::Path)]>,
eii_impls: &[EiiImpl],
eii_impl: Option<&EiiImpl>,
) {
self.print_define_opaques(define_opaque);
for eii_impl in eii_impls {
if let Some(eii_impl) = eii_impl {
self.print_eii_impl(eii_impl);
}
let (cb, ib) = self.head("");
Expand Down Expand Up @@ -197,7 +197,7 @@ impl<'a> State<'a> {
mutability: mutbl,
expr: body,
define_opaque,
eii_impls,
eii_impl,
}) => {
self.print_safety(*safety);
self.print_item_const(
Expand All @@ -210,7 +210,7 @@ impl<'a> State<'a> {
ast::Safety::Default,
ast::Defaultness::Implicit,
define_opaque.as_deref(),
eii_impls,
eii_impl.as_deref(),
);
}
ast::ItemKind::ConstBlock(ast::ConstBlockItem { id: _, span: _, block }) => {
Expand Down Expand Up @@ -243,7 +243,7 @@ impl<'a> State<'a> {
ast::Safety::Default,
*defaultness,
define_opaque.as_deref(),
&[],
None,
);
}
ast::ItemKind::Fn(func) => {
Expand Down Expand Up @@ -632,7 +632,7 @@ impl<'a> State<'a> {
ast::Safety::Default,
*defaultness,
define_opaque.as_deref(),
&[],
None,
);
}
ast::AssocItemKind::Type(ast::TyAlias {
Expand Down Expand Up @@ -732,12 +732,12 @@ impl<'a> State<'a> {
}

fn print_fn_full(&mut self, vis: &ast::Visibility, attrs: &[ast::Attribute], func: &ast::Fn) {
let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque, eii_impls } =
let ast::Fn { defaultness, ident, generics, sig, contract, body, define_opaque, eii_impl } =
func;

self.print_define_opaques(define_opaque.as_deref());

for eii_impl in eii_impls {
if let Some(eii_impl) = eii_impl {
self.print_eii_impl(eii_impl);
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/alloc_error_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
contract: None,
body,
define_opaque: None,
eii_impls: ThinVec::new(),
eii_impl: None,
}));

let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)];
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/autodiff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ mod llvm_enzyme {
contract: None,
body: Some(d_body),
define_opaque: None,
eii_impls: ThinVec::new(),
eii_impl: None,
});
let mut rustc_ad_attr =
Box::new(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff)));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,7 @@ impl<'a> MethodDef<'a> {
contract: None,
body: Some(body_block),
define_opaque: None,
eii_impls: ThinVec::new(),
eii_impl: None,
})),
tokens: None,
})
Expand Down
20 changes: 12 additions & 8 deletions compiler/rustc_builtin_macros/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,13 @@ pub(crate) struct CfgSelectNoMatches {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("a single item cannot both declare and implement EIIs")]
pub(crate) struct EiiBothDeclAndImpl {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("`#[eii_declaration(...)]` is only valid on macros")]
pub(crate) struct EiiExternTargetExpectedMacro {
Expand All @@ -1117,21 +1124,18 @@ pub(crate) struct EiiExternTargetExpectedUnsafe {
}

#[derive(Diagnostic)]
#[diag("`#[{$name}]` is only valid on functions and statics")]
pub(crate) struct EiiSharedMacroTarget {
#[diag("a single item cannot implement multiple EIIs")]
pub(crate) struct EiiMultipleImplementations {
#[primary_span]
pub span: Span,
pub name: String,
}

#[derive(Diagnostic)]
#[diag("static cannot implement multiple EIIs")]
#[note(
"this is not allowed because multiple externally implementable statics that alias may be unintuitive"
)]
pub(crate) struct EiiStaticMultipleImplementations {
#[diag("`#[{$name}]` is only valid on functions and statics")]
pub(crate) struct EiiSharedMacroTarget {
#[primary_span]
pub span: Span,
pub name: String,
}

#[derive(Diagnostic)]
Expand Down
Loading
Loading