Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit dee520e

Browse files
committed
Auto merge of rust-lang#134097 - fmease:rollup-e6kszfd, r=fmease
Rollup of 9 pull requests Successful merges: - rust-lang#133967 ([AIX] Pass -bnoipath when adding rust upstream dynamic crates) - rust-lang#133970 ([AIX] Replace sa_sigaction with sa_union.__su_sigaction for AIX) - rust-lang#133980 ([AIX] Remove option "-n" from AIX "ln" command) - rust-lang#134008 (Make `Copy` unsafe to implement for ADTs with `unsafe` fields) - rust-lang#134017 (Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction) - rust-lang#134023 (handle cygwin environment in `install::sanitize_sh`) - rust-lang#134041 (Use SourceMap to load debugger visualizer files) - rust-lang#134065 (Move `write_graphviz_results`) - rust-lang#134070 (Some asm! diagnostic adjustments and a papercut fix) r? `@ghost` `@rustbot` modify labels: rollup
2 parents ff7906b + c553994 commit dee520e

File tree

30 files changed

+560
-317
lines changed

30 files changed

+560
-317
lines changed

compiler/rustc_codegen_cranelift/example/mini_core.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,26 +55,26 @@ impl<T: ?Sized> LegacyReceiver for &mut T {}
5555
impl<T: ?Sized> LegacyReceiver for Box<T> {}
5656

5757
#[lang = "copy"]
58-
pub unsafe trait Copy {}
59-
60-
unsafe impl Copy for bool {}
61-
unsafe impl Copy for u8 {}
62-
unsafe impl Copy for u16 {}
63-
unsafe impl Copy for u32 {}
64-
unsafe impl Copy for u64 {}
65-
unsafe impl Copy for u128 {}
66-
unsafe impl Copy for usize {}
67-
unsafe impl Copy for i8 {}
68-
unsafe impl Copy for i16 {}
69-
unsafe impl Copy for i32 {}
70-
unsafe impl Copy for isize {}
71-
unsafe impl Copy for f32 {}
72-
unsafe impl Copy for f64 {}
73-
unsafe impl Copy for char {}
74-
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
75-
unsafe impl<T: ?Sized> Copy for *const T {}
76-
unsafe impl<T: ?Sized> Copy for *mut T {}
77-
unsafe impl<T: Copy> Copy for Option<T> {}
58+
pub trait Copy {}
59+
60+
impl Copy for bool {}
61+
impl Copy for u8 {}
62+
impl Copy for u16 {}
63+
impl Copy for u32 {}
64+
impl Copy for u64 {}
65+
impl Copy for u128 {}
66+
impl Copy for usize {}
67+
impl Copy for i8 {}
68+
impl Copy for i16 {}
69+
impl Copy for i32 {}
70+
impl Copy for isize {}
71+
impl Copy for f32 {}
72+
impl Copy for f64 {}
73+
impl Copy for char {}
74+
impl<'a, T: ?Sized> Copy for &'a T {}
75+
impl<T: ?Sized> Copy for *const T {}
76+
impl<T: ?Sized> Copy for *mut T {}
77+
impl<T: Copy> Copy for Option<T> {}
7878

7979
#[lang = "sync"]
8080
pub unsafe trait Sync {}

compiler/rustc_codegen_gcc/example/mini_core.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,24 @@ impl<T: ?Sized> LegacyReceiver for &mut T {}
5252
impl<T: ?Sized, A: Allocator> LegacyReceiver for Box<T, A> {}
5353

5454
#[lang = "copy"]
55-
pub unsafe trait Copy {}
56-
57-
unsafe impl Copy for bool {}
58-
unsafe impl Copy for u8 {}
59-
unsafe impl Copy for u16 {}
60-
unsafe impl Copy for u32 {}
61-
unsafe impl Copy for u64 {}
62-
unsafe impl Copy for usize {}
63-
unsafe impl Copy for i8 {}
64-
unsafe impl Copy for i16 {}
65-
unsafe impl Copy for i32 {}
66-
unsafe impl Copy for isize {}
67-
unsafe impl Copy for f32 {}
68-
unsafe impl Copy for f64 {}
69-
unsafe impl Copy for char {}
70-
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
71-
unsafe impl<T: ?Sized> Copy for *const T {}
72-
unsafe impl<T: ?Sized> Copy for *mut T {}
55+
pub trait Copy {}
56+
57+
impl Copy for bool {}
58+
impl Copy for u8 {}
59+
impl Copy for u16 {}
60+
impl Copy for u32 {}
61+
impl Copy for u64 {}
62+
impl Copy for usize {}
63+
impl Copy for i8 {}
64+
impl Copy for i16 {}
65+
impl Copy for i32 {}
66+
impl Copy for isize {}
67+
impl Copy for f32 {}
68+
impl Copy for f64 {}
69+
impl Copy for char {}
70+
impl<'a, T: ?Sized> Copy for &'a T {}
71+
impl<T: ?Sized> Copy for *const T {}
72+
impl<T: ?Sized> Copy for *mut T {}
7373

7474
#[lang = "sync"]
7575
pub unsafe trait Sync {}

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2745,6 +2745,15 @@ fn add_upstream_rust_crates(
27452745
.find(|(ty, _)| *ty == crate_type)
27462746
.expect("failed to find crate type in dependency format list");
27472747

2748+
if sess.target.is_like_aix {
2749+
// Unlike ELF linkers, AIX doesn't feature `DT_SONAME` to override
2750+
// the dependency name when outputing a shared library. Thus, `ld` will
2751+
// use the full path to shared libraries as the dependency if passed it
2752+
// by default unless `noipath` is passed.
2753+
// https://www.ibm.com/docs/en/aix/7.3?topic=l-ld-command.
2754+
cmd.link_or_cc_arg("-bnoipath");
2755+
}
2756+
27482757
for &cnum in &codegen_results.crate_info.used_crates {
27492758
// We may not pass all crates through to the linker. Some crates may appear statically in
27502759
// an existing dylib, meaning we'll pick up all the symbols from the dylib.

compiler/rustc_hir_analysis/src/check/intrinsicck.rs

Lines changed: 74 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::assert_matches::debug_assert_matches;
33
use rustc_abi::FieldIdx;
44
use rustc_ast::InlineAsmTemplatePiece;
55
use rustc_data_structures::fx::FxIndexSet;
6+
use rustc_hir::def_id::DefId;
67
use rustc_hir::{self as hir, LangItem};
78
use rustc_middle::bug;
89
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
@@ -21,6 +22,12 @@ pub struct InlineAsmCtxt<'a, 'tcx> {
2122
get_operand_ty: Box<dyn Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
2223
}
2324

25+
enum NonAsmTypeReason<'tcx> {
26+
UnevaluatedSIMDArrayLength(DefId, ty::Const<'tcx>),
27+
Invalid(Ty<'tcx>),
28+
InvalidElement(DefId, Ty<'tcx>),
29+
}
30+
2431
impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
2532
pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
2633
InlineAsmCtxt {
@@ -56,7 +63,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
5663
false
5764
}
5865

59-
fn get_asm_ty(&self, ty: Ty<'tcx>) -> Option<InlineAsmType> {
66+
fn get_asm_ty(&self, ty: Ty<'tcx>) -> Result<InlineAsmType, NonAsmTypeReason<'tcx>> {
6067
let asm_ty_isize = match self.tcx.sess.target.pointer_width {
6168
16 => InlineAsmType::I16,
6269
32 => InlineAsmType::I32,
@@ -65,64 +72,62 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
6572
};
6673

6774
match *ty.kind() {
68-
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
69-
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16),
70-
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
71-
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Some(InlineAsmType::I64),
72-
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Some(InlineAsmType::I128),
73-
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(asm_ty_isize),
74-
ty::Float(FloatTy::F16) => Some(InlineAsmType::F16),
75-
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
76-
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
77-
ty::Float(FloatTy::F128) => Some(InlineAsmType::F128),
78-
ty::FnPtr(..) => Some(asm_ty_isize),
79-
ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Some(asm_ty_isize),
75+
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Ok(InlineAsmType::I8),
76+
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Ok(InlineAsmType::I16),
77+
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Ok(InlineAsmType::I32),
78+
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Ok(InlineAsmType::I64),
79+
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Ok(InlineAsmType::I128),
80+
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Ok(asm_ty_isize),
81+
ty::Float(FloatTy::F16) => Ok(InlineAsmType::F16),
82+
ty::Float(FloatTy::F32) => Ok(InlineAsmType::F32),
83+
ty::Float(FloatTy::F64) => Ok(InlineAsmType::F64),
84+
ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128),
85+
ty::FnPtr(..) => Ok(asm_ty_isize),
86+
ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Ok(asm_ty_isize),
8087
ty::Adt(adt, args) if adt.repr().simd() => {
8188
let fields = &adt.non_enum_variant().fields;
82-
let elem_ty = fields[FieldIdx::ZERO].ty(self.tcx, args);
89+
let field = &fields[FieldIdx::ZERO];
90+
let elem_ty = field.ty(self.tcx, args);
8391

8492
let (size, ty) = match elem_ty.kind() {
8593
ty::Array(ty, len) => {
94+
let len = self.tcx.normalize_erasing_regions(self.typing_env, *len);
8695
if let Some(len) = len.try_to_target_usize(self.tcx) {
8796
(len, *ty)
8897
} else {
89-
return None;
98+
return Err(NonAsmTypeReason::UnevaluatedSIMDArrayLength(
99+
field.did, len,
100+
));
90101
}
91102
}
92103
_ => (fields.len() as u64, elem_ty),
93104
};
94105

95106
match ty.kind() {
96-
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::VecI8(size)),
97-
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => {
98-
Some(InlineAsmType::VecI16(size))
99-
}
100-
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => {
101-
Some(InlineAsmType::VecI32(size))
102-
}
103-
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => {
104-
Some(InlineAsmType::VecI64(size))
105-
}
107+
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Ok(InlineAsmType::VecI8(size)),
108+
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Ok(InlineAsmType::VecI16(size)),
109+
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Ok(InlineAsmType::VecI32(size)),
110+
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Ok(InlineAsmType::VecI64(size)),
106111
ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => {
107-
Some(InlineAsmType::VecI128(size))
112+
Ok(InlineAsmType::VecI128(size))
108113
}
109114
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => {
110-
Some(match self.tcx.sess.target.pointer_width {
115+
Ok(match self.tcx.sess.target.pointer_width {
111116
16 => InlineAsmType::VecI16(size),
112117
32 => InlineAsmType::VecI32(size),
113118
64 => InlineAsmType::VecI64(size),
114119
width => bug!("unsupported pointer width: {width}"),
115120
})
116121
}
117-
ty::Float(FloatTy::F16) => Some(InlineAsmType::VecF16(size)),
118-
ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)),
119-
ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(size)),
120-
ty::Float(FloatTy::F128) => Some(InlineAsmType::VecF128(size)),
121-
_ => None,
122+
ty::Float(FloatTy::F16) => Ok(InlineAsmType::VecF16(size)),
123+
ty::Float(FloatTy::F32) => Ok(InlineAsmType::VecF32(size)),
124+
ty::Float(FloatTy::F64) => Ok(InlineAsmType::VecF64(size)),
125+
ty::Float(FloatTy::F128) => Ok(InlineAsmType::VecF128(size)),
126+
_ => Err(NonAsmTypeReason::InvalidElement(field.did, ty)),
122127
}
123128
}
124129
ty::Infer(_) => bug!("unexpected infer ty in asm operand"),
125-
_ => None,
130+
_ => Err(NonAsmTypeReason::Invalid(ty)),
126131
}
127132
}
128133

@@ -163,17 +168,42 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
163168
}
164169
_ => self.get_asm_ty(ty),
165170
};
166-
let Some(asm_ty) = asm_ty else {
167-
let msg = format!("cannot use value of type `{ty}` for inline assembly");
168-
self.tcx
169-
.dcx()
170-
.struct_span_err(expr.span, msg)
171-
.with_note(
172-
"only integers, floats, SIMD vectors, pointers and function pointers \
173-
can be used as arguments for inline assembly",
174-
)
175-
.emit();
176-
return None;
171+
let asm_ty = match asm_ty {
172+
Ok(asm_ty) => asm_ty,
173+
Err(reason) => {
174+
match reason {
175+
NonAsmTypeReason::UnevaluatedSIMDArrayLength(did, len) => {
176+
let msg = format!("cannot evaluate SIMD vector length `{len}`");
177+
self.tcx
178+
.dcx()
179+
.struct_span_err(self.tcx.def_span(did), msg)
180+
.with_span_note(
181+
expr.span,
182+
"SIMD vector length needs to be known statically for use in `asm!`",
183+
)
184+
.emit();
185+
}
186+
NonAsmTypeReason::Invalid(ty) => {
187+
let msg = format!("cannot use value of type `{ty}` for inline assembly");
188+
self.tcx.dcx().struct_span_err(expr.span, msg).with_note(
189+
"only integers, floats, SIMD vectors, pointers and function pointers \
190+
can be used as arguments for inline assembly",
191+
).emit();
192+
}
193+
NonAsmTypeReason::InvalidElement(did, ty) => {
194+
let msg = format!(
195+
"cannot use SIMD vector with element type `{ty}` for inline assembly"
196+
);
197+
self.tcx.dcx()
198+
.struct_span_err(self.tcx.def_span(did), msg).with_span_note(
199+
expr.span,
200+
"only integers, floats, SIMD vectors, pointers and function pointers \
201+
can be used as arguments for inline assembly",
202+
).emit();
203+
}
204+
}
205+
return None;
206+
}
177207
};
178208

179209
// Check that the type implements Copy. The only case where this can

compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
103103
}
104104

105105
let cause = traits::ObligationCause::misc(DUMMY_SP, impl_did);
106-
match type_allowed_to_implement_copy(tcx, param_env, self_type, cause) {
106+
match type_allowed_to_implement_copy(tcx, param_env, self_type, cause, impl_header.safety) {
107107
Ok(()) => Ok(()),
108108
Err(CopyImplementationError::InfringingFields(fields)) => {
109109
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
@@ -123,6 +123,12 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
123123
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
124124
Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span }))
125125
}
126+
Err(CopyImplementationError::HasUnsafeFields) => {
127+
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
128+
Err(tcx
129+
.dcx()
130+
.span_delayed_bug(span, format!("cannot implement `Copy` for `{}`", self_type)))
131+
}
126132
}
127133
}
128134

compiler/rustc_hir_analysis/src/coherence/unsafety.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use rustc_errors::codes::*;
55
use rustc_errors::struct_span_code_err;
6-
use rustc_hir::Safety;
6+
use rustc_hir::{LangItem, Safety};
77
use rustc_middle::ty::ImplPolarity::*;
88
use rustc_middle::ty::print::PrintTraitRefExt as _;
99
use rustc_middle::ty::{ImplTraitHeader, TraitDef, TyCtxt};
@@ -20,7 +20,19 @@ pub(super) fn check_item(
2020
tcx.generics_of(def_id).own_params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
2121
let trait_ref = trait_header.trait_ref.instantiate_identity();
2222

23-
match (trait_def.safety, unsafe_attr, trait_header.safety, trait_header.polarity) {
23+
let is_copy = tcx.is_lang_item(trait_def.def_id, LangItem::Copy);
24+
let trait_def_safety = if is_copy {
25+
// If `Self` has unsafe fields, `Copy` is unsafe to implement.
26+
if trait_header.trait_ref.skip_binder().self_ty().has_unsafe_fields() {
27+
rustc_hir::Safety::Unsafe
28+
} else {
29+
rustc_hir::Safety::Safe
30+
}
31+
} else {
32+
trait_def.safety
33+
};
34+
35+
match (trait_def_safety, unsafe_attr, trait_header.safety, trait_header.polarity) {
2436
(Safety::Safe, None, Safety::Unsafe, Positive | Reservation) => {
2537
let span = tcx.def_span(def_id);
2638
return Err(struct_span_code_err!(
@@ -48,12 +60,22 @@ pub(super) fn check_item(
4860
"the trait `{}` requires an `unsafe impl` declaration",
4961
trait_ref.print_trait_sugared()
5062
)
51-
.with_note(format!(
52-
"the trait `{}` enforces invariants that the compiler can't check. \
53-
Review the trait documentation and make sure this implementation \
54-
upholds those invariants before adding the `unsafe` keyword",
55-
trait_ref.print_trait_sugared()
56-
))
63+
.with_note(if is_copy {
64+
format!(
65+
"the trait `{}` cannot be safely implemented for `{}` \
66+
because it has unsafe fields. Review the invariants \
67+
of those fields before adding an `unsafe impl`",
68+
trait_ref.print_trait_sugared(),
69+
trait_ref.self_ty(),
70+
)
71+
} else {
72+
format!(
73+
"the trait `{}` enforces invariants that the compiler can't check. \
74+
Review the trait documentation and make sure this implementation \
75+
upholds those invariants before adding the `unsafe` keyword",
76+
trait_ref.print_trait_sugared()
77+
)
78+
})
5779
.with_span_suggestion_verbose(
5880
span.shrink_to_lo(),
5981
"add `unsafe` to this trait implementation",

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -454,28 +454,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
454454
closure_kind: hir::ClosureKind,
455455
projection: ty::PolyProjectionPredicate<'tcx>,
456456
) -> Option<ExpectedSig<'tcx>> {
457-
let tcx = self.tcx;
458-
459-
let trait_def_id = projection.trait_def_id(tcx);
457+
let def_id = projection.projection_def_id();
460458

461459
// For now, we only do signature deduction based off of the `Fn` and `AsyncFn` traits,
462460
// for closures and async closures, respectively.
463461
match closure_kind {
464-
hir::ClosureKind::Closure
465-
if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() =>
466-
{
462+
hir::ClosureKind::Closure if self.tcx.is_lang_item(def_id, LangItem::FnOnceOutput) => {
467463
self.extract_sig_from_projection(cause_span, projection)
468464
}
469465
hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async)
470-
if self.tcx.async_fn_trait_kind_from_def_id(trait_def_id).is_some() =>
466+
if self.tcx.is_lang_item(def_id, LangItem::AsyncFnOnceOutput) =>
471467
{
472468
self.extract_sig_from_projection(cause_span, projection)
473469
}
474470
// It's possible we've passed the closure to a (somewhat out-of-fashion)
475471
// `F: FnOnce() -> Fut, Fut: Future<Output = T>` style bound. Let's still
476472
// guide inference here, since it's beneficial for the user.
477473
hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async)
478-
if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() =>
474+
if self.tcx.is_lang_item(def_id, LangItem::FnOnceOutput) =>
479475
{
480476
self.extract_sig_from_projection_and_future_bound(cause_span, projection)
481477
}

0 commit comments

Comments
 (0)