Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
e7b3b14
Add regression test for mutable closure argument suggestions
chenyukang Sep 21, 2026
a748eae
std: Update `wasip3` crate dependency
alexcrichton Sep 22, 2026
76c850e
document `#[rustc_dyn_incompatible_trait]`
mejrs Sep 22, 2026
9b9cb70
Stop embedding device code, now that the clang-linker-wrapper isn't c…
ZuseZ4 Sep 22, 2026
4f20be3
also drop now unused host.o
ZuseZ4 Sep 22, 2026
87e95d6
Enhance mutable closure suggestions with as_mut() support
chenyukang Sep 21, 2026
e5e0b10
Fix typo in std::sys::process::unix::unsupported::wait_status documen…
bushrat011899 Sep 23, 2026
16e81e9
Fix bignum build on 16-bit targets
amari-ca Sep 23, 2026
039b8bc
Add address_space and byref to abi PassMode::Indirect
Flakebi Sep 1, 2026
b8c747f
Pre-commit amdgpu gpu-kernel ABI test
Flakebi Sep 3, 2026
be988e9
Properly implement the gpu-kernel ABI for amdgpu
Flakebi Sep 15, 2026
289d40d
Rollup merge of #162177 - Flakebi:amdgpu-kernel-cc, r=bjorn3
JonathanBrouwer Sep 23, 2026
3ab4cd0
Rollup merge of #163168 - alexcrichton:update-wasip3, r=JohnTitor
JonathanBrouwer Sep 23, 2026
4d8a37a
Rollup merge of #163179 - ZuseZ4:cleanup-offload, r=bjorn3
JonathanBrouwer Sep 23, 2026
ef07321
Rollup merge of #162497 - mejrs:rustc_dyn_incompatible_trait, r=Shoyu…
JonathanBrouwer Sep 23, 2026
eb43f77
Rollup merge of #163191 - chenyukang:yukang-fix-as-mut-closure-sugges…
JonathanBrouwer Sep 23, 2026
1384163
Rollup merge of #163192 - bushrat011899:typo, r=JohnTitor
JonathanBrouwer Sep 23, 2026
339cbe2
Rollup merge of #163197 - amari-ca:amarica/fix-bignum-on-16-bit, r=tg…
JonathanBrouwer Sep 23, 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
4 changes: 2 additions & 2 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
}

/// If this method returns `true`, then this type should always have a `PassMode` of
/// `Indirect { on_stack: false, .. }` when being used as the argument type of a function with a
/// non-Rustic ABI (this is true for structs annotated with the
/// `Indirect { mode: IndirectMode::Pointer, .. }` when being used as the argument type of a
/// function with a non-Rustic ABI (this is true for structs annotated with the
/// `#[rustc_pass_indirectly_in_non_rustic_abis]` attribute).
///
/// This is used to replicate some of the behaviour of C array-to-pointer decay; however unlike
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1778,6 +1778,10 @@ pub struct AddressSpace(pub u32);
impl AddressSpace {
/// LLVM's `0` address space.
pub const ZERO: Self = AddressSpace(0);
/// The address space for constant memory on nvptx and amdgpu.
/// This address space is used e.g. for kernel arguments that are constant throughout the
/// execution.
pub const GPU_CONSTANT: Self = AddressSpace(4);
/// The address space for workgroup memory on nvptx and amdgpu.
/// See e.g. the `gpu_launch_sized_workgroup_mem` intrinsic for details.
pub const GPU_WORKGROUP: Self = AddressSpace(3);
Expand Down
60 changes: 60 additions & 0 deletions compiler/rustc_attr_ir/src/attribute_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,63 @@ const _: () = ();
///
/// [`vtable_entries`]: ../rustc_middle/ty/struct.TyCtxt.html#method.vtable_entries
const _: () = ();

#[doc(attribute = "rustc_dyn_incompatible_trait", alias = "rustc_do_not_implement_via_object")]
/// Opts a trait out of [dyn compatibility].
///
/// This is useful to reserve the ability to add dyn incompatible supertraits or methods to a trait
/// in the future and to ensure the soundness of various constructs - see below for more about that.
///
/// For example [`Field`], [`FnPtr`], [`Tuple`], [`TransmuteFrom`], [`Sized`] and [`Unsize`] must
/// be dyn incompatible because these traits describe properties and layouts of types that would
/// be invalid for trait objects.
///
/// While making a trait dyn incompatible can also be done by including a (hidden and/or unstable)
/// dyn incompatible method in the trait, using `#[rustc_dyn_incompatible_trait]` should be
/// preferred because it is self-documenting and generates better error messages.
///
/// # Example
///
#[doc = include_example!("rustc_dyn_incompatible_trait")]
///
/// # Unsafe traits and dyn (in)compatibility
///
/// [Recall] that a trait object (`dyn Trait`) implements the base trait, its auto traits, and any supertraits of
/// the base trait. This means that it's possible to run into subtle soundness problems when relying
/// on the safety contract of a dyn compatible unsafe trait. See the following example:
///
// ignore-tidy-odd-backticks
/// ```should_panic
#[doc = include_str!("../../../tests/ui/attributes/doc_examples/rustc_dyn_incompatible_trait2.rs")]
// ignore-tidy-odd-backticks
/// ```
///
/// A solution for this is to make `UnsafeTrait` dyn incompatible, forcing `LocalTrait` to also be
/// dyn incompatible so that a `dyn LocalTrait` cannot be formed. This is what we ended up doing for
/// [#154619].
///
/// [`Allocator`] has had similar problems with [`Clone`] ([#156920])
/// but as we really wanted `dyn Allocator` to be a thing we ended up not making it dyn
/// incompatible -- we ended up moving the safety contract to [`AllocatorClone`] instead.
///
/// See also [#156917] and [#160045] for more examples of this problem.
///
/// See [`AttributeKind::RustcDynIncompatibleTrait`] for the internal representation of this attribute.
///
/// [`Allocator`]: core::alloc::Allocator
/// [`AllocatorClone`]: core::alloc::AllocatorClone
/// [`Clone`]: core::clone::Clone
/// [`Field`]: core::field::Field
// FIXME: use core::ops::FnPtr once trickled down to beta
/// [`FnPtr`]: https://doc.rust-lang.org/nightly/core/ops/trait.FnPtr.html
/// [`Tuple`]: core::marker::Tuple
/// [`TransmuteFrom`]: core::mem::TransmuteFrom
/// [`Sized`]: core::marker::Sized
/// [`Unsize`]: core::marker::Unsize
/// [dyn compatibility]: https://doc.rust-lang.org/nightly/reference/items/traits.html#dyn-compatibility
/// [recall]: https://doc.rust-lang.org/nightly/reference/types/trait-object.html#r-type.trait-object.impls
/// [#154619]: https://github.com/rust-lang/rust/issues/154619 "`deref_patterns` is unsound due to `dyn` of subtrait of `DerefPure`"
/// [#156917]: https://github.com/rust-lang/rust/issues/156917 "`dyn Allocator` together with `Allocator + PartialEq` safety requirements leads to unsoundness"
/// [#156920]:https://github.com/rust-lang/rust/issues/156920 "`dyn Allocator` together with `Allocator + Clone` requirements is unsound, leading to UB with `Arc`"
/// [#160045]:https://github.com/rust-lang/rust/issues/160045 "`iter::Rev`'s `TrustedLen` impl is unsound with trait objects"
const _: () = ();
2 changes: 1 addition & 1 deletion compiler/rustc_attr_ir/src/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,7 @@ pub enum AttributeKind {
/// Represents the [`rustc_dump_vtable`](./attribute.rustc_dump_vtable.html) attribute.
RustcDumpVtable(Span),

/// Represents `#[rustc_dyn_incompatible_trait]`.
/// Represents the [`rustc_dyn_incompatible_trait`](./attribute.rustc_dyn_incompatible_trait.html) attribute.
RustcDynIncompatibleTrait(Span),

/// Represents `#[rustc_effective_visibility]`.
Expand Down
24 changes: 14 additions & 10 deletions compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use cranelift_codegen::ir::ArgumentPurpose;
use rustc_abi::{Reg, RegKind};
use rustc_target::callconv::{
ArgAbi, ArgAttributes, ArgExtension as RustcArgExtension, CastTarget, PassMode,
ArgAbi, ArgAttributes, ArgExtension as RustcArgExtension, CastTarget, IndirectMode, PassMode,
};
use smallvec::{SmallVec, smallvec};

Expand Down Expand Up @@ -126,8 +126,12 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
assert_eq!(pad_i32_count, 0, "padding support not yet implemented");
cast_target_to_abi_params(cast).into_iter().map(|(_, param)| param).collect()
}
PassMode::Indirect { attrs, meta_attrs: None, on_stack } => {
if on_stack {
PassMode::Indirect { attrs, meta_attrs: None, address_space: _, mode } => {
assert!(
mode != IndirectMode::AmdgpuKernelArg,
"unsupported amdgpu kernel argument"
);
if mode == IndirectMode::OnStack {
// Abi requires aligning struct size to pointer size
let size = self.layout.size.align_to(tcx.data_layout.pointer_align().abi);
let size = u32::try_from(size.bytes()).unwrap();
Expand All @@ -139,8 +143,8 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
smallvec![apply_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs)]
}
}
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => {
assert!(!on_stack);
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), address_space: _, mode } => {
assert!(mode == IndirectMode::Pointer);
smallvec![
apply_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs),
apply_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), meta_attrs),
Expand Down Expand Up @@ -184,8 +188,8 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
None,
cast_target_to_abi_params(cast).into_iter().map(|(_, param)| param).collect(),
),
PassMode::Indirect { attrs, meta_attrs: None, on_stack } => {
assert!(!on_stack);
PassMode::Indirect { attrs, meta_attrs: None, address_space: _, mode } => {
assert!(mode == IndirectMode::Pointer);
(
Some(apply_attrs_to_abi_param(
AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn),
Expand All @@ -194,7 +198,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
vec![],
)
}
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => {
unreachable!("unsized return value")
}
}
Expand Down Expand Up @@ -324,7 +328,7 @@ pub(super) fn cvalue_for_param<'tcx>(
PassMode::Cast { ref cast, .. } => {
from_casted_value(fx, &block_params, arg_abi.layout, cast)
}
PassMode::Indirect { attrs, meta_attrs: None, on_stack: _ } => {
PassMode::Indirect { attrs, meta_attrs: None, address_space: _, mode: _ } => {
assert_eq!(block_params.len(), 1, "{:?}", block_params);
if let Some(pointee_align) = attrs.pointee_align
&& pointee_align < arg_abi.layout.align.abi
Expand All @@ -342,7 +346,7 @@ pub(super) fn cvalue_for_param<'tcx>(
CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout)
}
}
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => {
assert_eq!(block_params.len(), 2, "{:?}", block_params);
CValue::by_ref_unsized(Pointer::new(block_params[0]), block_params[1], arg_abi.layout)
}
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_codegen_cranelift/src/abi/returning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ pub(super) fn codegen_return_param<'tcx>(
let is_ssa = ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.ret.layout.ty);
(super::make_local_place(fx, RETURN_PLACE, fx.fn_abi.ret.layout, is_ssa), smallvec![])
}
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => {
let ret_param = block_params_iter.next().unwrap();
assert_eq!(fx.bcx.func.dfg.value_type(ret_param), fx.pointer_type);
(CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.ret.layout), smallvec![ret_param])
}
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => {
unreachable!("unsized return value")
}
};
Expand Down Expand Up @@ -50,7 +50,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
) {
let (ret_temp_place, return_ptr) = match ret_arg_abi.mode {
PassMode::Ignore => (None, None),
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => {
if let Some(ret_ptr) = ret_place.try_to_ptr() {
// This is an optimization to prevent unnecessary copies of the return value when
// the return place is already a memory place as opposed to a register.
Expand All @@ -61,7 +61,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
(Some(place), Some(place.to_ptr().get_addr(fx)))
}
}
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => {
unreachable!("unsized return value")
}
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast { .. } => (None, None),
Expand All @@ -86,14 +86,14 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast);
ret_place.write_cvalue(fx, result);
}
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => {
if let Some(ret_temp_place) = ret_temp_place {
// If ret_temp_place is None, it is not necessary to copy the return value.
let ret_temp_value = ret_temp_place.to_cvalue(fx);
ret_place.write_cvalue(fx, ret_temp_value);
}
}
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => {
unreachable!("unsized return value")
}
}
Expand All @@ -102,10 +102,11 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
/// Codegen a return instruction with the right return value(s) if any.
pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) {
match fx.fn_abi.ret.mode {
PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
PassMode::Ignore
| PassMode::Indirect { attrs: _, meta_attrs: None, address_space: _, mode: _ } => {
fx.bcx.ins().return_(&[]);
}
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), address_space: _, mode: _ } => {
unreachable!("unsized return value")
}
PassMode::Direct(_) => {
Expand Down
33 changes: 28 additions & 5 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_middle::ty::layout::LayoutOf;
#[cfg(feature = "master")]
use rustc_session::{Session, config};
use rustc_span::bug;
use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode};
use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, IndirectMode, PassMode};
#[cfg(feature = "master")]
use rustc_target::spec::Arch;

Expand Down Expand Up @@ -189,7 +189,12 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
let ty = cast.gcc_type(cx);
apply_attrs(ty, &cast.attrs, argument_tys.len())
}
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: true } => {
PassMode::Indirect {
attrs: _,
meta_attrs: None,
address_space: _,
mode: IndirectMode::OnStack,
} => {
let x86_interrupt_first_arg = {
#[cfg(feature = "master")]
{
Expand All @@ -216,14 +221,32 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
arg.layout.gcc_type(cx)
}
}
PassMode::Indirect {
attrs: _,
meta_attrs: None,
address_space: _,
mode: IndirectMode::AmdgpuKernelArg,
} => {
unimplemented!("unsupported amdgpu kernel argument")
}
PassMode::Direct(attrs) => {
apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len())
}
PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => {
PassMode::Indirect {
attrs,
meta_attrs: None,
address_space: _,
mode: IndirectMode::Pointer,
} => {
apply_attrs(cx.type_ptr_to(arg.layout.gcc_type(cx)), &attrs, argument_tys.len())
}
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => {
assert!(!on_stack);
PassMode::Indirect {
attrs,
meta_attrs: Some(meta_attrs),
address_space: _,
mode,
} => {
assert!(mode == IndirectMode::Pointer);
// Construct the type of a (wide) pointer to `ty`, and pass its two fields.
// Any two ABI-compatible unsized types have the same metadata type and
// moreover the same metadata value leads to the same dynamic size and
Expand Down
Loading
Loading