Skip to content

Commit 99ba695

Browse files
committed
Auto merge of rust-lang#129773 - workingjubilee:rollup-qdoxwhe, r=workingjubilee
Rollup of 8 pull requests Successful merges: - rust-lang#126183 (Separate core search logic with search ui) - rust-lang#129366 (linker: Synchronize native library search in rustc and linker) - rust-lang#129403 (Ban non-array SIMD) - rust-lang#129527 (Don't use `TyKind` in a lint) - rust-lang#129534 (Deny `wasm_c_abi` lint to nudge the last 25%) - rust-lang#129640 (Re-enable android tests/benches in alloc/core) - rust-lang#129731 (Allow running `./x.py test compiler`) - rust-lang#129754 (wasi: Fix sleeping for `Duration::MAX`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0d63418 + 4f38687 commit 99ba695

File tree

142 files changed

+4474
-4685
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+4474
-4685
lines changed

compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99

1010
#[repr(simd)]
1111
#[derive(Copy, Clone, PartialEq, Debug)]
12-
struct f32x4(pub f32, pub f32, pub f32, pub f32);
12+
struct f32x4(pub [f32; 4]);
1313

1414
use std::intrinsics::simd::*;
1515

1616
fn main() {
17-
let x = f32x4(1.0, 2.0, 3.0, 4.0);
18-
let y = f32x4(2.0, 1.0, 4.0, 3.0);
17+
let x = f32x4([1.0, 2.0, 3.0, 4.0]);
18+
let y = f32x4([2.0, 1.0, 4.0, 3.0]);
1919

2020
#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
2121
let nan = f32::NAN;
@@ -24,13 +24,13 @@ fn main() {
2424
#[cfg(any(target_arch = "mips", target_arch = "mips64"))]
2525
let nan = f32::from_bits(f32::NAN.to_bits() - 1);
2626

27-
let n = f32x4(nan, nan, nan, nan);
27+
let n = f32x4([nan, nan, nan, nan]);
2828

2929
unsafe {
3030
let min0 = simd_fmin(x, y);
3131
let min1 = simd_fmin(y, x);
3232
assert_eq!(min0, min1);
33-
let e = f32x4(1.0, 1.0, 3.0, 3.0);
33+
let e = f32x4([1.0, 1.0, 3.0, 3.0]);
3434
assert_eq!(min0, e);
3535
let minn = simd_fmin(x, n);
3636
assert_eq!(minn, x);
@@ -40,7 +40,7 @@ fn main() {
4040
let max0 = simd_fmax(x, y);
4141
let max1 = simd_fmax(y, x);
4242
assert_eq!(max0, max1);
43-
let e = f32x4(2.0, 2.0, 4.0, 4.0);
43+
let e = f32x4([2.0, 2.0, 4.0, 4.0]);
4444
assert_eq!(max0, e);
4545
let maxn = simd_fmax(x, n);
4646
assert_eq!(maxn, x);

compiler/rustc_codegen_cranelift/example/std_example.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ fn main() {
166166
enum Never {}
167167
}
168168

169-
foo(I64X2(0, 0));
169+
foo(I64X2([0, 0]));
170170

171171
transmute_fat_pointer();
172172

@@ -204,7 +204,7 @@ fn rust_call_abi() {
204204
}
205205

206206
#[repr(simd)]
207-
struct I64X2(i64, i64);
207+
struct I64X2([i64; 2]);
208208

209209
#[allow(improper_ctypes_definitions)]
210210
extern "C" fn foo(_a: I64X2) {}

compiler/rustc_codegen_ssa/src/back/link.rs

+15-46
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::BTreeSet;
22
use std::ffi::OsString;
33
use std::fs::{read, File, OpenOptions};
44
use std::io::{BufWriter, Write};
5-
use std::ops::Deref;
5+
use std::ops::{ControlFlow, Deref};
66
use std::path::{Path, PathBuf};
77
use std::process::{ExitStatus, Output, Stdio};
88
use std::{env, fmt, fs, io, mem, str};
@@ -18,8 +18,8 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
1818
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError};
1919
use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
2020
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
21-
use rustc_metadata::find_native_static_library;
2221
use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
22+
use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
2323
use rustc_middle::bug;
2424
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
2525
use rustc_middle::middle::dependency_format::Linkage;
@@ -2110,50 +2110,19 @@ fn add_library_search_dirs(
21102110
return;
21112111
}
21122112

2113-
// Library search paths explicitly supplied by user (`-L` on the command line).
2114-
for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
2115-
cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir));
2116-
}
2117-
for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
2118-
// Contrary to the `-L` docs only framework-specific paths are considered here.
2119-
if search_path.kind != PathKind::All {
2120-
cmd.framework_path(&search_path.dir);
2121-
}
2122-
}
2123-
2124-
// The toolchain ships some native library components and self-contained linking was enabled.
2125-
// Add the self-contained library directory to search paths.
2126-
if self_contained_components.intersects(
2127-
LinkSelfContainedComponents::LIBC
2128-
| LinkSelfContainedComponents::UNWIND
2129-
| LinkSelfContainedComponents::MINGW,
2130-
) {
2131-
let lib_path = sess.target_tlib_path.dir.join("self-contained");
2132-
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
2133-
}
2134-
2135-
// Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
2136-
// library directory instead of the self-contained directories.
2137-
// Sanitizer libraries have the same issue and are also linked by name on Apple targets.
2138-
// The targets here should be in sync with `copy_third_party_objects` in bootstrap.
2139-
// FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
2140-
// and sanitizers to self-contained directory, and stop adding this search path.
2141-
if sess.target.vendor == "fortanix"
2142-
|| sess.target.os == "linux"
2143-
|| sess.target.os == "fuchsia"
2144-
|| sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
2145-
{
2146-
cmd.include_path(&fix_windows_verbatim_for_gcc(&sess.target_tlib_path.dir));
2147-
}
2148-
2149-
// Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
2150-
// we must have the support library stubs in the library search path (#121430).
2151-
if let Some(sdk_root) = apple_sdk_root
2152-
&& sess.target.llvm_target.contains("macabi")
2153-
{
2154-
cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib"));
2155-
cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"));
2156-
}
2113+
walk_native_lib_search_dirs(
2114+
sess,
2115+
self_contained_components,
2116+
apple_sdk_root,
2117+
|dir, is_framework| {
2118+
if is_framework {
2119+
cmd.framework_path(dir);
2120+
} else {
2121+
cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
2122+
}
2123+
ControlFlow::<()>::Continue(())
2124+
},
2125+
);
21572126
}
21582127

21592128
/// Add options making relocation sections in the produced ELF files read-only

compiler/rustc_codegen_ssa/src/back/linker.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{env, iter, mem, str};
77

88
use cc::windows_registry;
99
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
10-
use rustc_metadata::find_native_static_library;
10+
use rustc_metadata::{find_native_static_library, try_find_native_static_library};
1111
use rustc_middle::bug;
1212
use rustc_middle::middle::dependency_format::Linkage;
1313
use rustc_middle::middle::exported_symbols;
@@ -891,9 +891,15 @@ impl<'a> Linker for MsvcLinker<'a> {
891891
}
892892

893893
fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) {
894-
let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
895-
let suffix = if verbatim { "" } else { ".lib" };
896-
self.link_arg(format!("{prefix}{name}{suffix}"));
894+
// On MSVC-like targets rustc supports static libraries using alternative naming
895+
// scheme (`libfoo.a`) unsupported by linker, search for such libraries manually.
896+
if let Some(path) = try_find_native_static_library(self.sess, name, verbatim) {
897+
self.link_staticlib_by_path(&path, whole_archive);
898+
} else {
899+
let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
900+
let suffix = if verbatim { "" } else { ".lib" };
901+
self.link_arg(format!("{prefix}{name}{suffix}"));
902+
}
897903
}
898904

899905
fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) {

compiler/rustc_error_codes/src/error_codes/E0074.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This will cause an error:
1111
#![feature(repr_simd)]
1212
1313
#[repr(simd)]
14-
struct Bad<T>(T, T, T, T);
14+
struct Bad<T>([T; 4]);
1515
```
1616

1717
This will not:
@@ -20,5 +20,5 @@ This will not:
2020
#![feature(repr_simd)]
2121
2222
#[repr(simd)]
23-
struct Good(u32, u32, u32, u32);
23+
struct Good([u32; 4]);
2424
```
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
A `#[simd]` attribute was applied to an empty tuple struct.
1+
A `#[simd]` attribute was applied to an empty or multi-field struct.
22

3-
Erroneous code example:
3+
Erroneous code examples:
44

55
```compile_fail,E0075
66
#![feature(repr_simd)]
@@ -9,15 +9,21 @@ Erroneous code example:
99
struct Bad; // error!
1010
```
1111

12-
The `#[simd]` attribute can only be applied to non empty tuple structs, because
13-
it doesn't make sense to try to use SIMD operations when there are no values to
14-
operate on.
12+
```compile_fail,E0075
13+
#![feature(repr_simd)]
14+
15+
#[repr(simd)]
16+
struct Bad([u32; 1], [u32; 1]); // error!
17+
```
18+
19+
The `#[simd]` attribute can only be applied to a single-field struct, because
20+
the one field must be the array of values in the vector.
1521

1622
Fixed example:
1723

1824
```
1925
#![feature(repr_simd)]
2026
2127
#[repr(simd)]
22-
struct Good(u32); // ok!
28+
struct Good([u32; 2]); // ok!
2329
```
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
All types in a tuple struct aren't the same when using the `#[simd]`
1+
The type of the field in a tuple struct isn't an array when using the `#[simd]`
22
attribute.
33

44
Erroneous code example:
@@ -7,18 +7,18 @@ Erroneous code example:
77
#![feature(repr_simd)]
88
99
#[repr(simd)]
10-
struct Bad(u16, u32, u32 u32); // error!
10+
struct Bad(u16); // error!
1111
```
1212

1313
When using the `#[simd]` attribute to automatically use SIMD operations in tuple
14-
struct, the types in the struct must all be of the same type, or the compiler
15-
will trigger this error.
14+
structs, if you want a single-lane vector then the field must be a 1-element
15+
array, or the compiler will trigger this error.
1616

1717
Fixed example:
1818

1919
```
2020
#![feature(repr_simd)]
2121
2222
#[repr(simd)]
23-
struct Good(u32, u32, u32, u32); // ok!
23+
struct Good([u16; 1]); // ok!
2424
```

compiler/rustc_error_codes/src/error_codes/E0077.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Erroneous code example:
77
#![feature(repr_simd)]
88
99
#[repr(simd)]
10-
struct Bad(String); // error!
10+
struct Bad([String; 2]); // error!
1111
```
1212

1313
When using the `#[simd]` attribute on a tuple struct, the elements in the tuple
@@ -19,5 +19,5 @@ Fixed example:
1919
#![feature(repr_simd)]
2020
2121
#[repr(simd)]
22-
struct Good(u32, u32, u32, u32); // ok!
22+
struct Good([u32; 4]); // ok!
2323
```

compiler/rustc_error_codes/src/error_codes/E0511.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ The generic type has to be a SIMD type. Example:
2323
2424
#[repr(simd)]
2525
#[derive(Copy, Clone)]
26-
struct i32x2(i32, i32);
26+
struct i32x2([i32; 2]);
2727
2828
extern "rust-intrinsic" {
2929
fn simd_add<T>(a: T, b: T) -> T;
3030
}
3131
32-
unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
32+
unsafe { simd_add(i32x2([0, 0]), i32x2([1, 2])); } // ok!
3333
```

compiler/rustc_hir_analysis/src/check/check.rs

+22-20
Original file line numberDiff line numberDiff line change
@@ -1063,20 +1063,29 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
10631063
struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
10641064
return;
10651065
}
1066-
let e = fields[FieldIdx::ZERO].ty(tcx, args);
1067-
if !fields.iter().all(|f| f.ty(tcx, args) == e) {
1068-
struct_span_code_err!(tcx.dcx(), sp, E0076, "SIMD vector should be homogeneous")
1069-
.with_span_label(sp, "SIMD elements must have the same type")
1066+
1067+
let array_field = &fields[FieldIdx::ZERO];
1068+
let array_ty = array_field.ty(tcx, args);
1069+
let ty::Array(element_ty, len_const) = array_ty.kind() else {
1070+
struct_span_code_err!(
1071+
tcx.dcx(),
1072+
sp,
1073+
E0076,
1074+
"SIMD vector's only field must be an array"
1075+
)
1076+
.with_span_label(tcx.def_span(array_field.did), "not an array")
1077+
.emit();
1078+
return;
1079+
};
1080+
1081+
if let Some(second_field) = fields.get(FieldIdx::from_u32(1)) {
1082+
struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot have multiple fields")
1083+
.with_span_label(tcx.def_span(second_field.did), "excess field")
10701084
.emit();
10711085
return;
10721086
}
10731087

1074-
let len = if let ty::Array(_ty, c) = e.kind() {
1075-
c.try_eval_target_usize(tcx, tcx.param_env(def.did()))
1076-
} else {
1077-
Some(fields.len() as u64)
1078-
};
1079-
if let Some(len) = len {
1088+
if let Some(len) = len_const.try_eval_target_usize(tcx, tcx.param_env(def.did())) {
10801089
if len == 0 {
10811090
struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
10821091
return;
@@ -1096,16 +1105,9 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
10961105
// These are scalar types which directly match a "machine" type
10971106
// Yes: Integers, floats, "thin" pointers
10981107
// No: char, "fat" pointers, compound types
1099-
match e.kind() {
1100-
ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
1101-
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_, _) => (), // struct(u8, u8, u8, u8) is ok
1102-
ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
1103-
ty::Array(t, _clen)
1104-
if matches!(
1105-
t.kind(),
1106-
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_, _)
1107-
) =>
1108-
{ /* struct([f32; 4]) is ok */ }
1108+
match element_ty.kind() {
1109+
ty::Param(_) => (), // pass struct<T>([T; 4]) through, let monomorphization catch errors
1110+
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_, _) => (), // struct([u8; 4]) is ok
11091111
_ => {
11101112
struct_span_code_err!(
11111113
tcx.dcx(),

compiler/rustc_lint/src/foreign_modules.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,6 @@ fn structurally_same_type_impl<'tcx>(
265265
} else {
266266
// Do a full, depth-first comparison between the two.
267267
use rustc_type_ir::TyKind::*;
268-
let a_kind = a.kind();
269-
let b_kind = b.kind();
270268

271269
let compare_layouts = |a, b| -> Result<bool, &'tcx LayoutError<'tcx>> {
272270
debug!("compare_layouts({:?}, {:?})", a, b);
@@ -281,12 +279,11 @@ fn structurally_same_type_impl<'tcx>(
281279
Ok(a_layout == b_layout)
282280
};
283281

284-
#[allow(rustc::usage_of_ty_tykind)]
285282
let is_primitive_or_pointer =
286-
|kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..));
283+
|ty: Ty<'tcx>| ty.is_primitive() || matches!(ty.kind(), RawPtr(..) | Ref(..));
287284

288285
ensure_sufficient_stack(|| {
289-
match (a_kind, b_kind) {
286+
match (a.kind(), b.kind()) {
290287
(Adt(a_def, _), Adt(b_def, _)) => {
291288
// We can immediately rule out these types as structurally same if
292289
// their layouts differ.
@@ -382,17 +379,21 @@ fn structurally_same_type_impl<'tcx>(
382379

383380
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
384381
// enum layout optimisation is being applied.
385-
(Adt(..), other_kind) | (other_kind, Adt(..))
386-
if is_primitive_or_pointer(other_kind) =>
387-
{
388-
let (primitive, adt) =
389-
if is_primitive_or_pointer(a.kind()) { (a, b) } else { (b, a) };
390-
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, adt, ckind) {
391-
ty == primitive
382+
(Adt(..), _) if is_primitive_or_pointer(b) => {
383+
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, a, ckind) {
384+
ty == b
392385
} else {
393386
compare_layouts(a, b).unwrap_or(false)
394387
}
395388
}
389+
(_, Adt(..)) if is_primitive_or_pointer(a) => {
390+
if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, b, ckind) {
391+
ty == a
392+
} else {
393+
compare_layouts(a, b).unwrap_or(false)
394+
}
395+
}
396+
396397
// Otherwise, just compare the layouts. This may fail to lint for some
397398
// incompatible types, but at the very least, will stop reads into
398399
// uninitialised memory.

0 commit comments

Comments
 (0)