Skip to content

Commit 22be76b

Browse files
committed
Auto merge of #142901 - matthiaskrgr:rollup-topt4p6, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #141597 (Document subdirectories of UI tests with README files) - #142823 (Port `#[no_mangle]` to new attribute parsing infrastructure) - #142828 (1.88.0 release notes) - #142854 (centralize `-Zmin-function-alignment` logic) - #142875 (Check rustdoc-json-types FORMAT_VERSION is correctly updated) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 58d5e11 + 1104920 commit 22be76b

File tree

24 files changed

+1854
-97
lines changed

24 files changed

+1854
-97
lines changed

RELEASES.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,103 @@
1+
Version 1.88.0 (2025-06-26)
2+
==========================
3+
4+
<a id="1.88.0-Language"></a>
5+
6+
Language
7+
--------
8+
- [Stabilize `#![feature(let_chains)]` in the 2024 edition.](https://github.com/rust-lang/rust/pull/132833)
9+
This feature allows `&&`-chaining `let` statements inside `if` and `while`, allowing intermixture with boolean expressions. The patterns inside the `let` sub-expressions can be irrefutable or refutable.
10+
- [Stabilize `#![feature(naked_functions)]`.](https://github.com/rust-lang/rust/pull/134213)
11+
Naked functions allow writing functions with no compiler-generated epilogue and prologue, allowing full control over the generated assembly for a particular function.
12+
- [Stabilize `#![feature(cfg_boolean_literals)]`.](https://github.com/rust-lang/rust/pull/138632)
13+
This allows using boolean literals as `cfg` predicates, e.g. `#[cfg(true)]` and `#[cfg(false)]`.
14+
- [Fully de-stabilize the `#[bench]` attribute](https://github.com/rust-lang/rust/pull/134273). Usage of `#[bench]` without `#![feature(custom_test_frameworks)]` already triggered a deny-by-default future-incompatibility lint since Rust 1.77, but will now become a hard error.
15+
- [Add warn-by-default `dangerous_implicit_autorefs` lint against implicit autoref of raw pointer dereference.](https://github.com/rust-lang/rust/pull/123239)
16+
The lint [will be bumped to deny-by-default](https://github.com/rust-lang/rust/pull/141661) in the next version of Rust.
17+
- [Add `invalid_null_arguments` lint to prevent invalid usage of null pointers.](https://github.com/rust-lang/rust/pull/119220)
18+
This lint is uplifted from `clippy::invalid_null_ptr_usage`.
19+
- [Change trait impl candidate preference for builtin impls and trivial where-clauses.](https://github.com/rust-lang/rust/pull/138176)
20+
- [Check types of generic const parameter defaults](https://github.com/rust-lang/rust/pull/139646)
21+
22+
<a id="1.88.0-Compiler"></a>
23+
24+
Compiler
25+
--------
26+
- [Stabilize `-Cdwarf-version` for selecting the version of DWARF debug information to generate.](https://github.com/rust-lang/rust/pull/136926)
27+
28+
29+
<a id="1.88.0-Platform-Support"></a>
30+
31+
Platform Support
32+
----------------
33+
- [Demote `i686-pc-windows-gnu` to Tier 2.](https://blog.rust-lang.org/2025/05/26/demoting-i686-pc-windows-gnu/)
34+
35+
36+
Refer to Rust's [platform support page][platform-support-doc]
37+
for more information on Rust's tiered platform support.
38+
39+
[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html
40+
41+
<a id="1.88.0-Libraries"></a>
42+
43+
Libraries
44+
---------
45+
- [Remove backticks from `#[should_panic]` test failure message.](https://github.com/rust-lang/rust/pull/136160)
46+
- [Guarantee that `[T; N]::from_fn` is generated in order of increasing indices.](https://github.com/rust-lang/rust/pull/139099), for those passing it a stateful closure.
47+
- [The libtest flag `--nocapture` is deprecated in favor of the more consistent `--no-capture` flag.](https://github.com/rust-lang/rust/pull/139224)
48+
- [Guarantee that `{float}::NAN` is a quiet NaN.](https://github.com/rust-lang/rust/pull/139483)
49+
50+
51+
<a id="1.88.0-Stabilized-APIs"></a>
52+
53+
Stabilized APIs
54+
---------------
55+
56+
- [`Cell::update`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#method.update)
57+
- [`impl Default for *const T`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#impl-Default-for-*const+T)
58+
- [`impl Default for *mut T`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#impl-Default-for-*mut+T)
59+
- [`HashMap::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html#method.extract_if)
60+
- [`HashSet::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.HashSet.html#method.extract_if)
61+
- [`proc_macro::Span::line`](https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.line)
62+
- [`proc_macro::Span::column`](https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.column)
63+
- [`proc_macro::Span::start`](https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.start)
64+
- [`proc_macro::Span::end`](https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.end)
65+
- [`proc_macro::Span::file`](https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.file)
66+
- [`proc_macro::Span::local_file`](https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.local_file)
67+
68+
These previously stable APIs are now stable in const contexts:
69+
70+
- [`NonNull<T>::replace`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.replace)
71+
- [`<*mut T>::replace`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.replace)
72+
- [`std::ptr::swap_nonoverlapping`](https://github.com/rust-lang/rust/pull/137280)
73+
- [`Cell::{replace, get, get_mut, from_mut, as_slice_of_cells}`](https://github.com/rust-lang/rust/pull/137928)
74+
75+
76+
<a id="1.88.0-Cargo"></a>
77+
78+
Cargo
79+
-----
80+
- [Stabilize automatic garbage collection.](https://github.com/rust-lang/cargo/pull/14287/)
81+
- [use `zlib-rs` for gzip compression in rust code](https://github.com/rust-lang/cargo/pull/15417/)
82+
83+
<a id="1.88.0-Rustdoc"></a>
84+
85+
Rustdoc
86+
-----
87+
- [Doctests can be ignored based on target names using `ignore-*` attributes.](https://github.com/rust-lang/rust/pull/137096)
88+
- [Stabilize the `--test-runtool` and `--test-runtool-arg` CLI options to specify a program (like qemu) and its arguments to run a doctest.](https://github.com/rust-lang/rust/pull/137096)
89+
90+
<a id="1.88.0-Compatibility-Notes"></a>
91+
92+
Compatibility Notes
93+
-------------------
94+
- [Finish changing the internal representation of pasted tokens](https://github.com/rust-lang/rust/pull/124141). Certain invalid declarative macros that were previously accepted in obscure circumstances are now correctly rejected by the compiler. Use of a `tt` fragment specifier can often fix these macros.
95+
- [Fully de-stabilize the `#[bench]` attribute](https://github.com/rust-lang/rust/pull/134273). Usage of `#[bench]` without `#![feature(custom_test_frameworks)]` already triggered a deny-by-default future-incompatibility lint since Rust 1.77, but will now become a hard error.
96+
- [Fix borrow checking some always-true patterns.](https://github.com/rust-lang/rust/pull/139042)
97+
The borrow checker was overly permissive in some cases, allowing programs that shouldn't have compiled.
98+
- [Update the minimum external LLVM to 19.](https://github.com/rust-lang/rust/pull/139275)
99+
- [Make it a hard error to use a vector type with a non-Rust ABI without enabling the required target feature.](https://github.com/rust-lang/rust/pull/139309)
100+
1101
Version 1.87.0 (2025-05-15)
2102
==========================
3103

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ pub enum AttributeKind {
244244
reason: Option<Symbol>,
245245
},
246246

247+
/// Represents `#[no_mangle]`
248+
NoMangle(Span),
249+
247250
/// Represents `#[optimize(size|speed)]`
248251
Optimize(OptimizeAttr, Span),
249252

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,21 @@ impl<S: Stage> SingleAttributeParser<S> for ColdParser {
5656
Some(AttributeKind::Cold(cx.attr_span))
5757
}
5858
}
59+
60+
pub(crate) struct NoMangleParser;
61+
62+
impl<S: Stage> SingleAttributeParser<S> for NoMangleParser {
63+
const PATH: &[rustc_span::Symbol] = &[sym::no_mangle];
64+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
65+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
66+
const TEMPLATE: AttributeTemplate = template!(Word);
67+
68+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
69+
if !args.no_args() {
70+
cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
71+
return None;
72+
};
73+
74+
Some(AttributeKind::NoMangle(cx.attr_span))
75+
}
76+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_session::Session;
1515
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
1616

1717
use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
18-
use crate::attributes::codegen_attrs::{ColdParser, OptimizeParser};
18+
use crate::attributes::codegen_attrs::{ColdParser, NoMangleParser, OptimizeParser};
1919
use crate::attributes::confusables::ConfusablesParser;
2020
use crate::attributes::deprecation::DeprecationParser;
2121
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
@@ -114,6 +114,7 @@ attribute_parsers!(
114114
Single<InlineParser>,
115115
Single<MayDangleParser>,
116116
Single<MustUseParser>,
117+
Single<NoMangleParser>,
117118
Single<OptimizeParser>,
118119
Single<PubTransparentParser>,
119120
Single<RustcForceInlineParser>,

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -491,11 +491,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
491491
let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
492492
attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
493493
}
494-
// function alignment can be set globally with the `-Zmin-function-alignment=<n>` flag;
495-
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
496-
if let Some(align) =
497-
Ord::max(cx.tcx.sess.opts.unstable_opts.min_function_alignment, codegen_fn_attrs.alignment)
498-
{
494+
if let Some(align) = codegen_fn_attrs.alignment {
499495
llvm::set_alignment(llfn, align);
500496
}
501497
if let Some(backchain) = backchain_attr(cx) {

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple time
221221
222222
codegen_ssa_no_field = no field `{$name}`
223223
224+
codegen_ssa_no_mangle_nameless = `#[no_mangle]` cannot be used on {$definition} as it has no name
225+
224226
codegen_ssa_no_module_named =
225227
no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names}
226228

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_span::{Ident, Span, sym};
2323
use rustc_target::spec::SanitizerSet;
2424

2525
use crate::errors;
26+
use crate::errors::NoMangleNameless;
2627
use crate::target_features::{
2728
check_target_feature_trait_unsafe, check_tied_features, from_target_feature_attr,
2829
};
@@ -87,7 +88,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
8788
let mut link_ordinal_span = None;
8889
let mut no_sanitize_span = None;
8990
let mut mixed_export_name_no_mangle_lint_state = MixedExportNameAndNoMangleState::default();
90-
let mut no_mangle_span = None;
9191

9292
for attr in attrs.iter() {
9393
// In some cases, attribute are only valid on functions, but it's the `check_attr`
@@ -122,10 +122,35 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
122122
}
123123
AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
124124
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
125+
AttributeKind::NoMangle(attr_span) => {
126+
if tcx.opt_item_name(did.to_def_id()).is_some() {
127+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
128+
mixed_export_name_no_mangle_lint_state.track_no_mangle(
129+
*attr_span,
130+
tcx.local_def_id_to_hir_id(did),
131+
attr,
132+
);
133+
} else {
134+
tcx.dcx().emit_err(NoMangleNameless {
135+
span: *attr_span,
136+
definition: format!(
137+
"{} {}",
138+
tcx.def_descr_article(did.to_def_id()),
139+
tcx.def_descr(did.to_def_id())
140+
),
141+
});
142+
}
143+
}
125144
_ => {}
126145
}
127146
}
128147

148+
// Apply the minimum function alignment here, so that individual backends don't have to.
149+
codegen_fn_attrs.alignment = Ord::max(
150+
codegen_fn_attrs.alignment,
151+
tcx.sess.opts.unstable_opts.min_function_alignment,
152+
);
153+
129154
let Some(Ident { name, .. }) = attr.ident() else {
130155
continue;
131156
};
@@ -141,28 +166,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
141166
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
142167
}
143168
sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
144-
sym::no_mangle => {
145-
no_mangle_span = Some(attr.span());
146-
if tcx.opt_item_name(did.to_def_id()).is_some() {
147-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
148-
mixed_export_name_no_mangle_lint_state.track_no_mangle(
149-
attr.span(),
150-
tcx.local_def_id_to_hir_id(did),
151-
attr,
152-
);
153-
} else {
154-
tcx.dcx()
155-
.struct_span_err(
156-
attr.span(),
157-
format!(
158-
"`#[no_mangle]` cannot be used on {} {} as it has no name",
159-
tcx.def_descr_article(did.to_def_id()),
160-
tcx.def_descr(did.to_def_id()),
161-
),
162-
)
163-
.emit();
164-
}
165-
}
166169
sym::rustc_std_internal_symbol => {
167170
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
168171
}
@@ -544,12 +547,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
544547
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
545548
&& codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
546549
{
550+
let no_mangle_span =
551+
find_attr!(attrs, AttributeKind::NoMangle(no_mangle_span) => *no_mangle_span)
552+
.unwrap_or_default();
547553
let lang_item =
548554
lang_items::extract(attrs).map_or(None, |(name, _span)| LangItem::from_name(name));
549555
let mut err = tcx
550556
.dcx()
551557
.struct_span_err(
552-
no_mangle_span.unwrap_or_default(),
558+
no_mangle_span,
553559
"`#[no_mangle]` cannot be used on internal language items",
554560
)
555561
.with_note("Rustc requires this item to have a specific mangled name.")

compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,3 +1310,11 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_
13101310
diag
13111311
}
13121312
}
1313+
1314+
#[derive(Diagnostic)]
1315+
#[diag(codegen_ssa_no_mangle_nameless)]
1316+
pub(crate) struct NoMangleNameless {
1317+
#[primary_span]
1318+
pub span: Span,
1319+
pub definition: String,
1320+
}

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,8 @@ fn prefix_and_suffix<'tcx>(
131131
let attrs = tcx.codegen_fn_attrs(instance.def_id());
132132
let link_section = attrs.link_section.map(|symbol| symbol.as_str().to_string());
133133

134-
// function alignment can be set globally with the `-Zmin-function-alignment=<n>` flag;
135-
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
136-
// if no alignment is specified, an alignment of 4 bytes is used.
137-
let min_function_alignment = tcx.sess.opts.unstable_opts.min_function_alignment;
138-
let align_bytes =
139-
Ord::max(min_function_alignment, attrs.alignment).map(|a| a.bytes()).unwrap_or(4);
134+
// If no alignment is specified, an alignment of 4 bytes is used.
135+
let align_bytes = attrs.alignment.map(|a| a.bytes()).unwrap_or(4);
140136

141137
// In particular, `.arm` can also be written `.code 32` and `.thumb` as `.code 16`.
142138
let (arch_prefix, arch_suffix) = if is_arm {

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -877,12 +877,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
877877
if let Some(fn_val) = self.get_fn_alloc(id) {
878878
let align = match fn_val {
879879
FnVal::Instance(instance) => {
880-
// Function alignment can be set globally with the `-Zmin-function-alignment=<n>` flag;
881-
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
882-
let fn_align = self.tcx.codegen_fn_attrs(instance.def_id()).alignment;
883-
let global_align = self.tcx.sess.opts.unstable_opts.min_function_alignment;
884-
885-
Ord::max(global_align, fn_align).unwrap_or(Align::ONE)
880+
self.tcx.codegen_fn_attrs(instance.def_id()).alignment.unwrap_or(Align::ONE)
886881
}
887882
// Machine-specific extra functions currently do not support alignment restrictions.
888883
FnVal::Other(_) => Align::ONE,

compiler/rustc_lint/src/builtin.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
2121
use rustc_ast::visit::{FnCtxt, FnKind};
2222
use rustc_ast::{self as ast, *};
2323
use rustc_ast_pretty::pprust::expr_to_string;
24+
use rustc_attr_data_structures::{AttributeKind, find_attr};
2425
use rustc_errors::{Applicability, LintDiagnostic};
2526
use rustc_feature::GateIssue;
2627
use rustc_hir as hir;
@@ -954,7 +955,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN
954955
impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
955956
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
956957
let attrs = cx.tcx.hir_attrs(it.hir_id());
957-
let check_no_mangle_on_generic_fn = |attr: &hir::Attribute,
958+
let check_no_mangle_on_generic_fn = |attr_span: Span,
958959
impl_generics: Option<&hir::Generics<'_>>,
959960
generics: &hir::Generics<'_>,
960961
span| {
@@ -967,7 +968,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
967968
cx.emit_span_lint(
968969
NO_MANGLE_GENERIC_ITEMS,
969970
span,
970-
BuiltinNoMangleGeneric { suggestion: attr.span() },
971+
BuiltinNoMangleGeneric { suggestion: attr_span },
971972
);
972973
break;
973974
}
@@ -976,14 +977,15 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
976977
};
977978
match it.kind {
978979
hir::ItemKind::Fn { generics, .. } => {
979-
if let Some(attr) = attr::find_by_name(attrs, sym::export_name)
980-
.or_else(|| attr::find_by_name(attrs, sym::no_mangle))
980+
if let Some(attr_span) = attr::find_by_name(attrs, sym::export_name)
981+
.map(|at| at.span())
982+
.or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span))
981983
{
982-
check_no_mangle_on_generic_fn(attr, None, generics, it.span);
984+
check_no_mangle_on_generic_fn(attr_span, None, generics, it.span);
983985
}
984986
}
985987
hir::ItemKind::Const(..) => {
986-
if attr::contains_name(attrs, sym::no_mangle) {
988+
if find_attr!(attrs, AttributeKind::NoMangle(..)) {
987989
// account for "pub const" (#45562)
988990
let start = cx
989991
.tcx
@@ -1008,11 +1010,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
10081010
for it in *items {
10091011
if let hir::AssocItemKind::Fn { .. } = it.kind {
10101012
let attrs = cx.tcx.hir_attrs(it.id.hir_id());
1011-
if let Some(attr) = attr::find_by_name(attrs, sym::export_name)
1012-
.or_else(|| attr::find_by_name(attrs, sym::no_mangle))
1013+
if let Some(attr_span) = attr::find_by_name(attrs, sym::export_name)
1014+
.map(|at| at.span())
1015+
.or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span))
10131016
{
10141017
check_no_mangle_on_generic_fn(
1015-
attr,
1018+
attr_span,
10161019
Some(generics),
10171020
cx.tcx.hir_get_generics(it.id.owner_id.def_id).unwrap(),
10181021
it.span,

0 commit comments

Comments
 (0)