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
7 changes: 7 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3918,6 +3918,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
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 @@ -817,6 +823,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
38 changes: 26 additions & 12 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 @@ -602,6 +611,7 @@ impl<'a> State<'a> {
ast::Safety::Default,
*defaultness,
define_opaque.as_deref(),
&[],
);
}
ast::AssocItemKind::Type(box ast::TyAlias {
Expand Down Expand Up @@ -703,18 +713,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 +741,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 @@ -727,7 +727,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
Loading
Loading