3
3
#![ feature( is_sorted) ]
4
4
#![ cfg_attr( feature = "deny-warnings" , deny( warnings) ) ]
5
5
#![ warn( rust_2018_idioms, unused_lifetimes) ]
6
+ #![ allow( unused_extern_crates) ]
6
7
7
8
use compiletest:: { status_emitter, CommandBuilder } ;
8
9
use ui_test as compiletest;
9
10
use ui_test:: Mode as TestMode ;
10
11
12
+ use std:: collections:: BTreeMap ;
11
13
use std:: env:: { self , remove_var, set_var, var_os} ;
12
14
use std:: ffi:: { OsStr , OsString } ;
13
15
use std:: fs;
14
16
use std:: path:: { Path , PathBuf } ;
17
+ use std:: sync:: LazyLock ;
15
18
use test_utils:: IS_RUSTC_TEST_SUITE ;
16
19
20
+ // Test dependencies may need an `extern crate` here to ensure that they show up
21
+ // in the depinfo file (otherwise cargo thinks they are unused)
22
+ extern crate clippy_lints;
23
+ extern crate clippy_utils;
24
+ extern crate derive_new;
25
+ extern crate futures;
26
+ extern crate if_chain;
27
+ extern crate itertools;
28
+ extern crate parking_lot;
29
+ extern crate quote;
30
+ extern crate syn;
31
+ extern crate tokio;
32
+
33
+ /// All crates used in UI tests are listed here
34
+ static TEST_DEPENDENCIES : & [ & str ] = & [
35
+ "clippy_lints" ,
36
+ "clippy_utils" ,
37
+ "derive_new" ,
38
+ "futures" ,
39
+ "if_chain" ,
40
+ "itertools" ,
41
+ "parking_lot" ,
42
+ "quote" ,
43
+ "regex" ,
44
+ "serde_derive" ,
45
+ "serde" ,
46
+ "syn" ,
47
+ "tokio" ,
48
+ ] ;
49
+
50
+ /// Produces a string with an `--extern` flag for all UI test crate
51
+ /// dependencies.
52
+ ///
53
+ /// The dependency files are located by parsing the depinfo file for this test
54
+ /// module. This assumes the `-Z binary-dep-depinfo` flag is enabled. All test
55
+ /// dependencies must be added to Cargo.toml at the project root. Test
56
+ /// dependencies that are not *directly* used by this test module require an
57
+ /// `extern crate` declaration.
58
+ static EXTERN_FLAGS : LazyLock < Vec < String > > = LazyLock :: new ( || {
59
+ let current_exe_depinfo = {
60
+ let mut path = env:: current_exe ( ) . unwrap ( ) ;
61
+ path. set_extension ( "d" ) ;
62
+ fs:: read_to_string ( path) . unwrap ( )
63
+ } ;
64
+ let mut crates = BTreeMap :: < & str , & str > :: new ( ) ;
65
+ for line in current_exe_depinfo. lines ( ) {
66
+ // each dependency is expected to have a Makefile rule like `/path/to/crate-hash.rlib:`
67
+ let parse_name_path = || {
68
+ if line. starts_with ( char:: is_whitespace) {
69
+ return None ;
70
+ }
71
+ let path_str = line. strip_suffix ( ':' ) ?;
72
+ let path = Path :: new ( path_str) ;
73
+ if !matches ! ( path. extension( ) ?. to_str( ) ?, "rlib" | "so" | "dylib" | "dll" ) {
74
+ return None ;
75
+ }
76
+ let ( name, _hash) = path. file_stem ( ) ?. to_str ( ) ?. rsplit_once ( '-' ) ?;
77
+ // the "lib" prefix is not present for dll files
78
+ let name = name. strip_prefix ( "lib" ) . unwrap_or ( name) ;
79
+ Some ( ( name, path_str) )
80
+ } ;
81
+ if let Some ( ( name, path) ) = parse_name_path ( ) {
82
+ if TEST_DEPENDENCIES . contains ( & name) {
83
+ // A dependency may be listed twice if it is available in sysroot,
84
+ // and the sysroot dependencies are listed first. As of the writing,
85
+ // this only seems to apply to if_chain.
86
+ crates. insert ( name, path) ;
87
+ }
88
+ }
89
+ }
90
+ let not_found: Vec < & str > = TEST_DEPENDENCIES
91
+ . iter ( )
92
+ . copied ( )
93
+ . filter ( |n| !crates. contains_key ( n) )
94
+ . collect ( ) ;
95
+ assert ! (
96
+ not_found. is_empty( ) ,
97
+ "dependencies not found in depinfo: {not_found:?}\n \
98
+ help: Make sure the `-Z binary-dep-depinfo` rust flag is enabled\n \
99
+ help: Try adding to dev-dependencies in Cargo.toml\n \
100
+ help: Be sure to also add `extern crate ...;` to tests/compile-test.rs",
101
+ ) ;
102
+ crates
103
+ . into_iter ( )
104
+ . map ( |( name, path) | format ! ( "--extern={name}={path}" ) )
105
+ . collect ( )
106
+ } ) ;
107
+
17
108
mod test_utils;
18
109
19
110
// whether to run internal tests or not
@@ -29,7 +120,6 @@ fn base_config(test_dir: &str) -> compiletest::Config {
29
120
} else {
30
121
compiletest:: OutputConflictHandling :: Error ( "cargo test -- -- --bless" . into ( ) )
31
122
} ,
32
- dependencies_crate_manifest_path : Some ( "clippy_test_deps/Cargo.toml" . into ( ) ) ,
33
123
target : None ,
34
124
out_dir : "target/ui_test" . into ( ) ,
35
125
..compiletest:: Config :: rustc ( Path :: new ( "tests" ) . join ( test_dir) )
@@ -44,10 +134,23 @@ fn base_config(test_dir: &str) -> compiletest::Config {
44
134
let deps_path = current_exe_path. parent ( ) . unwrap ( ) ;
45
135
let profile_path = deps_path. parent ( ) . unwrap ( ) ;
46
136
47
- config. program . args . push ( "--emit=metadata" . into ( ) ) ;
48
- config. program . args . push ( "-Aunused" . into ( ) ) ;
49
- config. program . args . push ( "-Zui-testing" . into ( ) ) ;
50
- config. program . args . push ( "-Dwarnings" . into ( ) ) ;
137
+ config. program . args . extend (
138
+ [
139
+ "--emit=metadata" ,
140
+ "-Aunused" ,
141
+ "-Zui-testing" ,
142
+ "-Dwarnings" ,
143
+ & format ! ( "-Ldependency={}" , deps_path. display( ) ) ,
144
+ ]
145
+ . map ( OsString :: from) ,
146
+ ) ;
147
+
148
+ config. program . args . extend ( EXTERN_FLAGS . iter ( ) . map ( OsString :: from) ) ;
149
+
150
+ if let Some ( host_libs) = option_env ! ( "HOST_LIBS" ) {
151
+ let dep = format ! ( "-Ldependency={}" , Path :: new( host_libs) . join( "deps" ) . display( ) ) ;
152
+ config. program . args . push ( dep. into ( ) ) ;
153
+ }
51
154
52
155
// Normalize away slashes in windows paths.
53
156
config. stderr_filter ( r"\\" , "/" ) ;
@@ -105,9 +208,7 @@ fn run_internal_tests() {
105
208
if !RUN_INTERNAL_TESTS {
106
209
return ;
107
210
}
108
- let mut config = base_config ( "ui-internal" ) ;
109
- config. dependency_builder . args . push ( "--features" . into ( ) ) ;
110
- config. dependency_builder . args . push ( "internal" . into ( ) ) ;
211
+ let config = base_config ( "ui-internal" ) ;
111
212
compiletest:: run_tests ( config) . unwrap ( ) ;
112
213
}
113
214
@@ -165,7 +266,6 @@ fn run_ui_cargo() {
165
266
. push ( ( "RUSTFLAGS" . into ( ) , Some ( "-Dwarnings" . into ( ) ) ) ) ;
166
267
// We need to do this while we still have a rustc in the `program` field.
167
268
config. fill_host_and_target ( ) . unwrap ( ) ;
168
- config. dependencies_crate_manifest_path = None ;
169
269
config. program . program . set_file_name ( if cfg ! ( windows) {
170
270
"cargo-clippy.exe"
171
271
} else {
0 commit comments