Skip to content

Commit 506803a

Browse files
authored
Unrolled build for rust-lang#139469
Rollup merge of rust-lang#139469 - jieyouxu:compiletest-supports-crate-type, r=onur-ozkan Introduce a `//@ needs-crate-type` compiletest directive The `//@ needs-crate-type: $crate_types...` directive takes a comma-separated list of crate types that the target platform must support in order for the test to be run. This allows the test writer to semantically convey that the ignore condition is based on target crate type needs, instead of using a general purpose `//@ ignore-$target` directive (often without comment). Fixes rust-lang#132309. ### Example ```rs //@ needs-crate-type: dylib (ignored on e.g. wasm32-unknown-unknown) //@ compile-flags: --crate-type=dylib fn foo() {} ``` ### Review advice - Best reviewed commit-by-commit. - The impl is not very clean, I briefly attempted to clean up the directive handling but found that more invasive changes are needed, so I'd like to not block on the cleanup for now. try-job: test-various try-job: armhf-gnu
2 parents e62d47d + c615d10 commit 506803a

16 files changed

+154
-41
lines changed

src/doc/rustc-dev-guide/src/tests/directives.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,13 @@ settings:
191191
specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8,
192192
16, ptr` will only run if it supports the comma-separated list of atomic
193193
widths.
194-
- `needs-dynamic-linking` - ignores if target does not support dynamic linking
194+
- `needs-dynamic-linking` ignores if target does not support dynamic linking
195195
(which is orthogonal to it being unable to create `dylib` and `cdylib` crate types)
196+
- `needs-crate-type` — ignores if target platform does not support one or more
197+
of the comma-delimited list of specified crate types. For example,
198+
`//@ needs-crate-type: cdylib, proc-macro` will cause the test to be ignored
199+
on `wasm32-unknown-unknown` target because the target does not support the
200+
`proc-macro` crate type.
196201

197202
The following directives will check LLVM support:
198203

src/tools/compiletest/src/common.rs

+31
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ pub struct Config {
395395

396396
pub target_cfgs: OnceLock<TargetCfgs>,
397397
pub builtin_cfg_names: OnceLock<HashSet<String>>,
398+
pub supported_crate_types: OnceLock<HashSet<String>>,
398399

399400
pub nocapture: bool,
400401

@@ -472,6 +473,11 @@ impl Config {
472473
self.builtin_cfg_names.get_or_init(|| builtin_cfg_names(self))
473474
}
474475

476+
/// Get the list of crate types that the target platform supports.
477+
pub fn supported_crate_types(&self) -> &HashSet<String> {
478+
self.supported_crate_types.get_or_init(|| supported_crate_types(self))
479+
}
480+
475481
pub fn has_threads(&self) -> bool {
476482
// Wasm targets don't have threads unless `-threads` is in the target
477483
// name, such as `wasm32-wasip1-threads`.
@@ -745,6 +751,31 @@ fn builtin_cfg_names(config: &Config) -> HashSet<String> {
745751
.collect()
746752
}
747753

754+
pub const KNOWN_CRATE_TYPES: &[&str] =
755+
&["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
756+
757+
fn supported_crate_types(config: &Config) -> HashSet<String> {
758+
let crate_types: HashSet<_> = rustc_output(
759+
config,
760+
&["--target", &config.target, "--print=supported-crate-types", "-Zunstable-options"],
761+
Default::default(),
762+
)
763+
.lines()
764+
.map(|l| l.to_string())
765+
.collect();
766+
767+
for crate_type in crate_types.iter() {
768+
assert!(
769+
KNOWN_CRATE_TYPES.contains(&crate_type.as_str()),
770+
"unexpected crate type `{}`: known crate types are {:?}",
771+
crate_type,
772+
KNOWN_CRATE_TYPES
773+
);
774+
}
775+
776+
crate_types
777+
}
778+
748779
fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
749780
let mut command = Command::new(&config.rustc_path);
750781
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));

src/tools/compiletest/src/directive-list.rs

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
133133
"min-llvm-version",
134134
"min-system-llvm-version",
135135
"needs-asm-support",
136+
"needs-crate-type",
136137
"needs-deterministic-layouts",
137138
"needs-dlltool",
138139
"needs-dynamic-linking",

src/tools/compiletest/src/header/needs.rs

+46-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use crate::common::{Config, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
1+
use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
22
use crate::header::{IgnoreDecision, llvm_has_libzstd};
33

44
pub(super) fn handle_needs(
55
cache: &CachedNeedsConditions,
66
config: &Config,
77
ln: &str,
88
) -> IgnoreDecision {
9-
// Note thet we intentionally still put the needs- prefix here to make the file show up when
9+
// Note that we intentionally still put the needs- prefix here to make the file show up when
1010
// grepping for a directive name, even though we could technically strip that.
1111
let needs = &[
1212
Need {
@@ -224,6 +224,50 @@ pub(super) fn handle_needs(
224224
}
225225
}
226226

227+
// FIXME(jieyouxu): share multi-value directive logic with `needs-target-has-atomic` above.
228+
if name == "needs-crate-type" {
229+
let Some(rest) = rest else {
230+
return IgnoreDecision::Error {
231+
message:
232+
"expected `needs-crate-type` to have a comma-separated list of crate types"
233+
.to_string(),
234+
};
235+
};
236+
237+
// Expect directive value to be a list of comma-separated crate-types.
238+
let specified_crate_types = rest
239+
.split(',')
240+
.map(|crate_type| crate_type.trim())
241+
.map(ToString::to_string)
242+
.collect::<Vec<String>>();
243+
244+
for crate_type in &specified_crate_types {
245+
if !KNOWN_CRATE_TYPES.contains(&crate_type.as_str()) {
246+
return IgnoreDecision::Error {
247+
message: format!(
248+
"unknown crate type specified in `needs-crate-type`: `{crate_type}` is not \
249+
a known crate type, known values are `{:?}`",
250+
KNOWN_CRATE_TYPES
251+
),
252+
};
253+
}
254+
}
255+
256+
let satisfies_all_crate_types = specified_crate_types
257+
.iter()
258+
.all(|specified| config.supported_crate_types().contains(specified));
259+
if satisfies_all_crate_types {
260+
return IgnoreDecision::Continue;
261+
} else {
262+
return IgnoreDecision::Ignore {
263+
reason: format!(
264+
"skipping test as target does not support all of the crate types `{:?}`",
265+
specified_crate_types
266+
),
267+
};
268+
}
269+
}
270+
227271
if !name.starts_with("needs-") {
228272
return IgnoreDecision::Continue;
229273
}

src/tools/compiletest/src/header/tests.rs

+38
Original file line numberDiff line numberDiff line change
@@ -902,3 +902,41 @@ fn test_rustc_abi() {
902902
assert!(!check_ignore(&config, "//@ ignore-rustc_abi-x86-sse2"));
903903
assert!(check_ignore(&config, "//@ only-rustc_abi-x86-sse2"));
904904
}
905+
906+
#[test]
907+
fn test_supported_crate_types() {
908+
// Basic assumptions check on under-test compiler's `--print=supported-crate-types` output based
909+
// on knowledge about the cherry-picked `x86_64-unknown-linux-gnu` and `wasm32-unknown-unknown`
910+
// targets. Also smoke tests the `needs-crate-type` directive itself.
911+
912+
use std::collections::HashSet;
913+
914+
let config = cfg().target("x86_64-unknown-linux-gnu").build();
915+
assert_eq!(
916+
config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
917+
HashSet::from(["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"]),
918+
);
919+
assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
920+
assert!(!check_ignore(&config, "//@ needs-crate-type: dylib"));
921+
assert!(!check_ignore(
922+
&config,
923+
"//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
924+
));
925+
926+
let config = cfg().target("wasm32-unknown-unknown").build();
927+
assert_eq!(
928+
config.supported_crate_types().iter().map(String::as_str).collect::<HashSet<_>>(),
929+
HashSet::from(["bin", "cdylib", "lib", "rlib", "staticlib"]),
930+
);
931+
932+
// rlib is supported
933+
assert!(!check_ignore(&config, "//@ needs-crate-type: rlib"));
934+
// dylib is not
935+
assert!(check_ignore(&config, "//@ needs-crate-type: dylib"));
936+
// If multiple crate types are specified, then all specified crate types need to be supported.
937+
assert!(check_ignore(&config, "//@ needs-crate-type: cdylib, dylib"));
938+
assert!(check_ignore(
939+
&config,
940+
"//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
941+
));
942+
}

src/tools/compiletest/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
431431

432432
target_cfgs: OnceLock::new(),
433433
builtin_cfg_names: OnceLock::new(),
434+
supported_crate_types: OnceLock::new(),
434435

435436
nocapture: matches.opt_present("no-capture"),
436437

tests/ui/invalid-compile-flags/crate-type-flag.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
//!
44
//! This test does not try to check if the output artifacts are valid.
55
6-
// FIXME(#132309): add a proper `supports-crate-type` directive.
7-
86
// Single valid crate types should pass
97
//@ revisions: lib rlib staticlib dylib cdylib bin proc_dash_macro
108

@@ -17,19 +15,18 @@
1715
//@[staticlib] compile-flags: --crate-type=staticlib
1816
//@[staticlib] check-pass
1917

20-
//@[dylib] ignore-musl (dylib is supported, but musl libc is statically linked by default)
21-
//@[dylib] ignore-wasm (dylib is not supported)
18+
//@[dylib] needs-crate-type: dylib
2219
//@[dylib] compile-flags: --crate-type=dylib
2320
//@[dylib] check-pass
2421

25-
//@[cdylib] ignore-musl (cdylib is supported, but musl libc is statically linked by default)
22+
//@[cdylib] needs-crate-type: cdylib
2623
//@[cdylib] compile-flags: --crate-type=cdylib
2724
//@[cdylib] check-pass
2825

2926
//@[bin] compile-flags: --crate-type=bin
3027
//@[bin] check-pass
3128

32-
//@[proc_dash_macro] ignore-wasm (proc-macro is not supported)
29+
//@[proc_dash_macro] needs-crate-type: proc-macro
3330
//@[proc_dash_macro] needs-unwind (panic=abort causes warning to be emitted)
3431
//@[proc_dash_macro] compile-flags: --crate-type=proc-macro
3532
//@[proc_dash_macro] check-pass

tests/ui/linkage-attr/issue-12133-3.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
//@ aux-build:issue-12133-rlib.rs
33
//@ aux-build:issue-12133-dylib.rs
44
//@ aux-build:issue-12133-dylib2.rs
5-
//@ ignore-wasm32 no dylib support
6-
//@ ignore-musl
5+
//@ needs-crate-type: dylib
76
//@ needs-dynamic-linking
87

98

tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: crate `NonSnakeCase` should have a snake case name
2-
--> $DIR/lint-non-snake-case-crate.rs:36:18
2+
--> $DIR/lint-non-snake-case-crate.rs:35:18
33
|
44
LL | #![crate_name = "NonSnakeCase"]
55
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
66
|
77
note: the lint level is defined here
8-
--> $DIR/lint-non-snake-case-crate.rs:38:9
8+
--> $DIR/lint-non-snake-case-crate.rs:37:9
99
|
1010
LL | #![deny(non_snake_case)]
1111
| ^^^^^^^^^^^^^^

tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: crate `NonSnakeCase` should have a snake case name
2-
--> $DIR/lint-non-snake-case-crate.rs:36:18
2+
--> $DIR/lint-non-snake-case-crate.rs:35:18
33
|
44
LL | #![crate_name = "NonSnakeCase"]
55
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
66
|
77
note: the lint level is defined here
8-
--> $DIR/lint-non-snake-case-crate.rs:38:9
8+
--> $DIR/lint-non-snake-case-crate.rs:37:9
99
|
1010
LL | #![deny(non_snake_case)]
1111
| ^^^^^^^^^^^^^^

tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: crate `NonSnakeCase` should have a snake case name
2-
--> $DIR/lint-non-snake-case-crate.rs:36:18
2+
--> $DIR/lint-non-snake-case-crate.rs:35:18
33
|
44
LL | #![crate_name = "NonSnakeCase"]
55
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
66
|
77
note: the lint level is defined here
8-
--> $DIR/lint-non-snake-case-crate.rs:38:9
8+
--> $DIR/lint-non-snake-case-crate.rs:37:9
99
|
1010
LL | #![deny(non_snake_case)]
1111
| ^^^^^^^^^^^^^^

tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: crate `NonSnakeCase` should have a snake case name
2-
--> $DIR/lint-non-snake-case-crate.rs:36:18
2+
--> $DIR/lint-non-snake-case-crate.rs:35:18
33
|
44
LL | #![crate_name = "NonSnakeCase"]
55
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
66
|
77
note: the lint level is defined here
8-
--> $DIR/lint-non-snake-case-crate.rs:38:9
8+
--> $DIR/lint-non-snake-case-crate.rs:37:9
99
|
1010
LL | #![deny(non_snake_case)]
1111
| ^^^^^^^^^^^^^^

tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: crate `NonSnakeCase` should have a snake case name
2-
--> $DIR/lint-non-snake-case-crate.rs:36:18
2+
--> $DIR/lint-non-snake-case-crate.rs:35:18
33
|
44
LL | #![crate_name = "NonSnakeCase"]
55
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
66
|
77
note: the lint level is defined here
8-
--> $DIR/lint-non-snake-case-crate.rs:38:9
8+
--> $DIR/lint-non-snake-case-crate.rs:37:9
99
|
1010
LL | #![deny(non_snake_case)]
1111
| ^^^^^^^^^^^^^^

tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,27 @@
1010

1111
// But should fire on non-binary crates.
1212

13-
// FIXME(#132309): dylib crate type is not supported on wasm; we need a proper
14-
// supports-crate-type directive. Also, needs-dynamic-linking should rule out
15-
// musl since it supports neither dylibs nor cdylibs.
16-
//@[dylib_] ignore-wasm
17-
//@[dylib_] ignore-musl
18-
//@[cdylib_] ignore-musl
19-
20-
//@[dylib_] needs-dynamic-linking
13+
//@[cdylib_] compile-flags: --crate-type=cdylib
2114
//@[cdylib_] needs-dynamic-linking
22-
//@[proc_macro_] force-host
23-
//@[proc_macro_] no-prefer-dynamic
15+
//@[cdylib_] needs-crate-type: cdylib
2416

25-
//@[cdylib_] compile-flags: --crate-type=cdylib
2617
//@[dylib_] compile-flags: --crate-type=dylib
18+
//@[dylib_] needs-dynamic-linking
19+
//@[dylib_] needs-crate-type: dylib
20+
2721
//@[lib_] compile-flags: --crate-type=lib
22+
23+
//@[proc_macro_] force-host
24+
//@[proc_macro_] no-prefer-dynamic
2825
//@[proc_macro_] compile-flags: --crate-type=proc-macro
26+
// The compiler may emit a warning that causes stderr output that contains a warning this test does
27+
// not wish to check.
28+
//@[proc_macro_] needs-unwind
29+
//@[proc_macro_] needs-crate-type: proc-macro
30+
2931
//@[rlib_] compile-flags: --crate-type=rlib
30-
//@[staticlib_] compile-flags: --crate-type=staticlib
3132

32-
// The compiler may emit a warning that causes stderr output
33-
// that contains a warning this test does not wish to check.
34-
//@[proc_macro_] needs-unwind
33+
//@[staticlib_] compile-flags: --crate-type=staticlib
3534

3635
#![crate_name = "NonSnakeCase"]
3736
//[cdylib_,dylib_,lib_,proc_macro_,rlib_,staticlib_]~^ ERROR crate `NonSnakeCase` should have a snake case name

tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: crate `NonSnakeCase` should have a snake case name
2-
--> $DIR/lint-non-snake-case-crate.rs:36:18
2+
--> $DIR/lint-non-snake-case-crate.rs:35:18
33
|
44
LL | #![crate_name = "NonSnakeCase"]
55
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
66
|
77
note: the lint level is defined here
8-
--> $DIR/lint-non-snake-case-crate.rs:38:9
8+
--> $DIR/lint-non-snake-case-crate.rs:37:9
99
|
1010
LL | #![deny(non_snake_case)]
1111
| ^^^^^^^^^^^^^^

tests/ui/panic-runtime/abort-link-to-unwind-dylib.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
//@ build-fail
22
//@ compile-flags:-C panic=abort -C prefer-dynamic
33
//@ needs-unwind
4-
//@ ignore-musl - no dylibs here
5-
//@ ignore-emscripten
6-
//@ ignore-sgx no dynamic lib support
4+
//@ needs-crate-type: dylib
75

86
// This is a test where the local crate, compiled with `panic=abort`, links to
97
// the standard library **dynamically** which is already linked against

0 commit comments

Comments
 (0)