Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c5388d8
Fix feature gate for `repr(simd)`
JonathanBrouwer Jun 28, 2026
88a3c51
std: use `OnceLock` for SGX argument storage
joboet Jun 20, 2026
16dc408
Include AtomicU128/AtomicI128 in docs for any target
pluiee Jun 22, 2026
0f52e52
Fix various issues in Arc::make_mut and Rc::make_mut
maxdexh Jul 6, 2026
54bf52f
std: fix Xous UDP send_to length mismatch and truncation
devnexen Jul 7, 2026
015e8af
rustdoc: test ignoring rustc lints in CLI
notriddle May 15, 2026
83f5101
Look for the cdb architecture that corresponds to the target triple
Fulgen301 Jul 10, 2026
f5c700e
riscv: update c-variadic test for LLVM changes
durin42 Jul 10, 2026
64e2dd5
pretty-print: use inline asm's actual macro name
jakobjung10 Jul 10, 2026
920f3f1
Suggest `generic_const_args` + `type const` in const operation diagno…
Dnreikronos May 26, 2026
9211a89
Update const generic diagnostic fixture
Dnreikronos Jul 7, 2026
d905d0a
Add regression test for dollar-prefixed fragments in a repetition
asuto15 Jul 11, 2026
2200ed1
Add requested description comment
notriddle Jul 11, 2026
05a2bf7
doc: use ptr::addr in offset_from docs
kn1g78 Jul 11, 2026
74dc8e7
shrink mir::Statement to 40 bytes
panstromek Jul 9, 2026
fbef898
Fix PR number in bootstrap's change tracker
Kobzol Jul 11, 2026
e50eb58
Rollup merge of #159126 - Kobzol:bootstrap-fix-pr-number, r=Mark-Simu…
JonathanBrouwer Jul 11, 2026
fb6c55b
Rollup merge of #155811 - pluiee:pluiee/atomic-128-doc, r=Mark-Simula…
JonathanBrouwer Jul 11, 2026
aa8cf33
Rollup merge of #156968 - Dnreikronos:fix/gca-const-item-diagnostic-1…
JonathanBrouwer Jul 11, 2026
8c60f8c
Rollup merge of #159012 - panstromek:make-stmtdebuginfos-smaller, r=J…
JonathanBrouwer Jul 11, 2026
ce7f185
Rollup merge of #156618 - notriddle:rustdoc-lint-ignore-cli, r=lolbin…
JonathanBrouwer Jul 11, 2026
ac1e457
Rollup merge of #158182 - joboet:sgx_args_oncelock, r=clarfonthey
JonathanBrouwer Jul 11, 2026
891ee9d
Rollup merge of #159114 - asuto15:macro-fragment-regression, r=chenyu…
JonathanBrouwer Jul 11, 2026
b1bc4c6
Rollup merge of #158523 - JonathanBrouwer:repr_simd, r=mejrs
JonathanBrouwer Jul 11, 2026
a22bffb
Rollup merge of #158876 - maxdexh:bugfix-arc-make-mut, r=Mark-Simulacrum
JonathanBrouwer Jul 11, 2026
2666ceb
Rollup merge of #158928 - devnexen:xous_udp_fix, r=Mark-Simulacrum
JonathanBrouwer Jul 11, 2026
d596cdf
Rollup merge of #159060 - Fulgen301:bootstrap-cdb-discovery-target, r…
JonathanBrouwer Jul 11, 2026
f709f68
Rollup merge of #159089 - durin42:llvm-23-riscv-asm, r=folkertdev
JonathanBrouwer Jul 11, 2026
0ad6776
Rollup merge of #159093 - jakobjung10:pretty-print-asm-macro-name, r=…
JonathanBrouwer Jul 11, 2026
7e86eec
Rollup merge of #159122 - kn1g78:fix/ptr-addr-docs, r=hanna-kruppe
JonathanBrouwer Jul 11, 2026
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
1 change: 0 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3733,7 +3733,6 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"thin-vec",
]

[[package]]
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast_passes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,4 @@ rustc_macros = { path = "../rustc_macros" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
thin-vec = "0.2.18"
# tidy-alphabetical-end
16 changes: 0 additions & 16 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use rustc_hir::attrs::AttributeKind;
use rustc_session::Session;
use rustc_session::errors::{feature_err, feature_warn};
use rustc_span::{Span, Spanned, Symbol, sym};
use thin_vec::ThinVec;

use crate::diagnostics;

Expand Down Expand Up @@ -188,21 +187,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::ItemKind::ForeignMod(_foreign_module) => {
// handled during lowering
}
ast::ItemKind::Struct(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..) => {
for attr in attr::filter_by_name(&i.attrs, sym::repr) {
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
if item.has_name(sym::simd) {
gate!(
self,
repr_simd,
attr.span,
"SIMD types are experimental and possibly buggy"
);
}
}
}
}

ast::ItemKind::Impl(ast::Impl { of_trait: Some(of_trait), .. }) => {
if let ast::ImplPolarity::Negative(span) = of_trait.polarity {
gate!(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ impl<'a> State<'a> {
}
ast::ExprKind::InlineAsm(a) => {
// FIXME: Print `builtin # asm` once macro `asm` uses `builtin_syntax`.
self.word("asm!");
self.word(format!("{}!", a.asm_macro.macro_name()));
self.print_inline_asm(a);
}
ast::ExprKind::FormatArgs(fmt) => {
Expand Down
18 changes: 11 additions & 7 deletions compiler/rustc_attr_parsing/src/attributes/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use rustc_ast::{IntTy, LitIntType, LitKind, UintTy};
use rustc_feature::AttributeStability;
use rustc_hir::attrs::IntType::{SignedInt, UnsignedInt};
use rustc_hir::attrs::ReprAttr;
use rustc_session::errors::feature_err;

use super::prelude::*;
use crate::session_diagnostics;
Expand Down Expand Up @@ -141,13 +142,16 @@ fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option<
Some(ReprC)
}
Some(sym::simd) => {
cx.check_target(
"(simd)",
&AllowedTargets::AllowList(&[
Allow(Target::Struct), // Feature gated in `rustc_ast_passes`
Warn(Target::MacroCall), // FIXME: This is not feature gated (!!)
]),
);
if cx.features.is_some_and(|feats| !feats.repr_simd()) {
feature_err(
&cx.sess(),
sym::repr_simd,
param.span(),
"SIMD types are experimental and possibly buggy",
)
.emit();
}
cx.check_target("(simd)", &AllowedTargets::AllowList(&[Allow(Target::Struct)]));
cx.expect_no_args(param.args())?;
Some(ReprSimd)
}
Expand Down
15 changes: 9 additions & 6 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,13 +431,16 @@ impl<'tcx> ForbidParamUsesFolder<'tcx> {
diag.span_note(impl_.self_ty.span, "not a concrete type");
}
}
if matches!(self.context, ForbidParamContext::ConstArgument)
&& self.tcx.features().min_generic_const_args()
{
if !self.tcx.features().generic_const_args() {
diag.help("add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items");
} else {
if matches!(self.context, ForbidParamContext::ConstArgument) {
if self.tcx.features().generic_const_args() {
diag.help("consider factoring the expression into a `type const` item and use it as the const argument instead");
} else if self.tcx.features().min_generic_const_args() {
diag.help("add `#![feature(generic_const_args)]` and extract the expression into a `type const` item");
} else if self.tcx.sess.is_nightly_build() {
diag.help(
"add `#![feature(generic_const_exprs)]` to allow generic const expressions",
);
diag.help("alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item");
}
}
diag.emit()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1739,7 +1739,7 @@ impl<'a> State<'a> {
self.print_expr_cond_paren(result, self.precedence(result) < ExprPrecedence::Jump);
}
hir::ExprKind::InlineAsm(asm) => {
self.word("asm!");
self.word(format!("{}!", asm.asm_macro.macro_name()));
self.print_inline_asm(asm);
}
hir::ExprKind::OffsetOf(container, fields) => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1730,10 +1730,10 @@ mod size_asserts {

use super::*;
// tidy-alphabetical-start
static_assert_size!(BasicBlockData<'_>, 160);
static_assert_size!(BasicBlockData<'_>, 144);
static_assert_size!(LocalDecl<'_>, 40);
static_assert_size!(SourceScopeData<'_>, 64);
static_assert_size!(Statement<'_>, 56);
static_assert_size!(Statement<'_>, 40);
static_assert_size!(Terminator<'_>, 104);
static_assert_size!(VarDebugInfo<'_>, 88);
// tidy-alphabetical-end
Expand Down
86 changes: 64 additions & 22 deletions compiler/rustc_middle/src/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::ops;

use rustc_data_structures::outline;
use tracing::{debug, instrument};

use super::interpret::GlobalAlloc;
Expand Down Expand Up @@ -1034,66 +1035,107 @@ impl RawPtrKind {
}
}

// FIXME(panstromek)
// I'd like to use real ThinVec here, but it fails to borrow check,
// probably because ThinVec doesn't have #[may_dangle] on Drop impl?
type ThinVec<T> = Option<Box<Vec<T>>>;

// This collection is almost always empty, so we
// use thin representation and optimize all methods
// for that by inlining the empty check
// and outlining the rest.
#[derive(Default, Debug, Clone, TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable)]
pub struct StmtDebugInfos<'tcx>(Vec<StmtDebugInfo<'tcx>>);
pub struct StmtDebugInfos<'tcx>(ThinVec<StmtDebugInfo<'tcx>>);

impl<'tcx> StmtDebugInfos<'tcx> {
pub fn push(&mut self, debuginfo: StmtDebugInfo<'tcx>) {
self.0.push(debuginfo);
self.0.get_or_insert_default().push(debuginfo);
}

#[inline]
pub fn drop_debuginfo(&mut self) {
self.0.clear();
match &mut self.0 {
None => (),
Some(v) => outline(move || v.clear()),
}
}

#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
match &self.0 {
None => true,
Some(v) => outline(move || v.is_empty()),
}
}

#[inline]
pub fn prepend(&mut self, debuginfos: &mut Self) {
if debuginfos.is_empty() {
return;
};
debuginfos.0.append(self);
std::mem::swap(debuginfos, self);
outline(move || {
debuginfos.append(self);
std::mem::swap(debuginfos, self);
})
}

#[inline]
pub fn append(&mut self, debuginfos: &mut Self) {
if debuginfos.is_empty() {
return;
};
self.0.append(debuginfos);
outline(move || {
self.0.get_or_insert_default().append(debuginfos.0.as_mut().unwrap().as_mut())
});
}

#[inline]
pub fn extend(&mut self, debuginfos: &Self) {
if debuginfos.is_empty() {
return;
};
self.0.extend_from_slice(debuginfos);
outline(move || self.0.get_or_insert_default().extend_from_slice(debuginfos.as_slice()))
}

#[inline]
pub fn as_slice(&self) -> &[StmtDebugInfo<'tcx>] {
match &self.0 {
None => &[],
Some(items) => outline(move || items.as_slice()),
}
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [StmtDebugInfo<'tcx>] {
match &mut self.0 {
None => &mut [],
Some(items) => outline(move || items.as_mut_slice()),
}
}
#[inline]
pub fn retain_locals(&mut self, locals: &DenseBitSet<Local>) {
self.retain(|debuginfo| match debuginfo {
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => {
locals.contains(*local)
}
});
match &mut self.0 {
None => (),
Some(items) => outline(move || {
items.retain(|debuginfo| match debuginfo {
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => {
locals.contains(*local)
}
})
}),
}
}
}

impl<'tcx> ops::Deref for StmtDebugInfos<'tcx> {
type Target = Vec<StmtDebugInfo<'tcx>>;
type Target = [StmtDebugInfo<'tcx>];

#[inline]
fn deref(&self) -> &Vec<StmtDebugInfo<'tcx>> {
&self.0
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}

impl<'tcx> ops::DerefMut for StmtDebugInfos<'tcx> {
#[inline]
fn deref_mut(&mut self) -> &mut Vec<StmtDebugInfo<'tcx>> {
&mut self.0
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_slice()
}
}

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,10 @@ pub(crate) struct ParamInNonTrivialAnonConst {
"consider factoring the expression into a `type const` item and use it as the const argument instead"
)]
pub(crate) help_gca: bool,
#[help(
"alternatively, you can use `#![feature(generic_const_args)]` and extract the expression into a `type const` item"
)]
pub(crate) help_suggest_gca: bool,
}

#[derive(Debug)]
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_resolve/src/error_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1288,9 +1288,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
span,
name,
param_kind: is_type,
help: self.tcx.sess.is_nightly_build(),
help: self.tcx.sess.is_nightly_build()
&& !self.tcx.features().min_generic_const_args(),
is_gca,
help_gca: is_gca,
help_suggest_gca: self.tcx.sess.is_nightly_build() && !is_gca,
})
}
ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => {
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3981,9 +3981,12 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
span: lifetime_ref.ident.span,
name: lifetime_ref.ident.name,
param_kind: diagnostics::ParamKindInNonTrivialAnonConst::Lifetime,
help: self.r.tcx.sess.is_nightly_build(),
help: self.r.tcx.sess.is_nightly_build()
&& !self.r.features.min_generic_const_args(),
is_gca: self.r.features.generic_const_args(),
help_gca: self.r.features.generic_const_args(),
help_suggest_gca: self.r.tcx.sess.is_nightly_build()
&& !self.r.features.generic_const_args(),
})
.emit()
}
Expand Down
10 changes: 8 additions & 2 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2090,8 +2090,6 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Rc<T, A> {
} else if Rc::weak_count(this) != 0 {
// Can just steal the data, all that's left is Weaks

// We don't need panic-protection like the above branch does, but we might as well
// use the same mechanism.
let mut in_progress: UniqueRcUninit<T, A> =
UniqueRcUninit::new(&**this, this.alloc.clone());
unsafe {
Expand All @@ -2104,10 +2102,18 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Rc<T, A> {
size_of_val,
);

// This leaves us with 0 strong refs, so the data has
// effectively been moved to the new rc.
this.inner().dec_strong();

// Remove implicit strong-weak ref (no need to craft a fake
// Weak here -- we know other Weaks can clean up for us)
this.inner().dec_weak();

// Last chance to not accidentally forget the allocator.
// Only drop at the end of the scope to avoid panics.
let _alloc = ptr::read(&this.alloc);

// Replace `this` with newly constructed Rc that has the moved data.
ptr::write(this, in_progress.into_rc());
}
Expand Down
32 changes: 26 additions & 6 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2539,16 +2539,27 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Arc<T, A> {
// usize::MAX (i.e., locked), since the weak count can only be
// locked by a thread with a strong reference.

// Materialize our own implicit weak pointer, so that it can clean
// up the ArcInner as needed.
let _weak = Weak { ptr: this.ptr, alloc: this.alloc.clone() };
// Guard against panics while using the allocator.
// If we unwind before the Arc is overwritten, we expose a strong
// count of 0, resulting in a UAF (#155746, #157203).
// Until the new Arc is written, the old Arc must remain valid
struct Guard<'a, T: ?Sized> {
inner: &'a ArcInner<T>,
}
impl<'a, T: ?Sized> Drop for Guard<'a, T> {
fn drop(&mut self) {
self.inner.strong.store(1, Release);
}
}
let guard = Guard { inner: this.inner() };

// Can just steal the data, all that's left is Weaks
//
// We don't need panic-protection like the above branch does, but we might as well
// use the same mechanism.
// Note that this can panic in two ways:
// - The allocation can fail
// - The allocator clone can fail
let mut in_progress: UniqueArcUninit<T, A> =
UniqueArcUninit::new(&**this, this.alloc.clone());

unsafe {
// Initialize `in_progress` with move of **this.
// We have to express this in terms of bytes because `T: ?Sized`; there is no
Expand All @@ -2559,6 +2570,15 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Arc<T, A> {
size_of_val,
);

// We are now safe from panics.
mem::forget(guard);

// Materialize our own implicit weak pointer, so that it can clean
// up the ArcInner as needed.
// Make sure the allocator is not leaked when the Arc is overwritten.
// Only drop at the end of the scope to avoid panics.
let _weak = Weak { ptr: this.ptr, alloc: ptr::read(&this.alloc) };

ptr::write(this, in_progress.into_arc());
}
} else {
Expand Down
Loading
Loading