Skip to content

Rollup of 16 pull requests #144387

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 40 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
41e6f76
future-incompat lints: don't link to the nightly edition-guide version
dianne Jul 16, 2025
dad96b1
Use serde for target spec json deserialize
Noratrieb Jul 20, 2025
c4eb077
Ensure we codegen and don't internalize the entrypoint
saethlin Jul 17, 2025
6e8762f
Use less HIR in check_private_in_public.
cjgillot Oct 1, 2023
0aa6170
Add a test case for ui test false-sealed-traits-note.rs
yuk1ty Jul 21, 2025
2d1fccd
pass build.npm from bootstrap to tidy and use it for npm install
lolbinarycat Jul 22, 2025
9e75032
rustdoc: avoid allocating a temp String for aliases in search index
lolbinarycat Jul 22, 2025
3440bc9
Unquerify extern_mod_stmt_cnum.
cjgillot Jul 3, 2025
95de0aa
rustc_resolve: get rid of unused rustdoc::span_of_fragments_with_expa…
lolbinarycat Jul 22, 2025
9bb9c39
Don't suggest assoc ty bound on non-angle-bracketed problematic assoc…
fmease Jul 22, 2025
eb9c654
std: net: uefi: Add support to query connection data
Ayush1325 Jul 12, 2025
af06bb9
Stop using the old `validate_attr` logic for stability attributes
JonathanBrouwer Jul 23, 2025
37480bc
coretests/num: use ldexp instead of hard-coding a power of 2
RalfJung Jul 21, 2025
371b010
generate elf symbol version in raw-dylib
usamoi Jul 20, 2025
8418ba5
Implement support for explicit tail calls in the MIR block builders a…
xacrimon Jul 20, 2025
41f2e9a
chore: clang-format
xacrimon Jul 20, 2025
e7992cf
move tests in codegen to codegen-llvm
xacrimon Jul 24, 2025
e62e191
chore: fix typo
xacrimon Jul 21, 2025
68bd357
don't end lifetimes after call
xacrimon Jul 21, 2025
c346311
recursion-no-tce.rs should be run-crash
xacrimon Jul 21, 2025
7689046
fix typo in codegen test
xacrimon Jul 21, 2025
898d905
add an error message if you attempt to pass indirect args via guarant…
xacrimon Jul 21, 2025
4028c67
use span_bug instead of bug
xacrimon Jul 21, 2025
6f1b56c
add Rev::into_inner
Qelxiros Jul 22, 2025
6f0d38e
Rollup merge of #143374 - cjgillot:bare-extern-crate-map, r=petrochenkov
fmease Jul 24, 2025
45108e1
Rollup merge of #143838 - Ayush1325:uefi-tcp4-config-data, r=tgross35
fmease Jul 24, 2025
e14fba7
Rollup merge of #144014 - dianne:edition-guide-links, r=estebank
fmease Jul 24, 2025
ccba7c8
Rollup merge of #144094 - saethlin:codegen-the-main-fn, r=petrochenkov
fmease Jul 24, 2025
9cb6fe1
Rollup merge of #144218 - Noratrieb:target-spec-json-de-jank, r=fee1-…
fmease Jul 24, 2025
d75e96a
Rollup merge of #144221 - usamoi:versym, r=bjorn3
fmease Jul 24, 2025
5b839dd
Rollup merge of #144232 - xacrimon:explicit-tail-call, r=oli-obk
fmease Jul 24, 2025
3562181
Rollup merge of #144240 - yuk1ty:false-sealed-traits-note-reported-in…
fmease Jul 24, 2025
910915e
Rollup merge of #144247 - RalfJung:ldexp, r=tgross35
fmease Jul 24, 2025
6108d5e
Rollup merge of #144276 - cjgillot:no-hir-privacy, r=petrochenkov
fmease Jul 24, 2025
7aa6359
Rollup merge of #144278 - Qelxiros:rev-into-inner, r=tgross35
fmease Jul 24, 2025
d6f2bf8
Rollup merge of #144317 - lolbinarycat:tidy-obey-build.npm, r=Kobzol
fmease Jul 24, 2025
1290134
Rollup merge of #144320 - lolbinarycat:rustdoc-search_index-BTreeMap-…
fmease Jul 24, 2025
eb18cc1
Rollup merge of #144334 - lolbinarycat:rustdoc-span_of_fragments-reve…
fmease Jul 24, 2025
02f69d8
Rollup merge of #144335 - fmease:no-angle-no-colon, r=SparrowLii
fmease Jul 24, 2025
7c241fc
Rollup merge of #144358 - JonathanBrouwer:fix-stability-malformed, r=…
fmease Jul 24, 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
13 changes: 13 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4563,7 +4563,10 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"serde",
"serde_derive",
"serde_json",
"serde_path_to_error",
"tracing",
]

Expand Down Expand Up @@ -4955,6 +4958,16 @@ dependencies = [
"serde",
]

[[package]]
name = "serde_path_to_error"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
dependencies = [
"itoa",
"serde",
]

[[package]]
name = "serde_spanned"
version = "0.6.9"
Expand Down
26 changes: 22 additions & 4 deletions compiler/rustc_attr_parsing/src/attributes/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,15 @@ impl<S: Stage> AttributeParser<S> for StabilityParser {
template!(NameValueStr: "deprecation message"),
|this, cx, args| {
reject_outside_std!(cx);
this.allowed_through_unstable_modules =
args.name_value().and_then(|i| i.value_as_str())
let Some(nv) = args.name_value() else {
cx.expected_name_value(cx.attr_span, None);
return;
};
let Some(value_str) = nv.value_as_str() else {
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return;
};
this.allowed_through_unstable_modules = Some(value_str);
},
),
];
Expand Down Expand Up @@ -247,7 +254,12 @@ pub(crate) fn parse_stability<S: Stage>(
let mut feature = None;
let mut since = None;

for param in args.list()?.mixed() {
let ArgParser::List(list) = args else {
cx.expected_list(cx.attr_span);
return None;
};

for param in list.mixed() {
let param_span = param.span();
let Some(param) = param.meta_item() else {
cx.emit_err(session_diagnostics::UnsupportedLiteral {
Expand Down Expand Up @@ -322,7 +334,13 @@ pub(crate) fn parse_unstability<S: Stage>(
let mut is_soft = false;
let mut implied_by = None;
let mut old_name = None;
for param in args.list()?.mixed() {

let ArgParser::List(list) = args else {
cx.expected_list(cx.attr_span);
return None;
};

for param in list.mixed() {
let Some(param) = param.meta_item() else {
cx.emit_err(session_diagnostics::UnsupportedLiteral {
span: param.span(),
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,21 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
call
}

fn tail_call(
&mut self,
_llty: Self::Type,
_fn_attrs: Option<&CodegenFnAttrs>,
_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
_llfn: Self::Value,
_args: &[Self::Value],
_funclet: Option<&Self::Funclet>,
_instance: Option<Instance<'tcx>>,
) {
bug!(
"Guaranteed tail calls with the 'become' keyword are not implemented in the GCC backend"
);
}

fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
// FIXME(antoyo): this does not zero-extend.
self.gcc_int_cast(value, dest_typ)
Expand Down
26 changes: 25 additions & 1 deletion compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
Expand All @@ -24,7 +25,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_sanitizers::{cfi, kcfi};
use rustc_session::config::OptLevel;
use rustc_span::Span;
use rustc_target::callconv::FnAbi;
use rustc_target::callconv::{FnAbi, PassMode};
use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
use smallvec::SmallVec;
use tracing::{debug, instrument};
Expand Down Expand Up @@ -1431,6 +1432,29 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
call
}

fn tail_call(
&mut self,
llty: Self::Type,
fn_attrs: Option<&CodegenFnAttrs>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
llfn: Self::Value,
args: &[Self::Value],
funclet: Option<&Self::Funclet>,
instance: Option<Instance<'tcx>>,
) {
let call = self.call(llty, fn_attrs, Some(fn_abi), llfn, args, funclet, instance);

match &fn_abi.ret.mode {
PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(),
PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call),
mode @ PassMode::Cast { .. } => {
bug!("Encountered `PassMode::{mode:?}` during codegen")
}
}

llvm::LLVMRustSetTailCallKind(call, llvm::TailCallKind::MustTail);
}

fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ pub(crate) enum ModuleFlagMergeBehavior {

// Consts for the LLVM CallConv type, pre-cast to usize.

#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
#[allow(dead_code)]
pub(crate) enum TailCallKind {
None = 0,
Tail = 1,
MustTail = 2,
NoTail = 3,
}

/// LLVM CallingConv::ID. Should we wrap this?
///
/// See <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/CallingConv.h>
Expand Down Expand Up @@ -1186,6 +1196,7 @@ unsafe extern "C" {
pub(crate) safe fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool;
pub(crate) safe fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool);
pub(crate) safe fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool);
pub(crate) safe fn LLVMRustSetTailCallKind(CallInst: &Value, Kind: TailCallKind);

// Operations on attributes
pub(crate) fn LLVMCreateStringAttribute(
Expand Down
134 changes: 106 additions & 28 deletions compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};

use rustc_abi::Endian;
use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_hashes::Hash128;
use rustc_session::Session;
Expand Down Expand Up @@ -214,7 +214,7 @@ pub(super) fn create_raw_dylib_elf_stub_shared_objects<'a>(
/// It exports all the provided symbols, but is otherwise empty.
fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]) -> Vec<u8> {
use object::write::elf as write;
use object::{Architecture, elf};
use object::{AddressSize, Architecture, elf};

let mut stub_buf = Vec::new();

Expand All @@ -226,54 +226,94 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
// It is important that the order of reservation matches the order of writing.
// The object crate contains many debug asserts that fire if you get this wrong.

let Some((arch, sub_arch)) = sess.target.object_architecture(&sess.unstable_target_features)
else {
sess.dcx().fatal(format!(
"raw-dylib is not supported for the architecture `{}`",
sess.target.arch
));
};

let endianness = match sess.target.options.endian {
Endian::Little => object::Endianness::Little,
Endian::Big => object::Endianness::Big,
};
let mut stub = write::Writer::new(endianness, true, &mut stub_buf);

let is_64 = match arch.address_size() {
Some(AddressSize::U8 | AddressSize::U16 | AddressSize::U32) => false,
Some(AddressSize::U64) => true,
_ => sess.dcx().fatal(format!(
"raw-dylib is not supported for the architecture `{}`",
sess.target.arch
)),
};

let mut stub = write::Writer::new(endianness, is_64, &mut stub_buf);

let mut vers = Vec::new();
let mut vers_map = FxHashMap::default();
let mut syms = Vec::new();

for symbol in symbols {
let symbol_name = symbol.name.as_str();
if let Some((name, version_name)) = symbol_name.split_once('@') {
assert!(!version_name.contains('@'));
let dynstr = stub.add_dynamic_string(name.as_bytes());
let ver = if let Some(&ver_id) = vers_map.get(version_name) {
ver_id
} else {
let id = vers.len();
vers_map.insert(version_name, id);
let dynstr = stub.add_dynamic_string(version_name.as_bytes());
vers.push((version_name, dynstr));
id
};
syms.push((name, dynstr, Some(ver)));
} else {
let dynstr = stub.add_dynamic_string(symbol_name.as_bytes());
syms.push((symbol_name, dynstr, None));
}
}

let soname = stub.add_dynamic_string(soname.as_bytes());

// These initial reservations don't reserve any bytes in the binary yet,
// they just allocate in the internal data structures.

// First, we crate the dynamic symbol table. It starts with a null symbol
// First, we create the dynamic symbol table. It starts with a null symbol
// and then all the symbols and their dynamic strings.
stub.reserve_null_dynamic_symbol_index();

let dynstrs = symbols
.iter()
.map(|sym| {
stub.reserve_dynamic_symbol_index();
(sym, stub.add_dynamic_string(sym.name.as_str().as_bytes()))
})
.collect::<Vec<_>>();

let soname = stub.add_dynamic_string(soname.as_bytes());
for _ in syms.iter() {
stub.reserve_dynamic_symbol_index();
}

// Reserve the sections.
// We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to.
stub.reserve_shstrtab_section_index();
let text_section_name = stub.add_section_name(".text".as_bytes());
let text_section = stub.reserve_section_index();
stub.reserve_dynstr_section_index();
stub.reserve_dynsym_section_index();
stub.reserve_dynstr_section_index();
if !vers.is_empty() {
stub.reserve_gnu_versym_section_index();
stub.reserve_gnu_verdef_section_index();
}
stub.reserve_dynamic_section_index();

// These reservations now determine the actual layout order of the object file.
stub.reserve_file_header();
stub.reserve_shstrtab();
stub.reserve_section_headers();
stub.reserve_dynstr();
stub.reserve_dynsym();
stub.reserve_dynstr();
if !vers.is_empty() {
stub.reserve_gnu_versym();
stub.reserve_gnu_verdef(1 + vers.len(), 1 + vers.len());
}
stub.reserve_dynamic(2); // DT_SONAME, DT_NULL

// First write the ELF header with the arch information.
let Some((arch, sub_arch)) = sess.target.object_architecture(&sess.unstable_target_features)
else {
sess.dcx().fatal(format!(
"raw-dylib is not supported for the architecture `{}`",
sess.target.arch
));
};
let e_machine = match (arch, sub_arch) {
(Architecture::Aarch64, None) => elf::EM_AARCH64,
(Architecture::Aarch64_Ilp32, None) => elf::EM_AARCH64,
Expand Down Expand Up @@ -342,18 +382,19 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
sh_addralign: 1,
sh_entsize: 0,
});
stub.write_dynstr_section_header(0);
stub.write_dynsym_section_header(0, 1);
stub.write_dynstr_section_header(0);
if !vers.is_empty() {
stub.write_gnu_versym_section_header(0);
stub.write_gnu_verdef_section_header(0);
}
stub.write_dynamic_section_header(0);

// .dynstr
stub.write_dynstr();

// .dynsym
stub.write_null_dynamic_symbol();
for (_, name) in dynstrs {
for (_name, dynstr, _ver) in syms.iter().copied() {
stub.write_dynamic_symbol(&write::Sym {
name: Some(name),
name: Some(dynstr),
st_info: (elf::STB_GLOBAL << 4) | elf::STT_NOTYPE,
st_other: elf::STV_DEFAULT,
section: Some(text_section),
Expand All @@ -363,10 +404,47 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
});
}

// .dynstr
stub.write_dynstr();

// ld.bfd is unhappy if these sections exist without any symbols, so we only generate them when necessary.
if !vers.is_empty() {
// .gnu_version
stub.write_null_gnu_versym();
for (_name, _dynstr, ver) in syms.iter().copied() {
stub.write_gnu_versym(if let Some(ver) = ver {
assert!((2 + ver as u16) < elf::VERSYM_HIDDEN);
elf::VERSYM_HIDDEN | (2 + ver as u16)
} else {
1
});
}

// .gnu_version_d
stub.write_align_gnu_verdef();
stub.write_gnu_verdef(&write::Verdef {
version: elf::VER_DEF_CURRENT,
flags: elf::VER_FLG_BASE,
index: 1,
aux_count: 1,
name: soname,
});
for (ver, (_name, dynstr)) in vers.into_iter().enumerate() {
stub.write_gnu_verdef(&write::Verdef {
version: elf::VER_DEF_CURRENT,
flags: 0,
index: 2 + ver as u16,
aux_count: 1,
name: dynstr,
});
}
}

// .dynamic
// the DT_SONAME will be used by the linker to populate DT_NEEDED
// which the loader uses to find the library.
// DT_NULL terminates the .dynamic table.
stub.write_align_dynamic();
stub.write_dynamic_string(elf::DT_SONAME, soname);
stub.write_dynamic(elf::DT_NULL, 0);

Expand Down
Loading
Loading