Skip to content
Merged
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
16 changes: 9 additions & 7 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2109,16 +2109,18 @@ pub struct MacroDef {
/// `true` if macro was defined with `macro_rules`.
pub macro_rules: bool,

/// If this is a macro used for externally implementable items,
/// it refers to an extern item which is its "target". This requires
/// name resolution so can't just be an attribute, so we store it in this field.
pub eii_extern_target: Option<EiiExternTarget>,
/// Corresponds to `#[eii_declaration(...)]`.
/// `#[eii_declaration(...)]` is a built-in attribute macro, not a built-in attribute,
/// because we require some name resolution to occur in the parameters of this attribute.
/// Name resolution isn't possible in attributes otherwise, so we encode it in the AST.
/// During ast lowering, we turn it back into an attribute again
pub eii_declaration: Option<EiiDecl>,
}

#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
pub struct EiiExternTarget {
pub struct EiiDecl {
/// path to the extern item we're targeting
pub extern_item_path: Path,
pub foreign_item: Path,
pub impl_unsafe: bool,
}

Expand Down Expand Up @@ -3824,7 +3826,7 @@ pub struct EiiImpl {
///
/// This field is that shortcut: we prefill the extern target to skip a name resolution step,
/// making sure it never fails. It'd be awful UX if we fail name resolution in code invisible to the user.
pub known_eii_macro_resolution: Option<EiiExternTarget>,
pub known_eii_macro_resolution: Option<EiiDecl>,
pub impl_safety: Safety,
pub span: Span,
pub inner_span: Span,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ macro_rules! common_visitor_and_walkers {
WhereEqPredicate,
WhereRegionPredicate,
YieldKind,
EiiExternTarget,
EiiDecl,
EiiImpl,
);

Expand Down
35 changes: 16 additions & 19 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use rustc_abi::ExternAbi;
use rustc_ast::visit::AssocCtxt;
use rustc_ast::*;
use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImplResolution};
use rustc_hir::attrs::{AttributeKind, EiiImplResolution};
use rustc_hir::def::{DefKind, PerNS, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::{
Expand Down Expand Up @@ -134,16 +134,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn lower_eii_extern_target(
fn lower_eii_decl(
&mut self,
id: NodeId,
eii_name: Ident,
EiiExternTarget { extern_item_path, impl_unsafe }: &EiiExternTarget,
) -> Option<EiiDecl> {
self.lower_path_simple_eii(id, extern_item_path).map(|did| EiiDecl {
eii_extern_target: did,
name: Ident,
EiiDecl { foreign_item, impl_unsafe }: &EiiDecl,
) -> Option<hir::attrs::EiiDecl> {
self.lower_path_simple_eii(id, foreign_item).map(|did| hir::attrs::EiiDecl {
foreign_item: did,
impl_unsafe: *impl_unsafe,
name: eii_name,
name,
})
}

Expand All @@ -160,7 +160,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}: &EiiImpl,
) -> hir::attrs::EiiImpl {
let resolution = if let Some(target) = known_eii_macro_resolution
&& let Some(decl) = self.lower_eii_extern_target(
&& let Some(decl) = self.lower_eii_decl(
*node_id,
// the expect is ok here since we always generate this path in the eii macro.
eii_macro_path.segments.last().expect("at least one segment").ident,
Expand Down Expand Up @@ -196,9 +196,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
eii_impls.iter().map(|i| self.lower_eii_impl(i)).collect(),
))]
}
ItemKind::MacroDef(name, MacroDef { eii_extern_target: Some(target), .. }) => self
.lower_eii_extern_target(id, *name, target)
.map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiExternTarget(decl))])
ItemKind::MacroDef(name, MacroDef { eii_declaration: Some(target), .. }) => self
.lower_eii_decl(id, *name, target)
.map(|decl| vec![hir::Attribute::Parsed(AttributeKind::EiiDeclaration(decl))])
.unwrap_or_default(),

ItemKind::ExternCrate(..)
Expand Down Expand Up @@ -242,10 +242,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
vis_span,
span: self.lower_span(i.span),
has_delayed_lints: !self.delayed_lints.is_empty(),
eii: find_attr!(
attrs,
AttributeKind::EiiImpls(..) | AttributeKind::EiiExternTarget(..)
),
eii: find_attr!(attrs, AttributeKind::EiiImpls(..) | AttributeKind::EiiDeclaration(..)),
};
self.arena.alloc(item)
}
Expand Down Expand Up @@ -539,7 +536,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
hir::ItemKind::TraitAlias(constness, ident, generics, bounds)
}
ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_extern_target: _ }) => {
ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_declaration: _ }) => {
let ident = self.lower_ident(*ident);
let body = Box::new(self.lower_delim_args(body));
let def_id = self.local_def_id(id);
Expand All @@ -553,7 +550,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let macro_def = self.arena.alloc(ast::MacroDef {
body,
macro_rules: *macro_rules,
eii_extern_target: None,
eii_declaration: None,
});
hir::ItemKind::Macro(ident, macro_def, macro_kinds)
}
Expand Down Expand Up @@ -693,7 +690,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
has_delayed_lints: !this.delayed_lints.is_empty(),
eii: find_attr!(
attrs,
AttributeKind::EiiImpls(..) | AttributeKind::EiiExternTarget(..)
AttributeKind::EiiImpls(..) | AttributeKind::EiiDeclaration(..)
),
};
hir::OwnerNode::Item(this.arena.alloc(item))
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -865,10 +865,10 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
sp: Span,
print_visibility: impl FnOnce(&mut Self),
) {
if let Some(eii_extern_target) = &macro_def.eii_extern_target {
self.word("#[eii_extern_target(");
self.print_path(&eii_extern_target.extern_item_path, false, 0);
if eii_extern_target.impl_unsafe {
if let Some(eii_decl) = &macro_def.eii_declaration {
self.word("#[eii_declaration(");
self.print_path(&eii_decl.foreign_item, false, 0);
if eii_decl.impl_unsafe {
self.word(",");
self.space();
self.word("unsafe");
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,11 +709,11 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcPassIndirectlyInNonRusticAbisPa
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis;
}

pub(crate) struct EiiExternItemParser;
pub(crate) struct EiiForeignItemParser;

impl<S: Stage> NoArgsAttributeParser<S> for EiiExternItemParser {
const PATH: &[Symbol] = &[sym::rustc_eii_extern_item];
impl<S: Stage> NoArgsAttributeParser<S> for EiiForeignItemParser {
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 CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::EiiExternItem;
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::EiiForeignItem;
}
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::attributes::allow_unstable::{
use crate::attributes::body::CoroutineParser;
use crate::attributes::cfi_encoding::CfiEncodingParser;
use crate::attributes::codegen_attrs::{
ColdParser, CoverageParser, EiiExternItemParser, ExportNameParser, ForceTargetFeatureParser,
ColdParser, CoverageParser, EiiForeignItemParser, ExportNameParser, ForceTargetFeatureParser,
NakedParser, NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser,
RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser, TargetFeatureParser,
ThreadLocalParser, TrackCallerParser, UsedParser,
Expand Down Expand Up @@ -243,7 +243,7 @@ attribute_parsers!(
Single<WithoutArgs<CoroutineParser>>,
Single<WithoutArgs<DenyExplicitImplParser>>,
Single<WithoutArgs<DoNotImplementViaObjectParser>>,
Single<WithoutArgs<EiiExternItemParser>>,
Single<WithoutArgs<EiiForeignItemParser>>,
Single<WithoutArgs<ExportStableParser>>,
Single<WithoutArgs<FfiConstParser>>,
Single<WithoutArgs<FfiPureParser>>,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept

builtin_macros_duplicate_macro_attribute = duplicated attribute

builtin_macros_eii_extern_target_expected_list = `#[eii_extern_target(...)]` expects a list of one or two elements
builtin_macros_eii_extern_target_expected_macro = `#[eii_extern_target(...)]` is only valid on macros
builtin_macros_eii_extern_target_expected_unsafe = expected this argument to be "unsafe"
builtin_macros_eii_declaration_expected_list = `#[eii_declaration(...)]` expects a list of one or two elements
builtin_macros_eii_declaration_expected_macro = `#[eii_declaration(...)]` is only valid on macros
builtin_macros_eii_declaration_expected_unsafe = expected this argument to be "unsafe"
.note = the second argument is optional

builtin_macros_eii_only_once = `#[{$name}]` can only be specified once
Expand Down
24 changes: 12 additions & 12 deletions compiler/rustc_builtin_macros/src/eii.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rustc_ast::token::{Delimiter, TokenKind};
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_ast::{
Attribute, DUMMY_NODE_ID, EiiExternTarget, EiiImpl, ItemKind, MetaItem, Path, Stmt, StmtKind,
Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, Stmt, StmtKind,
Visibility, ast,
};
use rustc_ast_pretty::pprust::path_to_string;
Expand Down Expand Up @@ -30,7 +30,7 @@ use crate::errors::{
/// }
///
/// #[rustc_builtin_macro(eii_shared_macro)]
/// #[eii_extern_target(panic_handler)]
/// #[eii_declaration(panic_handler)]
/// macro panic_handler() {}
/// ```
pub(crate) fn eii(
Expand Down Expand Up @@ -210,8 +210,8 @@ fn generate_default_impl(
},
span: eii_attr_span,
is_default: true,
known_eii_macro_resolution: Some(ast::EiiExternTarget {
extern_item_path: ecx.path(
known_eii_macro_resolution: Some(ast::EiiDecl {
foreign_item: 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],
Expand Down Expand Up @@ -295,9 +295,9 @@ fn generate_foreign_item(
let mut foreign_item_attrs = ThinVec::new();
foreign_item_attrs.extend_from_slice(attrs_from_decl);

// Add the rustc_eii_extern_item on the foreign item. Usually, foreign items are mangled.
// Add the rustc_eii_foreign_item on the foreign item. Usually, foreign items are mangled.
// This attribute makes sure that we later know that this foreign item's symbol should not be.
foreign_item_attrs.push(ecx.attr_word(sym::rustc_eii_extern_item, eii_attr_span));
foreign_item_attrs.push(ecx.attr_word(sym::rustc_eii_foreign_item, eii_attr_span));

let abi = match func.sig.header.ext {
// extern "X" fn => extern "X" {}
Expand Down Expand Up @@ -349,7 +349,7 @@ fn generate_foreign_item(
/// // This attribute tells the compiler that
/// #[builtin_macro(eii_shared_macro)]
/// // the metadata to link this macro to the generated foreign item.
/// #[eii_extern_target(<related_reign_item>)]
/// #[eii_declaration(<related_foreign_item>)]
/// macro macro_name { () => {} }
/// ```
fn generate_attribute_macro_to_implement(
Expand Down Expand Up @@ -401,9 +401,9 @@ fn generate_attribute_macro_to_implement(
]),
}),
macro_rules: false,
// #[eii_extern_target(foreign_item_ident)]
eii_extern_target: Some(ast::EiiExternTarget {
extern_item_path: ast::Path::from_ident(foreign_item_name),
// #[eii_declaration(foreign_item_ident)]
eii_declaration: Some(ast::EiiDecl {
foreign_item: ast::Path::from_ident(foreign_item_name),
impl_unsafe,
}),
},
Expand All @@ -412,7 +412,7 @@ fn generate_attribute_macro_to_implement(
})
}

pub(crate) fn eii_extern_target(
pub(crate) fn eii_declaration(
ecx: &mut ExtCtxt<'_>,
span: Span,
meta_item: &ast::MetaItem,
Expand Down Expand Up @@ -461,7 +461,7 @@ pub(crate) fn eii_extern_target(
false
};

d.eii_extern_target = Some(EiiExternTarget { extern_item_path, impl_unsafe });
d.eii_declaration = Some(EiiDecl { foreign_item: extern_item_path, impl_unsafe });

// Return the original item and the new methods.
vec![item]
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,21 +1010,21 @@ pub(crate) struct CfgSelectUnreachable {
}

#[derive(Diagnostic)]
#[diag(builtin_macros_eii_extern_target_expected_macro)]
#[diag(builtin_macros_eii_declaration_expected_macro)]
pub(crate) struct EiiExternTargetExpectedMacro {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_eii_extern_target_expected_list)]
#[diag(builtin_macros_eii_declaration_expected_list)]
pub(crate) struct EiiExternTargetExpectedList {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_eii_extern_target_expected_unsafe)]
#[diag(builtin_macros_eii_declaration_expected_unsafe)]
pub(crate) struct EiiExternTargetExpectedUnsafe {
#[primary_span]
#[note]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
derive: derive::Expander { is_const: false },
derive_const: derive::Expander { is_const: true },
eii: eii::eii,
eii_extern_target: eii::eii_extern_target,
eii_declaration: eii::eii_declaration,
eii_shared_macro: eii::eii_shared_macro,
global_allocator: global_allocator::expand,
test: test::expand_test,
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,16 +282,16 @@ fn process_builtin_attrs(
AttributeKind::ObjcSelector { methname, .. } => {
codegen_fn_attrs.objc_selector = Some(*methname);
}
AttributeKind::EiiExternItem => {
AttributeKind::EiiForeignItem => {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM;
}
AttributeKind::EiiImpls(impls) => {
for i in impls {
let extern_item = match i.resolution {
let foreign_item = match i.resolution {
EiiImplResolution::Macro(def_id) => {
let Some(extern_item) = find_attr!(
tcx.get_all_attrs(def_id),
AttributeKind::EiiExternTarget(target) => target.eii_extern_target
AttributeKind::EiiDeclaration(target) => target.foreign_item
) else {
tcx.dcx().span_delayed_bug(
i.span,
Expand All @@ -301,7 +301,7 @@ fn process_builtin_attrs(
};
extern_item
}
EiiImplResolution::Known(decl) => decl.eii_extern_target,
EiiImplResolution::Known(decl) => decl.foreign_item,
EiiImplResolution::Error(_eg) => continue,
};

Expand All @@ -316,13 +316,13 @@ fn process_builtin_attrs(
// iterate over all implementations *in the current crate*
// (this is ok since we generate codegen fn attrs in the local crate)
// if any of them is *not default* then don't emit the alias.
&& tcx.externally_implementable_items(LOCAL_CRATE).get(&extern_item).expect("at least one").1.iter().any(|(_, imp)| !imp.is_default)
&& tcx.externally_implementable_items(LOCAL_CRATE).get(&foreign_item).expect("at least one").1.iter().any(|(_, imp)| !imp.is_default)
{
continue;
}

codegen_fn_attrs.foreign_item_symbol_aliases.push((
extern_item,
foreign_item,
if i.is_default { Linkage::LinkOnceAny } else { Linkage::External },
Visibility::Default,
));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
),
gated!(
rustc_eii_extern_item, Normal, template!(Word),
rustc_eii_foreign_item, Normal, template!(Word),
ErrorFollowing, EncodeCrossCrate::Yes, eii_internals,
"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
),
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub struct EiiImpl {

#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
pub struct EiiDecl {
pub eii_extern_target: DefId,
pub foreign_item: DefId,
/// whether or not it is unsafe to implement this EII
pub impl_unsafe: bool,
pub name: Ident,
Expand Down Expand Up @@ -744,10 +744,10 @@ pub enum AttributeKind {
Dummy,

/// Implementation detail of `#[eii]`
EiiExternItem,
EiiDeclaration(EiiDecl),

/// Implementation detail of `#[eii]`
EiiExternTarget(EiiDecl),
EiiForeignItem,

/// Implementation detail of `#[eii]`
EiiImpls(ThinVec<EiiImpl>),
Expand Down
Loading
Loading