about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-10-31 12:35:55 +0100
committerGitHub <noreply@github.com>2024-10-31 12:35:55 +0100
commit2da55600bc3d7830ee7d3e0567d60bd6c680eb11 (patch)
treeb996b2fd00fb02462648e39c368db0c0994eaaed /tests
parent4d296eabe4c5cfbce9bb68e6221bca2165aae97b (diff)
parentadb6d4752fd00093d44e0285cfff28406dfb7229 (diff)
downloadrust-2da55600bc3d7830ee7d3e0567d60bd6c680eb11.tar.gz
rust-2da55600bc3d7830ee7d3e0567d60bd6c680eb11.zip
Rollup merge of #130693 - jieyouxu:minicore, r=bjorn3
Add `minicore` test auxiliary and support `//@ add-core-stubs` directive in ui/assembly/codegen tests

Context: [Real cross-compiling tests instead of `#![no_core]` silliness #130375](https://github.com/rust-lang/rust/issues/130375)
MCP: https://github.com/rust-lang/compiler-team/issues/786
Tracking issue: https://github.com/rust-lang/rust/issues/131485

This prototype PR is subject to further changes based on feedback.

### New `minicore` test auxiliary and `//@ add-core-stubs` compiletest directive

This PR introduces a prototype implementation of a `minicore` auxiliary test helper that provides `core` stubs for `#![no_core]` ui/assembly/codegen tests that need to build but not run on both the host platform and the cross-compiled target platform.

Key summary:

- `tests/auxiliary/minicore.rs` contains stub definitions of `core` items intended for consumption by `check-pass`/`build-pass` tests that want the typical prelude items like `Copy` to be stubbed out under `#![no_core]` scenarios, so that the test can be built (not run) for cross-compiled target platforms. Such tests don't want nor need full `-Z build-std` (e.g. `tests/ui/abi/compatibility.rs`).
- `minicore` is intended for `core` items **only**, not `std`- or `alloc`-exclusive items. If stubs for `alloc` or `std` are wanted, they should be provided by an additional directive and test auxiliary, and not be conflated with `minicore` or `core` stubs. This is because a wider range of tests can benefit from `core`-only stubs.

### Implementation

- The `minicore` auxiliary is a single source file `tests/auxiliary/minicore.rs`.
- The path to `minicore` is made avaiable from bootstrap to compiletest via the `--minicore-path` compiletest flag.
- `minicore` is then built on-demand via the `//@ add-core-stubs` compiletest directive, for each test revision for the given target platform (this distinction is important for when host platform != target platform in cross-compilation scenario).
- `minicore` is then made available to the test as an [extern prelude].

[extern prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude

### Example usage

```rs
// tests/ui/abi/my-abi-test.rs

//@ check-pass
//@ add-core-stubs
//@ compile-flags: --target i686-unknown-linux-gnu
//@ needs-llvm-components: x86

#![feature(no_core, lang_items)]
#![no_std]
#![no_core]
#![allow(unused, internal_features)]

extern crate minicore;
use minicore::*;

#[lang = "clone"]
pub trait Clone: Sized {      // `Sized` is provided by `minicore`
    fn clone(&self) -> Self;
}
```

### Implementation steps

- [x] 1. Add an initial `minicore` test auxiliary.
- [x] 2. Build `minicore` in bootstrap.
- [x] 3. Setup a `--minicore-path` compiletest cli flag and pass `minicore` build artifact path from bootstrap to compiletest.
- [x] 4. Assert `add-core-stubs` is mutually incompatible with tests that require to be `run`, as the stubs are only good for tests that only need to be built (i.e. no `run-{pass,fail}`).
- [x] 5. Add some self-tests to sanity check the behavior.
- [x] 6. Ensure that `tests/auxiliary/minicore.rs` is input stamped, i.e. modifying `tests/auxiliary/minicore.rs` should invalidate test cache and force the test to be rerun.

### Known limitations

- The current `minicore` is very minimal, because this PR is intended to focus on supporting the test infrastructure first. Further stubs could be added in follow-up PRs and/or on a as-needed basis.

try-job: aarch64-apple
try-job: armhf-gnu
try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
Diffstat (limited to 'tests')
-rw-r--r--tests/assembly/compiletest-self-test/use-minicore-no-run.rs5
-rw-r--r--tests/auxiliary/minicore.rs72
-rw-r--r--tests/codegen/compiletest-self-test/minicore-smoke-test.rs20
-rw-r--r--tests/ui/abi/compatibility.rs69
-rw-r--r--tests/ui/compiletest-self-test/minicore-smoke-test.rs20
5 files changed, 131 insertions, 55 deletions
diff --git a/tests/assembly/compiletest-self-test/use-minicore-no-run.rs b/tests/assembly/compiletest-self-test/use-minicore-no-run.rs
new file mode 100644
index 00000000000..0e4f05c4b37
--- /dev/null
+++ b/tests/assembly/compiletest-self-test/use-minicore-no-run.rs
@@ -0,0 +1,5 @@
+//! `compiletest` self-test to check that `add-core-stubs` is incompatible with run pass modes.
+
+//@ add-core-stubs
+//@ run-pass
+//@ should-fail
diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs
new file mode 100644
index 00000000000..49a7580eccc
--- /dev/null
+++ b/tests/auxiliary/minicore.rs
@@ -0,0 +1,72 @@
+//! Auxiliary `minicore` prelude which stubs out `core` items for `no_core` tests that need to work
+//! in cross-compilation scenarios where no `core` is available (that don't want nor need to
+//! `-Zbuild-std`).
+//!
+//! # Important notes
+//!
+//! - `minicore` is **only** intended for `core` items, and the stubs should match the actual `core`
+//!   items.
+//!
+//! # References
+//!
+//! This is partially adapted from `rustc_codegen_cranelift`:
+//! <https://github.com/rust-lang/rust/blob/c0b5cc9003f6464c11ae1c0662c6a7e06f6f5cab/compiler/rustc_codegen_cranelift/example/mini_core.rs>.
+// ignore-tidy-linelength
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![allow(unused, improper_ctypes_definitions, internal_features)]
+#![no_std]
+#![no_core]
+
+// `core` has some exotic `marker_impls!` macro for handling the with-generics cases, but for our
+// purposes, just use a simple macro_rules macro.
+macro_rules! impl_marker_trait {
+    ($Trait:ident => [$( $ty:ident ),* $(,)?] ) => {
+        $( impl $Trait for $ty {} )*
+    }
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "legacy_receiver"]
+pub trait LegacyReceiver {}
+impl<T: ?Sized> LegacyReceiver for &T {}
+impl<T: ?Sized> LegacyReceiver for &mut T {}
+
+#[lang = "copy"]
+pub trait Copy: Sized {}
+
+impl_marker_trait!(Copy => [ bool, char, isize, usize, i8, i16, i32, i64, u8, u16, u32, u64 ]);
+impl<'a, T: ?Sized> Copy for &'a T {}
+impl<T: ?Sized> Copy for *const T {}
+impl<T: ?Sized> Copy for *mut T {}
+
+#[lang = "phantom_data"]
+pub struct PhantomData<T: ?Sized>;
+impl<T: ?Sized> Copy for PhantomData<T> {}
+
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+impl<T: Copy> Copy for Option<T> {}
+
+pub enum Result<T, E> {
+    Ok(T),
+    Err(E),
+}
+impl<T: Copy, E: Copy> Copy for Result<T, E> {}
+
+#[lang = "manually_drop"]
+#[repr(transparent)]
+pub struct ManuallyDrop<T: ?Sized> {
+    value: T,
+}
+impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {}
+
+#[lang = "unsafe_cell"]
+#[repr(transparent)]
+pub struct UnsafeCell<T: ?Sized> {
+    value: T,
+}
diff --git a/tests/codegen/compiletest-self-test/minicore-smoke-test.rs b/tests/codegen/compiletest-self-test/minicore-smoke-test.rs
new file mode 100644
index 00000000000..9dd1bf29c6c
--- /dev/null
+++ b/tests/codegen/compiletest-self-test/minicore-smoke-test.rs
@@ -0,0 +1,20 @@
+//! Basic smoke test for `minicore` test auxiliary.
+
+//@ add-core-stubs
+//@ compile-flags: --target=x86_64-unknown-linux-gnu
+//@ needs-llvm-components: x86
+
+#![crate_type = "lib"]
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+struct Meow;
+impl Copy for Meow {}
+
+// CHECK-LABEL: meow
+#[no_mangle]
+fn meow() {}
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index 408dbea4ae8..01d90717107 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -1,4 +1,5 @@
 //@ check-pass
+//@ add-core-stubs
 //@ revisions: host
 //@ revisions: i686
 //@[i686] compile-flags: --target i686-unknown-linux-gnu
@@ -58,8 +59,10 @@
 //@ revisions: nvptx64
 //@[nvptx64] compile-flags: --target nvptx64-nvidia-cuda
 //@[nvptx64] needs-llvm-components: nvptx
-#![feature(rustc_attrs, unsized_fn_params, transparent_unions)]
-#![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)]
+#![feature(no_core, rustc_attrs, lang_items)]
+#![feature(unsized_fn_params, transparent_unions)]
+#![no_std]
+#![no_core]
 #![allow(unused, improper_ctypes_definitions, internal_features)]
 
 // FIXME: some targets are broken in various ways.
@@ -67,67 +70,24 @@
 // sparc64: https://github.com/rust-lang/rust/issues/115336
 // mips64: https://github.com/rust-lang/rust/issues/115404
 
-#[cfg(host)]
-use std::{
-    any::Any, marker::PhantomData, mem::ManuallyDrop, num::NonZero, ptr::NonNull, rc::Rc, sync::Arc,
-};
+extern crate minicore;
+use minicore::*;
 
-/// To work cross-target this test must be no_core.
-/// This little prelude supplies what we need.
-#[cfg(not(host))]
+/// To work cross-target this test must be no_core. This little prelude supplies what we need.
+///
+/// Note that `minicore` provides a very minimal subset of `core` items (not yet complete). This
+/// prelude contains `alloc` and non-`core` (but in `std`) items that minicore does not stub out.
 mod prelude {
-    #[lang = "sized"]
-    pub trait Sized {}
+    use minicore::*;
 
-    #[lang = "legacy_receiver"]
-    pub trait LegacyReceiver {}
-    impl<T: ?Sized> LegacyReceiver for &T {}
-    impl<T: ?Sized> LegacyReceiver for &mut T {}
-
-    #[lang = "copy"]
-    pub trait Copy: Sized {}
-    impl Copy for i32 {}
-    impl Copy for f32 {}
-    impl<T: ?Sized> Copy for &T {}
-    impl<T: ?Sized> Copy for *const T {}
-    impl<T: ?Sized> Copy for *mut T {}
+    // Trait stub, no `type_id` method.
+    pub trait Any: 'static {}
 
     #[lang = "clone"]
     pub trait Clone: Sized {
         fn clone(&self) -> Self;
     }
 
-    #[lang = "phantom_data"]
-    pub struct PhantomData<T: ?Sized>;
-    impl<T: ?Sized> Copy for PhantomData<T> {}
-
-    #[lang = "unsafe_cell"]
-    #[repr(transparent)]
-    pub struct UnsafeCell<T: ?Sized> {
-        value: T,
-    }
-
-    pub trait Any: 'static {}
-
-    pub enum Option<T> {
-        None,
-        Some(T),
-    }
-    impl<T: Copy> Copy for Option<T> {}
-
-    pub enum Result<T, E> {
-        Ok(T),
-        Err(E),
-    }
-    impl<T: Copy, E: Copy> Copy for Result<T, E> {}
-
-    #[lang = "manually_drop"]
-    #[repr(transparent)]
-    pub struct ManuallyDrop<T: ?Sized> {
-        value: T,
-    }
-    impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {}
-
     #[repr(transparent)]
     #[rustc_layout_scalar_valid_range_start(1)]
     #[rustc_nonnull_optimization_guaranteed]
@@ -185,7 +145,6 @@ mod prelude {
         alloc: A,
     }
 }
-#[cfg(not(host))]
 use prelude::*;
 
 macro_rules! test_abi_compatible {
diff --git a/tests/ui/compiletest-self-test/minicore-smoke-test.rs b/tests/ui/compiletest-self-test/minicore-smoke-test.rs
new file mode 100644
index 00000000000..ec879f2852e
--- /dev/null
+++ b/tests/ui/compiletest-self-test/minicore-smoke-test.rs
@@ -0,0 +1,20 @@
+//! Basic smoke test for `minicore` test auxiliary.
+//!
+//! This test is duplicated between ui/codegen/assembly because they have different runtest
+//! codepaths.
+
+//@ add-core-stubs
+//@ check-pass
+//@ compile-flags: --target=x86_64-unknown-linux-gnu
+//@ needs-llvm-components: x86
+
+#![crate_type = "lib"]
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+struct Meow;
+impl Copy for Meow {}