Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ffe1dba
Fix unused_parens for pinned reference patterns
P8L1 May 17, 2026
9849fa8
Adress concerns
P8L1 May 31, 2026
3c6c901
move batch
zedddie Jun 1, 2026
01f5cc8
bless batch
zedddie Jun 1, 2026
7ec390a
remove unnecessary roundtrips through kind_from_def_id
khyperia May 29, 2026
09bb5bb
remove AliasTerm::kind() method
khyperia Jun 2, 2026
7092ebf
Integrate `field_names` inside `field_tys`.
cjgillot May 24, 2026
c8ce74a
Simplify `compute_layout`.
cjgillot Jun 2, 2026
2a2e4c9
Split coroutine layout computation to its own file.
cjgillot May 31, 2026
62690a6
Move coroutine.rs to be a mod.rs
cjgillot May 31, 2026
e3468ae
Promotes 5 Thumb-mode bare-metal Arm targets to Tier 2
cezarbbb Jun 2, 2026
ac63a3e
Pacify doc-checker.
cjgillot Jun 2, 2026
0e1bd7c
rustc_codegen_ssa: Refactor `ArchiveEntry` to include entry kind
petrochenkov Jun 1, 2026
d39ecc0
rustc_codegen_ssa: check whether `add_archive` argument is a rlib
petrochenkov Jun 2, 2026
9b7623a
Remove -Zemscripten-wasm-eh
bjorn3 May 25, 2026
3a850de
bootstrap: enable `clippy::mem_replace_with_default`
JarlEvanson Jun 2, 2026
3dacac8
compiler: fix `clippy::mem_replace_with_default` warnings
JarlEvanson Jun 2, 2026
c2b9f39
windows: remove division-by-zero checks for performance counters
mathisbot Jun 2, 2026
fba4788
Add more tests for the `optimize` attribute
veluca93 Jun 2, 2026
c611d64
Fix some wf module argument/doc comment name mismatches
fallible-algebra Jun 3, 2026
42d5c96
Rewrite target checking for `#[sanitize]`
JonathanBrouwer Jun 2, 2026
dd28618
Add `attr-on-mac-call` test
JonathanBrouwer Jun 3, 2026
b0ccb01
Add "functions with a body" target group
JonathanBrouwer Jun 3, 2026
9bc4e33
Rewrite target checking of `rustc_dummy`
JonathanBrouwer Jun 2, 2026
a10c598
Emit error when there is an infer lifetime in user-specified args in …
aerooneqq Jun 3, 2026
28cfce7
Move out statements out of delegation's callee first arg
aerooneqq Jun 3, 2026
33165e8
Rollup merge of #155763 - cezarbbb:promote-thumb-to-tier2, r=petroche…
JonathanBrouwer Jun 3, 2026
03e3b67
Rollup merge of #156953 - aerooneqq:delegation-emit-err-when-incorrec…
JonathanBrouwer Jun 3, 2026
417ae70
Rollup merge of #157248 - aerooneqq:delegation-statements-out-of-firs…
JonathanBrouwer Jun 3, 2026
edf929c
Rollup merge of #157263 - petrochenkov:arentry, r=bjorn3
JonathanBrouwer Jun 3, 2026
d190e9b
Rollup merge of #156089 - P8L1:fix-unused-parens-pinned-patterns, r=K…
JonathanBrouwer Jun 3, 2026
90a46a6
Rollup merge of #156928 - bjorn3:emscripten_always_wasm_eh, r=TaKO8Ki
JonathanBrouwer Jun 3, 2026
912e77a
Rollup merge of #157236 - zedddie:gsoc-batch-3-meow, r=Kivooeo
JonathanBrouwer Jun 3, 2026
e68c830
Rollup merge of #157287 - khyperia:const-generics-nits, r=BoxyUwU
JonathanBrouwer Jun 3, 2026
1f9f94d
Rollup merge of #157294 - cjgillot:split-coroutine-layout, r=oli-obk
JonathanBrouwer Jun 3, 2026
7dc56f3
Rollup merge of #157297 - veluca93:more-optimize-tests, r=jieyouxu
JonathanBrouwer Jun 3, 2026
1f9741a
Rollup merge of #157328 - mathisbot:opt-std-windows-time, r=ChrisDenton
JonathanBrouwer Jun 3, 2026
608cba9
Rollup merge of #157332 - JonathanBrouwer:target-sanitize, r=mejrs
JonathanBrouwer Jun 3, 2026
3a32179
Rollup merge of #157336 - JarlEvanson:mem-replace-with-default, r=Jon…
JonathanBrouwer Jun 3, 2026
28f4500
Rollup merge of #157362 - fallible-algebra:typos/arg-in-wf, r=petroch…
JonathanBrouwer Jun 3, 2026
a72cf41
Rollup merge of #157364 - JonathanBrouwer:target-dummy, r=mejrs
JonathanBrouwer Jun 3, 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
44 changes: 25 additions & 19 deletions compiler/rustc_ast_lowering/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
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>] = &[];

for idx in 0..param_count {
let (param, pat_node_id) = this.generate_param(is_method, idx, span);
parameters.push(param);

let generate_arg =
|this: &mut Self| this.generate_arg(is_method, idx, param.pat.hir_id, span);

let arg = if let Some(block) = block
&& idx == 0
{
Expand All @@ -424,10 +428,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
self_resolver.visit_block(block);
// Target expr needs to lower `self` path.
this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id);
this.lower_target_expr(&block)

// Lower with `HirId::INVALID` as we will use only expr and stmts.
// FIXME(fn_delegation): Alternatives for target expression lowering:
// https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2197170600.
let block = this.lower_block_noalloc(HirId::INVALID, block, false);

stmts = block.stmts;

// The behavior of the delegation's target expression differs from the
// behavior of the usual block, where if there is no final expression
// the `()` is returned. In case of the similar situation in delegation
// (no final expression) we propagate first argument instead of replacing
// it with `()`.
if let Some(&expr) = block.expr { expr } else { generate_arg(this) }
} else {
this.generate_arg(is_method, idx, param.pat.hir_id, span)
generate_arg(this)
};

args.push(arg);
}

Expand All @@ -439,11 +457,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
if param_count == 0
&& let Some(block) = block
{
args.push(this.lower_target_expr(&block));
args.push(this.lower_block_expr(&block));
}

let (final_expr, hir_id) =
this.finalize_body_lowering(delegation, args, generics, span);
this.finalize_body_lowering(delegation, stmts, args, generics, span);

call_expr_id = hir_id;

Expand All @@ -455,22 +473,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
(block_id, call_expr_id)
}

// FIXME(fn_delegation): Alternatives for target expression lowering:
// https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2197170600.
fn lower_target_expr(&mut self, block: &Block) -> hir::Expr<'hir> {
if let [stmt] = block.stmts.as_slice()
&& let StmtKind::Expr(expr) = &stmt.kind
{
return self.lower_expr_mut(expr);
}

let block = self.lower_block(block, false);
self.mk_expr(hir::ExprKind::Block(block, None), block.span)
}

fn finalize_body_lowering(
&mut self,
delegation: &Delegation,
stmts: &'hir [hir::Stmt<'hir>],
args: Vec<hir::Expr<'hir>>,
generics: &mut GenericsGenerationResults<'hir>,
span: Span,
Expand Down Expand Up @@ -522,7 +528,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let call = self.arena.alloc(self.mk_expr(hir::ExprKind::Call(callee_path, args), span));

let block = self.arena.alloc(hir::Block {
stmts: &[],
stmts,
expr: Some(call),
hir_id: self.next_id(),
rules: hir::BlockCheckMode::DefaultBlock,
Expand Down Expand Up @@ -587,7 +593,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

let callee_path = this.arena.alloc(this.mk_expr(hir::ExprKind::Path(path), span));
let args = if let Some(block) = delegation.body.as_ref() {
this.arena.alloc_slice(&[this.lower_target_expr(block)])
this.arena.alloc_slice(&[this.lower_block_expr(block)])
} else {
&mut []
};
Expand Down
27 changes: 25 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::attributes::AttributeSafety;
use crate::session_diagnostics::{
EmptyExportName, NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass,
NullOnObjcSelector, ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral,
SanitizeInvalidStatic,
};
use crate::target_checking::Policy::AllowSilent;

Expand Down Expand Up @@ -566,8 +567,18 @@ pub(crate) struct SanitizeParser;

impl SingleAttributeParser for SanitizeParser {
const PATH: &[Symbol] = &[sym::sanitize];
// FIXME: still checked in check_attrs.rs
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Closure),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Impl { of_trait: false }),
Allow(Target::Impl { of_trait: true }),
Allow(Target::Mod),
Allow(Target::Crate),
Allow(Target::Static),
]);
const TEMPLATE: AttributeTemplate = template!(List: &[
r#"address = "on|off""#,
r#"kernel_address = "on|off""#,
Expand Down Expand Up @@ -668,6 +679,18 @@ impl SingleAttributeParser for SanitizeParser {
}
}

// The sanitizer attribute is only allowed on statics, if only address bits are set
let all_set_except_address =
(on_set | off_set) & !(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS);
if cx.target == Target::Static
&& let Some(set) = all_set_except_address.iter().next()
{
cx.emit_err(SanitizeInvalidStatic {
span: cx.attr_span,
field: set.as_str().expect("Since this `SanitizerSet` is returned from an iterator, exactly one field is set")
});
}

Some(AttributeKind::Sanitize { on_set, off_set, rtsan, span: cx.attr_span })
}
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_attr_parsing/src/attributes/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@ use rustc_span::{Symbol, sym};
use crate::attributes::{OnDuplicate, SingleAttributeParser};
use crate::context::AcceptContext;
use crate::parser::ArgParser;
use crate::target_checking::{ALL_TARGETS, AllowedTargets};
use crate::target_checking::AllowedTargets;
use crate::unstable;

pub(crate) struct RustcDummyParser;
impl SingleAttributeParser for RustcDummyParser {
const PATH: &[Symbol] = &[sym::rustc_dummy];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::ManuallyChecked;
const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really
const STABILITY: AttributeStability =
unstable!(rustc_attrs, "the `#[rustc_dummy]` attribute is used for rustc unit tests");

fn convert(_: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
args.ignore_args();
cx.ignore_target_checks();
Some(AttributeKind::RustcDummy)
}
}
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 @@ -1023,3 +1023,12 @@ pub(crate) enum InvalidMachoSectionReason {
#[note("section name `{$section}` is longer than 16 bytes")]
SectionTooLong { section: String },
}

#[derive(Diagnostic)]
#[diag("`#[sanitize({$field} = ...)]` attribute cannot be used on statics")]
#[help("`#[sanitize]` can be used on statics if only the address is sanitized")]
pub(crate) struct SanitizeInvalidStatic {
#[primary_span]
pub span: Span,
pub field: &'static str,
}
20 changes: 19 additions & 1 deletion compiler/rustc_attr_parsing/src/target_checking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,13 @@ pub(crate) fn allowed_targets_applied(
Target::Method(MethodKind::Trait { body: true }),
Target::Method(MethodKind::TraitImpl),
];
const FUNCTION_WITH_BODY_LIKE: &[Target] = &[
Target::Fn,
Target::Closure,
Target::Method(MethodKind::Inherent),
Target::Method(MethodKind::Trait { body: true }),
Target::Method(MethodKind::TraitImpl),
];
const METHOD_LIKE: &[Target] = &[
Target::Method(MethodKind::Inherent),
Target::Method(MethodKind::Trait { body: false }),
Expand All @@ -379,6 +386,13 @@ pub(crate) fn allowed_targets_applied(
target,
&mut added_fake_targets,
);
filter_targets(
&mut allowed_targets,
FUNCTION_WITH_BODY_LIKE,
"functions with a body",
target,
&mut added_fake_targets,
);
filter_targets(&mut allowed_targets, METHOD_LIKE, "methods", target, &mut added_fake_targets);
filter_targets(&mut allowed_targets, IMPL_LIKE, "impl blocks", target, &mut added_fake_targets);
filter_targets(&mut allowed_targets, ADT_LIKE, "data types", target, &mut added_fake_targets);
Expand Down Expand Up @@ -422,11 +436,15 @@ impl<'f, 'sess> AcceptContext<'f, 'sess> {
attribute_args: &'static str,
allowed_targets: &AllowedTargets,
) {
self.ignore_target_checks();
AttributeParser::check_target(allowed_targets, attribute_args, self);
}

pub(crate) fn ignore_target_checks(&mut self) {
#[cfg(debug_assertions)]
{
self.has_target_been_checked = true;
}
AttributeParser::check_target(allowed_targets, attribute_args, self);
}
}

Expand Down
20 changes: 0 additions & 20 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use rustc_session::config::{
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, FunctionReturn, PAuthKey, PacRet,
};
use rustc_span::{DUMMY_SP, Span, Spanned, Symbol, sym};
use rustc_symbol_mangling::mangle_internal_symbol;
use rustc_target::spec::{
Arch, CfgAbi, Env, FramePointer, HasTargetSpec, Os, RelocModel, SmallDataThresholdSupport,
Target, TlsModel,
Expand Down Expand Up @@ -136,7 +135,6 @@ pub(crate) struct FullCx<'ll, 'tcx> {
pub dbg_cx: Option<debuginfo::CodegenUnitDebugContext<'ll, 'tcx>>,

eh_personality: Cell<Option<&'ll Value>>,
eh_catch_typeinfo: Cell<Option<&'ll Value>>,
pub rust_try_fn: Cell<Option<(&'ll Type, &'ll Value)>>,

intrinsics:
Expand Down Expand Up @@ -672,7 +670,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
coverage_cx,
dbg_cx,
eh_personality: Cell::new(None),
eh_catch_typeinfo: Cell::new(None),
rust_try_fn: Cell::new(None),
intrinsics: Default::default(),
local_gen_sym_counter: Cell::new(0),
Expand Down Expand Up @@ -1042,23 +1039,6 @@ impl<'ll> CodegenCx<'ll, '_> {
}
}
}

pub(crate) fn eh_catch_typeinfo(&self) -> &'ll Value {
if let Some(eh_catch_typeinfo) = self.eh_catch_typeinfo.get() {
return eh_catch_typeinfo;
}
let tcx = self.tcx;
assert!(self.sess().target.os == Os::Emscripten);
let eh_catch_typeinfo = match tcx.lang_items().eh_catch_typeinfo() {
Some(def_id) => self.get_static(def_id),
_ => {
let ty = self.type_struct(&[self.type_ptr(), self.type_ptr()], false);
self.declare_global(&mangle_internal_symbol(self.tcx, "rust_eh_catch_typeinfo"), ty)
}
};
self.eh_catch_typeinfo.set(Some(eh_catch_typeinfo));
eh_catch_typeinfo
}
}

impl CodegenCx<'_, '_> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
.map(|field_index| {
let coroutine_saved_local = coroutine_layout.variant_fields[variant_index]
[FieldIdx::from_usize(field_index)];
let field_name_maybe = coroutine_layout.field_names[coroutine_saved_local];
let field_name_maybe =
coroutine_layout.field_tys[coroutine_saved_local].debuginfo_name;
let field_name = field_name_maybe
.as_ref()
.map(|s| Cow::from(s.as_str()))
Expand Down
85 changes: 1 addition & 84 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC;
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
use rustc_target::callconv::PassMode;
use rustc_target::spec::{Arch, Os};
use rustc_target::spec::Arch;
use tracing::debug;

use crate::abi::FnAbiLlvmExt;
Expand Down Expand Up @@ -1356,8 +1356,6 @@ fn catch_unwind_intrinsic<'ll, 'tcx>(
codegen_msvc_try(bx, try_func, data, catch_func)
} else if wants_wasm_eh(bx.sess()) {
codegen_wasm_try(bx, try_func, data, catch_func)
} else if bx.sess().target.os == Os::Emscripten {
codegen_emcc_try(bx, try_func, data, catch_func)
} else {
codegen_gnu_try(bx, try_func, data, catch_func)
}
Expand Down Expand Up @@ -1654,87 +1652,6 @@ fn codegen_gnu_try<'ll, 'tcx>(
ret
}

// Variant of codegen_gnu_try used for emscripten where Rust panics are
// implemented using C++ exceptions. Here we use exceptions of a specific type
// (`struct rust_panic`) to represent Rust panics.
fn codegen_emcc_try<'ll, 'tcx>(
bx: &mut Builder<'_, 'll, 'tcx>,
try_func: &'ll Value,
data: &'ll Value,
catch_func: &'ll Value,
) -> &'ll Value {
let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
// Codegens the shims described above:
//
// bx:
// invoke %try_func(%data) normal %normal unwind %catch
//
// normal:
// ret 0
//
// catch:
// (%ptr, %selector) = landingpad
// %rust_typeid = @llvm.eh.typeid.for(@_ZTI10rust_panic)
// %is_rust_panic = %selector == %rust_typeid
// %catch_data = alloca { i8*, i8 }
// %catch_data[0] = %ptr
// %catch_data[1] = %is_rust_panic
// call %catch_func(%data, %catch_data)
// ret 1
let then = bx.append_sibling_block("then");
let catch = bx.append_sibling_block("catch");

let try_func = llvm::get_param(bx.llfn(), 0);
let data = llvm::get_param(bx.llfn(), 1);
let catch_func = llvm::get_param(bx.llfn(), 2);
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);

bx.switch_to_block(then);
bx.ret(bx.const_bool(false));

// Type indicator for the exception being thrown.
//
// The first value in this tuple is a pointer to the exception object
// being thrown. The second value is a "selector" indicating which of
// the landing pad clauses the exception's type had been matched to.
bx.switch_to_block(catch);
let tydesc = bx.eh_catch_typeinfo();
let lpad_ty = bx.type_struct(&[bx.type_ptr(), bx.type_i32()], false);
let vals = bx.landing_pad(lpad_ty, bx.eh_personality(), 2);
bx.add_clause(vals, tydesc);
bx.add_clause(vals, bx.const_null(bx.type_ptr()));
let ptr = bx.extract_value(vals, 0);
let selector = bx.extract_value(vals, 1);

// Check if the typeid we got is the one for a Rust panic.
let rust_typeid = bx.call_intrinsic("llvm.eh.typeid.for", &[bx.val_ty(tydesc)], &[tydesc]);
let is_rust_panic = bx.icmp(IntPredicate::IntEQ, selector, rust_typeid);
let is_rust_panic = bx.zext(is_rust_panic, bx.type_bool());

// We need to pass two values to catch_func (ptr and is_rust_panic), so
// create an alloca and pass a pointer to that.
let ptr_size = bx.tcx().data_layout.pointer_size();
let ptr_align = bx.tcx().data_layout.pointer_align().abi;
let i8_align = bx.tcx().data_layout.i8_align;
// Required in order for there to be no padding between the fields.
assert!(i8_align <= ptr_align);
let catch_data = bx.alloca(2 * ptr_size, ptr_align);
bx.store(ptr, catch_data, ptr_align);
let catch_data_1 = bx.inbounds_ptradd(catch_data, bx.const_usize(ptr_size.bytes()));
bx.store(is_rust_panic, catch_data_1, i8_align);

let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
bx.call(catch_ty, None, None, catch_func, &[data, catch_data], None, None);
bx.ret(bx.const_bool(true));
});

// Note that no invoke is used here because by definition this function
// can't panic (that's what it's catching).
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
ret
}

// Helper function to give a Block to a closure to codegen a shim function.
// This is currently primarily used for the `try` intrinsic functions above.
fn gen_fn<'a, 'll, 'tcx>(
Expand Down
Loading
Loading