Skip to content

Commit 9dd4d3f

Browse files
committed
Add new unstable attribute: #[rust_symbol_export_level].
1 parent 9ba00e0 commit 9dd4d3f

File tree

16 files changed

+192
-10
lines changed

16 files changed

+192
-10
lines changed

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,10 @@ pub enum AttributeKind {
431431
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
432432
Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span },
433433

434+
/// Represents `#[rust_symbol_export_level]` which is one of alternatives discussed
435+
/// in <https://github.com/rust-lang/rfcs/pull/3834>.
436+
RustSymbolExportLevel(Span),
437+
434438
/// Represents `#[rustc_builtin_macro]`.
435439
RustcBuiltinMacro { builtin_name: Option<Symbol>, helper_attrs: ThinVec<Symbol>, span: Span },
436440

compiler/rustc_attr_data_structures/src/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl AttributeKind {
6666
ProcMacroDerive { .. } => No,
6767
PubTransparent(..) => Yes,
6868
Repr { .. } => No,
69+
RustSymbolExportLevel { .. } => No,
6970
RustcBuiltinMacro { .. } => Yes,
7071
RustcLayoutScalarValidRangeEnd(..) => Yes,
7172
RustcLayoutScalarValidRangeStart(..) => Yes,

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ impl<S: Stage> SingleAttributeParser<S> for ExportNameParser {
118118
}
119119
}
120120

121+
pub(crate) struct RustSymbolExportLevelParser;
122+
impl<S: Stage> NoArgsAttributeParser<S> for RustSymbolExportLevelParser {
123+
const PATH: &[Symbol] = &[sym::rust_symbol_export_level];
124+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
125+
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustSymbolExportLevel;
126+
}
127+
121128
#[derive(Default)]
122129
pub(crate) struct NakedParser {
123130
span: Option<Span>,

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use crate::attributes::allow_unstable::{
1818
};
1919
use crate::attributes::codegen_attrs::{
2020
ColdParser, CoverageParser, ExportNameParser, NakedParser, NoMangleParser,
21-
OmitGdbPrettyPrinterSectionParser, OptimizeParser, TargetFeatureParser, TrackCallerParser,
22-
UsedParser,
21+
OmitGdbPrettyPrinterSectionParser, OptimizeParser, RustSymbolExportLevelParser,
22+
TargetFeatureParser, TrackCallerParser, UsedParser,
2323
};
2424
use crate::attributes::confusables::ConfusablesParser;
2525
use crate::attributes::deprecation::DeprecationParser;
@@ -194,6 +194,7 @@ attribute_parsers!(
194194
Single<WithoutArgs<ProcMacroAttributeParser>>,
195195
Single<WithoutArgs<ProcMacroParser>>,
196196
Single<WithoutArgs<PubTransparentParser>>,
197+
Single<WithoutArgs<RustSymbolExportLevelParser>>,
197198
Single<WithoutArgs<SpecializationTraitParser>>,
198199
Single<WithoutArgs<StdInternalSymbolParser>>,
199200
Single<WithoutArgs<TrackCallerParser>>,

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_hir::{self as hir, LangItem, lang_items};
1313
use rustc_middle::middle::codegen_fn_attrs::{
1414
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
1515
};
16+
use rustc_middle::middle::exported_symbols::SymbolExportLevel;
1617
use rustc_middle::mir::mono::Linkage;
1718
use rustc_middle::query::Providers;
1819
use rustc_middle::span_bug;
@@ -113,6 +114,18 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
113114
AttributeKind::ExportName { name, .. } => {
114115
codegen_fn_attrs.export_name = Some(*name);
115116
}
117+
AttributeKind::RustSymbolExportLevel(span) => {
118+
if !tcx.features().rust_symbol_export_level() {
119+
feature_err(
120+
&tcx.sess,
121+
sym::rust_symbol_export_level,
122+
*span,
123+
"`#[rust_symbol_export_level]` is currently unstable",
124+
)
125+
.emit();
126+
}
127+
codegen_fn_attrs.export_level = Some(SymbolExportLevel::Rust);
128+
}
116129
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
117130
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
118131
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
@@ -509,6 +522,17 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
509522
err.emit();
510523
}
511524

525+
if codegen_fn_attrs.export_level.is_some() && !codegen_fn_attrs.contains_extern_indicator() {
526+
let rust_symbol_export_level_span =
527+
find_attr!(attrs, AttributeKind::RustSymbolExportLevel(span) => *span)
528+
.unwrap_or_default();
529+
tcx.dcx().span_err(
530+
rust_symbol_export_level_span,
531+
"`#[rust_symbol_export_level]` will be ignored \
532+
without `export_name`, `no_mangle`, or similar attribute",
533+
);
534+
}
535+
512536
if let Some(features) = check_tied_features(
513537
tcx.sess,
514538
&codegen_fn_attrs

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
495495
ungated!(unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
496496
ungated!(unsafe(Edition2024) link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
497497
ungated!(unsafe(Edition2024) no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
498+
ungated!(rust_symbol_export_level, Normal, template!(Word), ErrorPreceding, EncodeCrossCrate::No),
498499
ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, EncodeCrossCrate::No),
499500
ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, EncodeCrossCrate::Yes),
500501
ungated!(unsafe naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),

compiler/rustc_feature/src/unstable.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,9 @@ declare_features! (
625625
(unstable, return_type_notation, "1.70.0", Some(109417)),
626626
/// Allows `extern "rust-cold"`.
627627
(unstable, rust_cold_cc, "1.63.0", Some(97544)),
628+
/// Allows `#[rust_symbol_export_level]` on definitions of statics and/or functions.
629+
/* FIXME / DO NOT SUBMIT - use actual bug number */
630+
(unstable, rust_symbol_export_level, "CURRENT_RUSTC_VERSION", Some(123456)),
628631
/// Allows the use of SIMD types in functions declared in `extern` blocks.
629632
(unstable, simd_ffi, "1.0.0", Some(27731)),
630633
/// Allows specialization of implementations (RFC 1210).

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable};
77
use rustc_span::Symbol;
88
use rustc_target::spec::SanitizerSet;
99

10+
use crate::middle::exported_symbols::SymbolExportLevel;
1011
use crate::mir::mono::Linkage;
1112
use crate::ty::{InstanceKind, TyCtxt};
1213

@@ -49,6 +50,10 @@ pub struct CodegenFnAttrs {
4950
/// be set when `link_name` is set. This is for foreign items with the
5051
/// "raw-dylib" kind.
5152
pub link_ordinal: Option<u16>,
53+
/// `None` means to use the default value. `Some(level)` means that this specific
54+
/// level should be used. Typically set to `Some(level)` when
55+
/// `#[rust_symbol_export_level]` attribute has been used.
56+
pub export_level: Option<SymbolExportLevel>,
5257
/// The `#[target_feature(enable = "...")]` attribute and the enabled
5358
/// features (only enabled features are supported right now).
5459
/// Implied target features have already been applied.
@@ -173,6 +178,7 @@ impl CodegenFnAttrs {
173178
export_name: None,
174179
link_name: None,
175180
link_ordinal: None,
181+
export_level: None,
176182
target_features: vec![],
177183
safe_target_features: false,
178184
linkage: None,

compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -928,15 +928,17 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
928928
return Visibility::Default;
929929
}
930930

931-
let export_level = if is_generic {
932-
// Generic functions never have export-level C.
933-
SymbolExportLevel::Rust
934-
} else {
935-
match tcx.reachable_non_generics(id.krate).get(&id) {
936-
Some(SymbolExportInfo { level: SymbolExportLevel::C, .. }) => SymbolExportLevel::C,
937-
_ => SymbolExportLevel::Rust,
931+
let export_level = tcx.codegen_fn_attrs(id).export_level.unwrap_or_else(|| {
932+
if is_generic {
933+
// Generic functions never have export-level C.
934+
SymbolExportLevel::Rust
935+
} else {
936+
match tcx.reachable_non_generics(id.krate).get(&id) {
937+
Some(SymbolExportInfo { level: SymbolExportLevel::C, .. }) => SymbolExportLevel::C,
938+
_ => SymbolExportLevel::Rust,
939+
}
938940
}
939-
};
941+
});
940942

941943
match export_level {
942944
// C-export level items remain at `Default` to allow C code to

compiler/rustc_passes/src/check_attr.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
237237
Attribute::Parsed(AttributeKind::ExportName { span: attr_span, .. }) => {
238238
self.check_export_name(hir_id, *attr_span, span, target)
239239
}
240+
Attribute::Parsed(AttributeKind::RustSymbolExportLevel { .. }) => {
241+
/* verified in compiler/rustc_codegen_ssa/src/codegen_attrs.rs */
242+
}
240243
Attribute::Parsed(AttributeKind::Align { align, span: attr_span }) => {
241244
self.check_align(span, hir_id, target, *align, *attr_span)
242245
}

0 commit comments

Comments
 (0)