Skip to content

Rollup of 17 pull requests #143916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
136d24f
core: Add `BorrowedCursor::with_unfilled_buf`
a1phyr Jun 22, 2025
f1b5a56
wrapping shift: remove first bitmask and table
hkBst Jul 3, 2025
148a220
remote-test-client: Exit code `128 + <signal-number>` instead of `3`
Enselic Jul 4, 2025
7fc2127
bootstrap/miri: avoid rebuilds for test builds
RalfJung Jul 9, 2025
4c94798
random: Add comment on `RandomSource::fill_bytes` about multiple calls
joshtriplett Jul 9, 2025
ef5c209
tidy: clippy fixes
hkBst Jul 9, 2025
a4e994e
tidy: simplify fluent file extension checking
hkBst Jul 10, 2025
9bd4c90
tidy: move to edition 2024
hkBst Jul 10, 2025
6356faf
tidy: use flatten instead of manual flatten
hkBst Jul 10, 2025
8bf88a2
tidy: use write_all
hkBst Jul 10, 2025
cfb66e5
Consolidate infinity tests
rocurley Jul 10, 2025
c5e67b4
Consolidate test_num tests
rocurley Jul 10, 2025
c2e6b39
Consolidate neg_infinity tests
rocurley Jul 10, 2025
0c01322
Consolidate zero tests
rocurley Jul 10, 2025
fc01eed
Consolidate negative zero tests
rocurley Jul 10, 2025
868020e
Consolidate one tests
rocurley Jul 10, 2025
1b8904c
Consolidate is_nan
rocurley Jul 10, 2025
e3d8367
Consolidate is_infinite tests
rocurley Jul 10, 2025
7dd2811
Consolidate is_finite tests
rocurley Jul 10, 2025
d2c1900
Consolidate is_normal tests
rocurley Jul 10, 2025
79769f2
Consolidate classify tests
rocurley Jul 10, 2025
5e20385
random: Provide a `Distribution<T>` trait
joshtriplett Jul 9, 2025
900aa00
Update miri for change to random API
joshtriplett Jul 11, 2025
5d7db7e
Fixed a core crate compilation failure when enabling the `optimize_fo…
nazo6 Jul 12, 2025
b703451
refine comment
RalfJung Jul 12, 2025
86349e3
Port `#[omit_gdb_pretty_printer_section]` to the new attribute parsin…
JonathanBrouwer Jul 12, 2025
a5ab682
warn on align on fields to avoid breaking changes
jdonszelmann Jul 13, 2025
75561c4
Port `#[link_ordinal]` to the new attribute parsing infrastructure.
Periodic1911 Jun 29, 2025
377aa76
Attempt to fix up SGX for random API updates
joshtriplett Jul 13, 2025
a2d4139
Use zero for initialized Once state
orlp Jul 13, 2025
f041962
Add comment why we use zero for COMPLETE
orlp Jul 13, 2025
a3c90b6
Run bootstrap tests sooner in the `x test` pipeline
Kobzol Jul 13, 2025
25794b1
Compiletest: Simplify {Html,Json}DocCk directive handling
fmease Jul 12, 2025
98eadb3
Don't unnecessarily require `eh_personality`
ChrisDenton Jul 13, 2025
6b02597
update issue number for `const_trait_impl`
fee1-dead Jul 13, 2025
c2c9aad
Make sure that users don't take region obligations in a snapshot
compiler-errors Jul 13, 2025
f6f2f83
Simplify make_query_region_constraints
compiler-errors Jul 13, 2025
5feadc3
Rollup merge of #142885 - a1phyr:borrowed_cursor_to_buf, r=Mark-Simul…
jhpratt Jul 14, 2025
40f511f
Rollup merge of #143217 - Periodic1911:link-ordinal, r=jdonszelmann
jhpratt Jul 14, 2025
fffc52e
Rollup merge of #143355 - hkBst:cleanup-shift-double-bitmask, r=Mark-…
jhpratt Jul 14, 2025
7b668ec
Rollup merge of #143448 - Enselic:remote-test-client-signals, r=Mark-…
jhpratt Jul 14, 2025
89c7256
Rollup merge of #143681 - RalfJung:bootstrap-miri-rebuilds, r=Kobzol
jhpratt Jul 14, 2025
c230be7
Rollup merge of #143710 - joshtriplett:random-updates, r=joshtriplett
jhpratt Jul 14, 2025
1969d41
Rollup merge of #143724 - hkBst:tidy-cleanup, r=Mark-Simulacrum
jhpratt Jul 14, 2025
32e6850
Rollup merge of #143738 - rocurley:float_tests_refactor_2, r=tgross35
jhpratt Jul 14, 2025
3e990a2
Rollup merge of #143820 - nazo6:fix-optimize-for-size, r=Mark-Simulacrum
jhpratt Jul 14, 2025
ad34942
Rollup merge of #143850 - fmease:comptest-simp-docck-handling, r=jiey…
jhpratt Jul 14, 2025
1b4f3ad
Rollup merge of #143855 - JonathanBrouwer:omit_gdb_pretty_printer_sec…
jhpratt Jul 14, 2025
7f7f2d4
Rollup merge of #143868 - jdonszelmann:fix-align-on-fields, r=working…
jhpratt Jul 14, 2025
d446ddc
Rollup merge of #143875 - fee1-dead-contrib:push-zvqrmzrprpzt, r=comp…
jhpratt Jul 14, 2025
b56c69d
Rollup merge of #143881 - orlp:once-state-repr, r=tgross35
jhpratt Jul 14, 2025
943771b
Rollup merge of #143887 - Kobzol:reroder-bootstrap-tests, r=jieyouxu
jhpratt Jul 14, 2025
ff20a84
Rollup merge of #143893 - ChrisDenton:eh_personality_optional, r=comp…
jhpratt Jul 14, 2025
5b8ac1b
Rollup merge of #143901 - compiler-errors:region-constraint-nits, r=lcnr
jhpratt Jul 14, 2025
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: 6 additions & 0 deletions compiler/rustc_attr_data_structures/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ pub enum AttributeKind {
/// Represents `#[link_name]`.
LinkName { name: Symbol, span: Span },

/// Represents `#[link_ordinal]`.
LinkOrdinal { ordinal: u16, span: Span },

/// Represents [`#[link_section]`](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute)
LinkSection { name: Symbol, span: Span },

Expand Down Expand Up @@ -328,6 +331,9 @@ pub enum AttributeKind {
/// Represents `#[non_exhaustive]`
NonExhaustive(Span),

/// Represents `#[omit_gdb_pretty_printer_section]`
OmitGdbPrettyPrinterSection,

/// Represents `#[optimize(size|speed)]`
Optimize(OptimizeAttr, Span),

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_attr_data_structures/src/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl AttributeKind {
Ignore { .. } => No,
Inline(..) => No,
LinkName { .. } => Yes,
LinkOrdinal { .. } => No,
LinkSection { .. } => No,
LoopMatch(..) => No,
MacroTransparency(..) => Yes,
Expand All @@ -50,6 +51,7 @@ impl AttributeKind {
NoImplicitPrelude(..) => No,
NoMangle(..) => No,
NonExhaustive(..) => Yes,
OmitGdbPrettyPrinterSection => No,
Optimize(..) => No,
ParenSugar(..) => No,
PassByValue(..) => Yes,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ attr_parsing_invalid_repr_hint_no_value =
attr_parsing_invalid_since =
'since' must be a Rust version number, such as "1.31.0"
attr_parsing_link_ordinal_out_of_range = ordinal value in `link_ordinal` is too large: `{$ordinal}`
.note = the value may not exceed `u16::MAX`
attr_parsing_missing_feature =
missing 'feature'
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,11 @@ impl<S: Stage> CombineAttributeParser<S> for TargetFeatureParser {
features
}
}

pub(crate) struct OmitGdbPrettyPrinterSectionParser;

impl<S: Stage> NoArgsAttributeParser<S> for OmitGdbPrettyPrinterSectionParser {
const PATH: &[Symbol] = &[sym::omit_gdb_pretty_printer_section];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::OmitGdbPrettyPrinterSection;
}
39 changes: 36 additions & 3 deletions compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection};
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{Span, Symbol, sym};

use crate::attributes::{
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
};
use crate::context::{AcceptContext, Stage};
use crate::context::{AcceptContext, Stage, parse_single_integer};
use crate::parser::ArgParser;
use crate::session_diagnostics::NullOnLinkSection;
use crate::session_diagnostics::{LinkOrdinalOutOfRange, NullOnLinkSection};

pub(crate) struct LinkNameParser;

Expand Down Expand Up @@ -87,3 +87,36 @@ impl<S: Stage> NoArgsAttributeParser<S> for StdInternalSymbolParser {
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::StdInternalSymbol;
}

pub(crate) struct LinkOrdinalParser;

impl<S: Stage> SingleAttributeParser<S> for LinkOrdinalParser {
const PATH: &[Symbol] = &[sym::link_ordinal];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(List: "ordinal");

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
let ordinal = parse_single_integer(cx, args)?;

// According to the table at
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
// ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import
// information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
//
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for
// this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that
// specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import
// library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an
// import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I
// don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
// see earlier comment about LINK.EXE failing.)
let Ok(ordinal) = ordinal.try_into() else {
cx.emit_err(LinkOrdinalOutOfRange { span: cx.attr_span, ordinal });
return None;
};

Some(LinkOrdinal { ordinal, span: cx.attr_span })
}
}
34 changes: 5 additions & 29 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use rustc_ast::LitKind;
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{Symbol, sym};

use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
use crate::context::{AcceptContext, Stage};
use crate::context::{AcceptContext, Stage, parse_single_integer};
use crate::parser::ArgParser;

pub(crate) struct RustcLayoutScalarValidRangeStart;
Expand All @@ -16,8 +15,8 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStart {
const TEMPLATE: AttributeTemplate = template!(List: "start");

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
parse_rustc_layout_scalar_valid_range(cx, args)
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(n, cx.attr_span))
parse_single_integer(cx, args)
.map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(Box::new(n), cx.attr_span))
}
}

Expand All @@ -30,34 +29,11 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEnd {
const TEMPLATE: AttributeTemplate = template!(List: "end");

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
parse_rustc_layout_scalar_valid_range(cx, args)
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(n, cx.attr_span))
parse_single_integer(cx, args)
.map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(Box::new(n), cx.attr_span))
}
}

fn parse_rustc_layout_scalar_valid_range<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser<'_>,
) -> Option<Box<u128>> {
let Some(list) = args.list() else {
cx.expected_list(cx.attr_span);
return None;
};
let Some(single) = list.single() else {
cx.expected_single_argument(list.span);
return None;
};
let Some(lit) = single.lit() else {
cx.expected_integer_literal(single.span());
return None;
};
let LitKind::Int(num, _ty) = lit.kind else {
cx.expected_integer_literal(single.span());
return None;
};
Some(Box::new(num.0))
}

pub(crate) struct RustcObjectLifetimeDefaultParser;

impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {
Expand Down
41 changes: 36 additions & 5 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::ops::{Deref, DerefMut};
use std::sync::LazyLock;

use private::Sealed;
use rustc_ast::{self as ast, MetaItemLit, NodeId};
use rustc_ast::{self as ast, LitKind, MetaItemLit, NodeId};
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::lints::{AttributeLint, AttributeLintKind};
use rustc_errors::{DiagCtxtHandle, Diagnostic};
Expand All @@ -16,16 +16,16 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};

use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
use crate::attributes::codegen_attrs::{
ColdParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser, TargetFeatureParser,
TrackCallerParser, UsedParser,
ColdParser, ExportNameParser, NakedParser, NoMangleParser, OmitGdbPrettyPrinterSectionParser,
OptimizeParser, TargetFeatureParser, TrackCallerParser, UsedParser,
};
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::dummy::DummyParser;
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
use crate::attributes::link_attrs::{
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser,
StdInternalSymbolParser,
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser,
LinkSectionParser, StdInternalSymbolParser,
};
use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
Expand Down Expand Up @@ -141,6 +141,7 @@ attribute_parsers!(
Single<IgnoreParser>,
Single<InlineParser>,
Single<LinkNameParser>,
Single<LinkOrdinalParser>,
Single<LinkSectionParser>,
Single<MustUseParser>,
Single<OptimizeParser>,
Expand Down Expand Up @@ -171,6 +172,7 @@ attribute_parsers!(
Single<WithoutArgs<NoImplicitPreludeParser>>,
Single<WithoutArgs<NoMangleParser>>,
Single<WithoutArgs<NonExhaustiveParser>>,
Single<WithoutArgs<OmitGdbPrettyPrinterSectionParser>>,
Single<WithoutArgs<ParenSugarParser>>,
Single<WithoutArgs<PassByValueParser>>,
Single<WithoutArgs<PubTransparentParser>>,
Expand Down Expand Up @@ -772,3 +774,32 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
}
}
}

/// Parse a single integer.
///
/// Used by attributes that take a single integer as argument, such as
/// `#[link_ordinal]` and `#[rustc_layout_scalar_valid_range_start]`.
/// `cx` is the context given to the attribute.
/// `args` is the parser for the attribute arguments.
pub(crate) fn parse_single_integer<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser<'_>,
) -> Option<u128> {
let Some(list) = args.list() else {
cx.expected_list(cx.attr_span);
return None;
};
let Some(single) = list.single() else {
cx.expected_single_argument(list.span);
return None;
};
let Some(lit) = single.lit() else {
cx.expected_integer_literal(single.span());
return None;
};
let LitKind::Int(num, _ty) = lit.kind else {
cx.expected_integer_literal(single.span());
return None;
};
Some(num.0)
}
9 changes: 9 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,15 @@ pub(crate) struct NakedFunctionIncompatibleAttribute {
pub attr: String,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_link_ordinal_out_of_range)]
#[note]
pub(crate) struct LinkOrdinalOutOfRange {
#[primary_span]
pub span: Span,
pub ordinal: u128,
}

pub(crate) enum AttributeParseErrorReason {
ExpectedNoArgs,
ExpectedStringLiteral { byte_string: Option<Span> },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}

GenericArgKind::Type(mut t1) => {
// Scraped constraints may have had inference vars.
t1 = self.infcx.resolve_vars_if_possible(t1);

// Normalize the type we receive from a `TypeOutlives` obligation
// in the new trait solver.
if infcx.next_trait_solver() {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// .debug_gdb_scripts binary section.

use rustc_ast::attr;
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
use rustc_codegen_ssa::traits::*;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType;
use rustc_session::config::{CrateType, DebugInfo};
use rustc_span::sym;

use crate::builder::Builder;
use crate::common::CodegenCx;
Expand Down Expand Up @@ -87,7 +86,7 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(

pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
let omit_gdb_pretty_printer_section =
attr::contains_name(cx.tcx.hir_krate_attrs(), sym::omit_gdb_pretty_printer_section);
find_attr!(cx.tcx.hir_krate_attrs(), AttributeKind::OmitGdbPrettyPrinterSection);

// To ensure the section `__rustc_debug_gdb_scripts_section__` will not create
// ODR violations at link time, this section will not be emitted for rlibs since
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extensio
codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced
codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal`
.note = an unsuffixed integer value, e.g., `1`, is expected
codegen_ssa_incorrect_cgu_reuse_type =
CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
[one] {"at least "}
Expand All @@ -93,9 +90,6 @@ codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and i
codegen_ssa_invalid_instruction_set = invalid instruction set specified
codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]`
.note = the attribute requires exactly one argument
codegen_ssa_invalid_literal_value = invalid literal value
.label = value must be an integer between `0` and `255`
Expand Down
49 changes: 4 additions & 45 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
AttributeKind::LinkOrdinal { ordinal, span } => {
codegen_fn_attrs.link_ordinal = Some(*ordinal);
link_ordinal_span = Some(*span);
}
AttributeKind::LinkSection { name, .. } => {
codegen_fn_attrs.link_section = Some(*name)
}
Expand Down Expand Up @@ -250,12 +254,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
}
}
sym::link_ordinal => {
link_ordinal_span = Some(attr.span());
if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) {
codegen_fn_attrs.link_ordinal = ordinal;
}
}
sym::no_sanitize => {
no_sanitize_span = Some(attr.span());
if let Some(list) = attr.meta_item_list() {
Expand Down Expand Up @@ -568,45 +566,6 @@ fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> {
tcx.codegen_fn_attrs(opt_trait_item(tcx, def_id)?).alignment
}

fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
let meta_item_list = attr.meta_item_list()?;
let [sole_meta_list] = &meta_item_list[..] else {
tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span() });
return None;
};
if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
sole_meta_list.lit()
{
// According to the table at
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
// ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import
// information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
//
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for
// this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that
// specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import
// library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an
// import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I
// don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
// see earlier comment about LINK.EXE failing.)
if *ordinal <= u16::MAX as u128 {
Some(ordinal.get() as u16)
} else {
let msg = format!("ordinal value in `link_ordinal` is too large: `{ordinal}`");
tcx.dcx()
.struct_span_err(attr.span(), msg)
.with_note("the value may not exceed `u16::MAX`")
.emit();
None
}
} else {
tcx.dcx().emit_err(errors::InvalidLinkOrdinalFormat { span: attr.span() });
None
}
}

fn check_link_name_xor_ordinal(
tcx: TyCtxt<'_>,
codegen_fn_attrs: &CodegenFnAttrs,
Expand Down
Loading
Loading