Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d780821
Ensure inferred let pattern types are well-formed
s7tya May 27, 2026
b573841
Use a placeholder self type for escaping dyn principals in WF
Dnreikronos Jun 2, 2026
0676d4a
Add regression tests for WF-checking dyn in HRTB bounds
Dnreikronos Jun 2, 2026
de37dfd
Add or_try_* variants for HashMap Entry API
peterjoel Feb 6, 2024
92175ed
platform support: add SNaN erratum to MIPS targets
RalfJung Jun 2, 2026
51001cf
Make the retained dep graph deterministic under the parallel frontend
xmakro Jun 3, 2026
d00722c
Re-enable dep-graph ui tests under the parallel frontend
xmakro Jun 3, 2026
c1cd236
Attribute post-monomorphization error notes by emitting thread
xmakro Jun 5, 2026
2e128c7
Re-enable parallel frontend tests for post-monomorphization errors
xmakro Jun 5, 2026
3669c24
Allow escaping self types in ExistentialTraitRef::with_self_ty
Dnreikronos Jun 9, 2026
e069f47
Add a regression test
oli-obk Jun 8, 2026
947a5b6
Mark `trait_info_of` as comptime and adjust the compiler to handle it
oli-obk Jun 8, 2026
b3c6e82
Mark more reflection things as comptime
oli-obk Jun 8, 2026
d3201bd
Autogenerate unstable compiler flag stubs for unstable-book
kohsine Jun 8, 2026
5bc21b1
Fix parser error recovery for 'dyn' in Rust 2015
i-like-ICEs Jun 9, 2026
c010b25
Implement or_try_* methods on BTreeMap Entry API
asder8215 Jun 3, 2026
8ee1dfa
Move symbol hiding code to a new file
cezarbbb Jun 10, 2026
2a5673f
Rename `rustc_expand/src/errors.rs` into `rustc_expand/src/diagnostic…
GuillaumeGomez Jun 9, 2026
96eb195
Rename `rustc_metadata/src/errors.rs` into `rustc_metadata/src/diagno…
GuillaumeGomez Jun 9, 2026
00ac562
Rename `rustc_mir_build/src/errors.rs` into `rustc_mir_build/src/diag…
GuillaumeGomez Jun 10, 2026
b679cbd
Rename `rustc_mir_dataflow/src/errors.rs` into `rustc_mir_dataflow/sr…
GuillaumeGomez Jun 10, 2026
6708111
Emit error for unused target expression in glob and list delegations
aerooneqq Jun 10, 2026
6a0f2d4
Fix doc link to Instant sub in saturating caveat
orlp Jun 10, 2026
20c1e3f
Rollup merge of #157280 - Dnreikronos:existential_trait_ref_escaping_…
JonathanBrouwer Jun 10, 2026
b09fa35
Rollup merge of #157282 - xmakro:fix/parallel-pme-note, r=petrochenkov
JonathanBrouwer Jun 10, 2026
5283dad
Rollup merge of #157352 - xmakro:fix/parallel-dep-graph-determinism, …
JonathanBrouwer Jun 10, 2026
5c8f182
Rollup merge of #157601 - aerooneqq:delegation-glob-useless-target-ex…
JonathanBrouwer Jun 10, 2026
4373202
Rollup merge of #157626 - kohsine:autogen-flag-stubs, r=clubby789
JonathanBrouwer Jun 10, 2026
bfef926
Rollup merge of #157647 - oli-obk:start-using-comptime, r=fee1-dead
JonathanBrouwer Jun 10, 2026
7570cff
Rollup merge of #157013 - s7tya:fix-let-pat-inferred-wf, r=lcnr
JonathanBrouwer Jun 10, 2026
47c2278
Rollup merge of #157288 - RalfJung:mips-snan, r=ehuss,chenx97,Cyanoxygen
JonathanBrouwer Jun 10, 2026
0c0e37d
Rollup merge of #157355 - asder8215:entry_try, r=jhpratt
JonathanBrouwer Jun 10, 2026
bb6c37a
Rollup merge of #157577 - i-like-ICEs:fix-dyn-2015-parser, r=fmease
JonathanBrouwer Jun 10, 2026
470afdb
Rollup merge of #157670 - GuillaumeGomez:rename-err-to-diag, r=Jonath…
JonathanBrouwer Jun 10, 2026
ed57588
Rollup merge of #157691 - cezarbbb:staticlib-move-symbol-edit, r=petr…
JonathanBrouwer Jun 10, 2026
2d92477
Rollup merge of #157700 - GuillaumeGomez:rename-err-to-diag-2, r=Jona…
JonathanBrouwer Jun 10, 2026
7ee75f1
Rollup merge of #157703 - orlp:fix-instant-comment, r=SimonSapin
JonathanBrouwer Jun 10, 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
8 changes: 5 additions & 3 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ use rustc_data_structures::tagged_ptr::Tag;
use rustc_macros::{Decodable, Encodable, StableHash, Walkable};
pub use rustc_span::AttrId;
use rustc_span::{
ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Spanned, Symbol, kw, respan, sym,
ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, LocalExpnId, Span, Spanned, Symbol, kw, respan,
sym,
};
use thin_vec::{ThinVec, thin_vec};

Expand Down Expand Up @@ -3906,10 +3907,10 @@ pub struct EiiImpl {
pub is_default: bool,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable, PartialEq, Eq)]
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq)]
pub enum DelegationSource {
Single,
List,
List(LocalExpnId),
Glob,
}

Expand All @@ -3923,6 +3924,7 @@ pub struct Delegation {
pub rename: Option<Ident>,
pub body: Option<Box<Block>>,
/// The item was expanded from a glob delegation item.
#[visitable(ignore)]
pub source: DelegationSource,
}

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,6 @@ macro_rules! common_visitor_and_walkers {
Delegation,
DelegationMac,
DelegationSuffixes,
DelegationSource,
DelimArgs,
DelimSpan,
EnumDef,
Expand Down
38 changes: 29 additions & 9 deletions compiler/rustc_ast_lowering/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ use crate::diagnostics::{
};
use crate::{
AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
ResolverAstLoweringExt, index_crate,
index_crate,
};

mod generics;
Expand Down Expand Up @@ -126,7 +126,7 @@ pub(crate) fn delegations_resolutions(
let delegation = ast_index[def_id].delegation().expect("processing delegations");
let span = delegation.last_segment_span();

if let Some(info) = resolver.delegation_info(def_id) {
if let Some(info) = tcx.resolutions(()).delegation_infos.get(&def_id) {
let res = info.resolution_id.map(|id| check_for_cycles(tcx, id, span).map(|_| id));
result.insert(def_id, res.flatten());
} else {
Expand All @@ -143,16 +143,14 @@ pub(crate) fn delegations_resolutions(
fn check_for_cycles(tcx: TyCtxt<'_>, mut def_id: DefId, span: Span) -> Result<(), ErrorGuaranteed> {
let mut visited: FxHashSet<DefId> = Default::default();

let (resolver, _) = &*tcx.hir_crate(()).delayed_resolver.borrow();

loop {
visited.insert(def_id);

// If def_id is in local crate and it corresponds to another delegation
// it means that we refer to another delegation as a callee, so in order to obtain
// a signature DefId we obtain NodeId of the callee delegation and try to get signature from it.
if let Some(local_id) = def_id.as_local()
&& let Some(info) = resolver.delegation_info(local_id)
&& let Some(info) = tcx.resolutions(()).delegation_infos.get(&local_id)
&& let Ok(id) = info.resolution_id
{
def_id = id;
Expand Down Expand Up @@ -209,17 +207,19 @@ impl<'hir> LoweringContext<'_, 'hir> {

let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method);

let (body_id, call_expr_id) =
let (body_id, call_expr_id, unused_target_expr) =
self.lower_delegation_body(delegation, sig_id, param_count, &mut generics, span);

let decl = self.lower_delegation_decl(
delegation.source,
sig_id,
param_count,
c_variadic,
span,
&generics,
delegation.id,
call_expr_id,
unused_target_expr,
);

let sig = self.lower_delegation_sig(sig_id, decl, span);
Expand Down Expand Up @@ -375,13 +375,15 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_delegation_decl(
&mut self,
source: DelegationSource,
sig_id: DefId,
param_count: usize,
c_variadic: bool,
span: Span,
generics: &GenericsGenerationResults<'hir>,
call_path_node_id: NodeId,
call_expr_id: HirId,
unused_target_expr: bool,
) -> &'hir hir::FnDecl<'hir> {
// The last parameter in C variadic functions is skipped in the signature,
// like during regular lowering.
Expand All @@ -406,6 +408,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
parent_args_segment_id: generics.parent.args_segment_id,
self_ty_id: generics.self_ty_id,
propagate_self_ty: generics.propagate_self_ty,
group_id: {
let id = match source {
DelegationSource::Single => None,
DelegationSource::List(expn_id) => Some(expn_id),
DelegationSource::Glob => {
Some(self.tcx.expn_that_defined(self.owner.def_id).expect_local())
}
};

id.map(|id| (id, unused_target_expr))
},
})),
)),
span,
Expand Down Expand Up @@ -504,16 +517,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
param_count: usize,
generics: &mut GenericsGenerationResults<'hir>,
span: Span,
) -> (BodyId, HirId) {
) -> (BodyId, HirId, bool) {
let block = delegation.body.as_deref();
let mut call_expr_id = HirId::INVALID;
let mut unused_target_expr = false;

let block_id = self.lower_body(|this| {
let mut parameters: Vec<hir::Param<'_>> = Vec::with_capacity(param_count);
let mut args: Vec<hir::Expr<'_>> = Vec::with_capacity(param_count);
let mut stmts: &[hir::Stmt<'hir>] = &[];

let is_method = this.is_method(sig_id, span);
let should_generate_block = this.should_generate_block(delegation, sig_id, is_method);

// Consider non-specified target expression as generated,
// as we do not want to emit error when target expression is
// not specified.
unused_target_expr = block.is_some() && (param_count == 0 || !should_generate_block);

for idx in 0..param_count {
let (param, pat_node_id) = this.generate_param(is_method, idx, span);
Expand All @@ -524,7 +544,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

let arg = if let Some(block) = block
&& idx == 0
&& this.should_generate_block(delegation, sig_id, is_method)
&& should_generate_block
{
let mut self_resolver = SelfResolver {
ctxt: this,
Expand Down Expand Up @@ -565,7 +585,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

debug_assert_ne!(call_expr_id, HirId::INVALID);

(block_id, call_expr_id)
(block_id, call_expr_id, unused_target_expr)
}

fn finalize_body_lowering(
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use rustc_macros::extension;
use rustc_middle::hir::{self as mid_hir};
use rustc_middle::queries::Providers;
use rustc_middle::span_bug;
use rustc_middle::ty::{DelegationInfo, PerOwnerResolverData, ResolverAstLowering, TyCtxt};
use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt};
use rustc_session::errors::add_feature_diagnostics;
use rustc_span::symbol::{Ident, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
Expand Down Expand Up @@ -307,10 +307,6 @@ impl<'tcx> ResolverAstLowering<'tcx> {
self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..])
}

fn delegation_info(&self, id: LocalDefId) -> Option<&DelegationInfo> {
self.delegation_infos.get(&id)
}

fn owner_def_id(&self, id: NodeId) -> LocalDefId {
self.owners[&id].def_id
}
Expand Down
157 changes: 3 additions & 154 deletions compiler/rustc_codegen_ssa/src/back/archive.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
use std::env;
use std::error::Error;
use std::ffi::OsString;
use std::fs::{self, File};
use std::io::{self, BufWriter, Write};
use std::path::{Path, PathBuf};
use std::{env, mem};

use ar_archive_writer::{
ArchiveKind, COFFShortExport, MachineTypes, NewArchiveMember, write_archive_to_stream,
};
pub use ar_archive_writer::{DEFAULT_OBJECT_READER, ObjectReader};
use object::read::archive::{ArchiveFile, ArchiveKind as ObjectArchiveKind};
use object::read::elf::Sym as _;
use object::read::macho::{FatArch, Nlist};
use object::{Endianness, elf, macho};
use object::read::macho::FatArch;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_data_structures::memmap::Mmap;
use rustc_fs_util::TempDirBuilder;
Expand All @@ -24,6 +22,7 @@ use tracing::trace;

use super::metadata::{create_compressed_metadata_file, search_for_section};
use super::rmeta_link;
use super::symbol_edit::apply_hide;
use crate::common;
// Public for ArchiveBuilderBuilder::extract_bundled_libs
pub use crate::errors::ExtractBundledLibsError;
Expand Down Expand Up @@ -671,153 +670,3 @@ impl<'a> ArArchiveBuilder<'a> {
fn io_error_context(context: &str, err: io::Error) -> io::Error {
io::Error::new(io::ErrorKind::Other, format!("{context}: {err}"))
}

// We use the `object` crate for the read-only pass over ELF/Mach-O object files
// because its `Sym`/`Nlist` traits provide clean access to symbol properties without
// manual byte parsing. However, `object` does not expose mutable views into the data,
// so we cannot use it to modify symbol fields in place. Instead, the read-only pass
// collects byte-level patches (offset + new value), and the write pass
// (`apply_patches`) applies them to a copy of the byte buffer without any ELF/Mach-O
// parsing — similar to how linker relocations work.

/// A byte-level patch collected in the read-only pass and applied in the write pass.
struct Patch {
offset: usize,
value: u8,
}

/// Apply a list of byte patches to `data`, returning the (possibly modified) bytes.
fn apply_patches(data: &[u8], patches: &[Patch]) -> Vec<u8> {
let mut buf = data.to_vec();
for p in patches {
buf[p.offset] = p.value;
}
buf
}

// ---------------------------------------------------------------------------
// ELF hide – read-only pass uses `object` crate, write pass uses `Patch` list
// ---------------------------------------------------------------------------

fn elf_hide_patches_impl<'data, Elf: object::read::elf::FileHeader<Endian = Endianness>>(
data: &'data [u8],
st_other_offset: usize,
exported: &FxHashSet<String>,
) -> Option<Vec<Patch>>
where
u64: From<Elf::Word>,
{
let header = Elf::parse(data).ok()?;
let endian = header.endian().ok()?;
let sections = header.sections(endian, data).ok()?;
let symtab = sections.symbols(endian, data, elf::SHT_SYMTAB).ok()?;

let data_ptr = data.as_ptr() as usize;
let strings = symtab.strings();
let mut patches = Vec::new();

for sym in symtab.iter() {
let binding = sym.st_bind();
if binding != elf::STB_GLOBAL && binding != elf::STB_WEAK {
continue;
}
if sym.is_undefined(endian) {
continue;
}
let Ok(name_bytes) = sym.name(endian, strings) else { continue };
let Ok(name) = str::from_utf8(name_bytes) else { continue };
if !exported.contains(name) {
let sym_addr = sym as *const Elf::Sym as usize;
let offset = sym_addr - data_ptr + st_other_offset;
let new_vis = (sym.st_other() & !0x03) | elf::STV_HIDDEN;
patches.push(Patch { offset, value: new_vis });
}
}

Some(patches)
}

// ---------------------------------------------------------------------------
// Mach-O hide – same architecture: read-only pass via `object`, write via patches
// ---------------------------------------------------------------------------

fn macho_hide_patches_impl<'data, Mach: object::read::macho::MachHeader<Endian = Endianness>>(
data: &'data [u8],
n_type_offset: usize,
exported: &FxHashSet<String>,
) -> Option<Vec<Patch>> {
let header = Mach::parse(data, 0).ok()?;
let endian = header.endian().ok()?;
let mut commands = header.load_commands(endian, data, 0).ok()?;

let symtab_cmd = loop {
let cmd = commands.next().ok()??;
if let Some(st) = cmd.symtab().ok().flatten() {
break st;
}
};
let symtab: object::read::macho::SymbolTable<'_, Mach, &_> =
symtab_cmd.symbols(endian, data).ok()?;

let data_ptr = data.as_ptr() as usize;
let strings = symtab.strings();
let mut patches = Vec::new();

for nlist in symtab.iter() {
if nlist.is_stab() {
continue;
}
if nlist.is_undefined() {
continue;
}
if nlist.n_type() & macho::N_EXT == 0 {
continue;
}
let Ok(name_bytes) = nlist.name(endian, strings) else { continue };
let Ok(name) = str::from_utf8(name_bytes) else { continue };
let name = name.strip_prefix('_').unwrap_or(name);
if !exported.contains(name) {
let nlist_addr = nlist as *const Mach::Nlist as usize;
let offset = nlist_addr - data_ptr + n_type_offset;
patches.push(Patch { offset, value: nlist.n_type() | macho::N_PEXT });
}
}

Some(patches)
}

// ---------------------------------------------------------------------------
// Unified dispatch: top-level detection via `object::File::parse`
// ---------------------------------------------------------------------------

fn hide_patches(data: &[u8], exported: &FxHashSet<String>) -> Option<Vec<Patch>> {
let file = object::File::parse(data).ok()?;
match file {
object::File::Elf64(_) => elf_hide_patches_impl::<elf::FileHeader64<Endianness>>(
data,
mem::offset_of!(elf::Sym64<Endianness>, st_other),
exported,
),
object::File::Elf32(_) => elf_hide_patches_impl::<elf::FileHeader32<Endianness>>(
data,
mem::offset_of!(elf::Sym32<Endianness>, st_other),
exported,
),
object::File::MachO64(_) => macho_hide_patches_impl::<macho::MachHeader64<Endianness>>(
data,
mem::offset_of!(macho::Nlist64<Endianness>, n_type),
exported,
),
object::File::MachO32(_) => macho_hide_patches_impl::<macho::MachHeader32<Endianness>>(
data,
mem::offset_of!(macho::Nlist32<Endianness>, n_type),
exported,
),
_ => None,
}
}

fn apply_hide(data: &[u8], exported: &FxHashSet<String>) -> Vec<u8> {
let patches = hide_patches(data, exported).unwrap_or_default();
apply_patches(data, &patches)
}
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/back/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod lto;
pub mod metadata;
pub mod rmeta_link;
pub(crate) mod rpath;
mod symbol_edit;
pub mod symbol_export;
pub mod write;

Expand Down
Loading
Loading