Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6fc3880
hwaddress: automatically add -Ctarget-feature=tagged-globals
Darksonn Apr 1, 2026
221c39a
Add myself as co-maintainer for hexagon-unknown-linux-musl
Apr 3, 2026
690d193
Break a single query cycle in the deadlock handler
Zoxc Mar 14, 2026
f493cab
Add a test for an LLVM crash "Vector elements must have same size"
jakubadamw Apr 9, 2026
12e847f
Add a test for a const evaluator ICE on a self-receiver type mismatch
jakubadamw Apr 9, 2026
fc9f492
Add a codegen test for a missed optimisation with spare niches
jakubadamw Apr 9, 2026
0fbab04
minor follow up to removing soft mode `#[unstable]`
WaffleLapkin Mar 10, 2026
6cd5315
Implement `GenericTypeVisitable` for some types
ChayimFriedman2 Apr 9, 2026
d024e57
Fix if branch in op.rs
malezjaa Apr 9, 2026
dbc08cf
main-termination
xonx4l Jan 19, 2026
b65574d
Add (failing) ui test for denying global_allocator + thread_local
Fayti1703 Apr 9, 2026
95c1a37
Deny global_allocator + thread_local
Fayti1703 Apr 9, 2026
9614f28
Update ui test for deny global_allocator + thread_local
Fayti1703 Apr 9, 2026
dbe7a4e
Improve diagnostic for global_allocator + thread_local
Fayti1703 Apr 9, 2026
b537c45
Apply suggestions from fmt output
Fayti1703 Apr 9, 2026
a2255aa
Set the Fuchsia ABI to the documented minimum
ilovepi Apr 9, 2026
e249b03
Rollup merge of #154973 - Zoxc:cycle-single, r=petrochenkov
jhpratt Apr 10, 2026
6e7e947
Rollup merge of #155034 - ChayimFriedman2:ra-fixes, r=lcnr
jhpratt Apr 10, 2026
d831599
Rollup merge of #151377 - xonx4l:main_termination, r=lcnr
jhpratt Apr 10, 2026
5a6abf3
Rollup merge of #154677 - Darksonn:hwasan-tagged-globals, r=davidtwco
jhpratt Apr 10, 2026
8220818
Rollup merge of #154774 - quic-mliebel:add-maintainer, r=TaKO8Ki
jhpratt Apr 10, 2026
d788fbf
Rollup merge of #155015 - jakubadamw:issues-104037-112623-113899, r=K…
jhpratt Apr 10, 2026
ddf6fae
Rollup merge of #155039 - WaffleLapkin:hard_unstable, r=JonathanBrouwer
jhpratt Apr 10, 2026
5d8f9c8
Rollup merge of #155043 - malezjaa:refactor-typecheck-op, r=adwinwhite
jhpratt Apr 10, 2026
c305a1a
Rollup merge of #155071 - Fayti1703:alloc/no-thread-local, r=Kivooeo
jhpratt Apr 10, 2026
4f606c8
Rollup merge of #155072 - ilovepi:fuchsia-riscv-driver-default, r=jie…
jhpratt Apr 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
10 changes: 10 additions & 0 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,16 @@ pub(crate) struct AllocMustStatics {
pub(crate) span: Span,
}

#[derive(Diagnostic)]
#[diag("allocators cannot be `#[thread_local]`")]
pub(crate) struct AllocCannotThreadLocal {
#[primary_span]
pub(crate) span: Span,
#[label("marked `#[thread_local]` here")]
#[suggestion("remove this attribute", code = "", applicability = "maybe-incorrect")]
pub(crate) attr: Span,
}

pub(crate) use autodiff::*;

mod autodiff {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_builtin_macros/src/global_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ pub(crate) fn expand(
return vec![orig_item];
};

// Forbid `#[thread_local]` attributes on the item
if let Some(attr) = item.attrs.iter().find(|x| x.has_name(sym::thread_local)) {
ecx.dcx().emit_err(errors::AllocCannotThreadLocal { span: item.span, attr: attr.span });
return vec![orig_item];
}

// Generate a bunch of new items using the AllocFnFactory
let span = ecx.with_def_site_ctxt(item.span);
let f = AllocFnFactory { span, ty_span, global: ident, cx: ecx };
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ fn llvm_features_by_flags(sess: &Session, features: &mut Vec<String>) {
}

target_features::retpoline_features_by_flags(sess, features);
target_features::sanitizer_features_by_flags(sess, features);

// -Zfixed-x18
if sess.opts.unstable_opts.fixed_x18 {
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_session::Session;
use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON;
use rustc_session::parse::feature_err;
use rustc_span::{Span, Symbol, edit_distance, sym};
use rustc_target::spec::Arch;
use rustc_target::spec::{Arch, SanitizerSet};
use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability};
use smallvec::SmallVec;

Expand Down Expand Up @@ -460,6 +460,15 @@ pub fn retpoline_features_by_flags(sess: &Session, features: &mut Vec<String>) {
}
}

/// Computes the backend target features to be added to account for sanitizer flags.
pub fn sanitizer_features_by_flags(sess: &Session, features: &mut Vec<String>) {
// It's intentional that this is done only for non-kernel version of hwaddress. This matches
// clang behavior.
if sess.sanitizers().contains(SanitizerSet::HWADDRESS) {
features.push("+tagged-globals".into());
}
}

pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
rust_target_features: |tcx, cnum| {
Expand Down
67 changes: 33 additions & 34 deletions compiler/rustc_hir_analysis/src/check/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, TyCtxt, TypingMode};
use rustc_session::config::EntryFnType;
use rustc_span::Span;
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::regions::InferCtxtRegionExt;
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};

use super::check_function_signature;
use crate::errors;

pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) {
pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
match tcx.entry_fn(()) {
Some((def_id, EntryFnType::Main { .. })) => check_main_fn_ty(tcx, def_id),
_ => {}
_ => Ok(()),
}
}

fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) -> Result<(), ErrorGuaranteed> {
let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity();
let main_span = tcx.def_span(main_def_id);

Expand Down Expand Up @@ -87,33 +88,28 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
}
}

let mut error = false;
let main_diagnostics_def_id = main_fn_diagnostics_def_id(tcx, main_def_id, main_span);

let main_asyncness = tcx.asyncness(main_def_id);
if main_asyncness.is_async() {
let asyncness_span = main_fn_asyncness_span(tcx, main_def_id);
tcx.dcx()
.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span });
error = true;
return Err(tcx
.dcx()
.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span }));
}

if let Some(attr_span) = find_attr!(tcx, main_def_id, TrackCaller(span) => *span) {
tcx.dcx().emit_err(errors::TrackCallerOnMain { span: attr_span, annotated: main_span });
error = true;
return Err(tcx
.dcx()
.emit_err(errors::TrackCallerOnMain { span: attr_span, annotated: main_span }));
}

if !tcx.codegen_fn_attrs(main_def_id).target_features.is_empty()
// Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988
&& !tcx.sess.target.is_like_wasm
&& !tcx.sess.opts.actually_rustdoc
{
tcx.dcx().emit_err(errors::TargetFeatureOnMain { main: main_span });
error = true;
}

if error {
return;
return Err(tcx.dcx().emit_err(errors::TargetFeatureOnMain { main: main_span }));
}

// Main should have no WC, so empty param env is OK here.
Expand All @@ -123,8 +119,9 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
let return_ty = main_fnsig.output();
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
let Some(return_ty) = return_ty.no_bound_vars() else {
tcx.dcx().emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
return;
return Err(tcx
.dcx()
.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span }));
};
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
let cause = traits::ObligationCause::new(
Expand All @@ -137,8 +134,16 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
let errors = ocx.evaluate_obligations_error_on_ambiguity();
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(errors);
error = true;
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
}

let region_errors =
infcx.resolve_regions(main_diagnostics_def_id, param_env, ty::List::empty());

if !region_errors.is_empty() {
return Err(infcx
.err_ctxt()
.report_region_errors(main_diagnostics_def_id, &region_errors));
}
// now we can take the return type of the given main function
expected_return_type = norm_return_ty;
Expand All @@ -147,10 +152,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
expected_return_type = tcx.types.unit;
}

if error {
return;
}

let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig(
[],
expected_return_type,
Expand All @@ -159,7 +160,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
ExternAbi::Rust,
));

if check_function_signature(
check_function_signature(
tcx,
ObligationCause::new(
main_span,
Expand All @@ -168,26 +169,24 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
),
main_def_id,
expected_sig,
)
.is_err()
{
return;
}
)?;

let main_fn_generics = tcx.generics_of(main_def_id);
let main_fn_predicates = tcx.predicates_of(main_def_id);
if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
tcx.dcx().emit_err(errors::MainFunctionGenericParameters {
return Err(tcx.dcx().emit_err(errors::MainFunctionGenericParameters {
span: generics_param_span.unwrap_or(main_span),
label_span: generics_param_span,
});
}));
} else if !main_fn_predicates.predicates.is_empty() {
// generics may bring in implicit predicates, so we skip this check if generics is present.
let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id);
tcx.dcx().emit_err(errors::WhereClauseOnMain {
return Err(tcx.dcx().emit_err(errors::WhereClauseOnMain {
span: generics_where_clauses_span.unwrap_or(main_span),
generics_span: generics_where_clauses_span,
});
}));
}

Ok(())
}
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2372,7 +2372,8 @@ pub(super) fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuarante
}))
.and(items.par_nested_bodies(|item| tcx.ensure_result().check_well_formed(item)))
.and(items.par_opaques(|item| tcx.ensure_result().check_well_formed(item)));
super::entry::check_for_entry_fn(tcx);

super::entry::check_for_entry_fn(tcx)?;

res
}
Expand Down
38 changes: 20 additions & 18 deletions compiler/rustc_hir_typeck/src/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,24 +294,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.apply_adjustments(lhs_expr, vec![autoref]);
}

if let ty::Ref(_, _, mutbl) = method.sig.inputs()[1].kind() {
// Allow two-phase borrows for binops in initial deployment
// since they desugar to methods
let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes);
let autoref = Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
target: method.sig.inputs()[1],
};
// HACK(eddyb) Bypass checks due to reborrows being in
// some cases applied on the RHS, on top of which we need
// to autoref, which is not allowed by apply_adjustments.
// self.apply_adjustments(rhs_expr, vec![autoref]);
self.typeck_results
.borrow_mut()
.adjustments_mut()
.entry(rhs_expr.hir_id)
.or_default()
.push(autoref);
if by_ref_binop {
if let ty::Ref(_, _, mutbl) = method.sig.inputs()[1].kind() {
// Allow two-phase borrows for binops in initial deployment
// since they desugar to methods
let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes);
let autoref = Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
target: method.sig.inputs()[1],
};
// HACK(eddyb) Bypass checks due to reborrows being in
// some cases applied on the RHS, on top of which we need
// to autoref, which is not allowed by apply_adjustments.
// self.apply_adjustments(rhs_expr, vec![autoref]);
self.typeck_results
.borrow_mut()
.adjustments_mut()
.entry(rhs_expr.hir_id)
.or_default()
.push(autoref);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ pub(crate) fn run_in_thread_pool_with_globals<

use rustc_data_structures::defer;
use rustc_middle::ty::tls;
use rustc_query_impl::break_query_cycles;
use rustc_query_impl::break_query_cycle;

let thread_stack_size = init_stack_size(thread_builder_diag);

Expand Down Expand Up @@ -260,7 +260,7 @@ internal compiler error: query cycle handler thread panicked, aborting process";
)
},
);
break_query_cycles(job_map, &registry);
break_query_cycle(job_map, &registry);
})
})
});
Expand Down
Loading
Loading