Skip to content

Commit 27db39b

Browse files
authored
Rollup merge of #106470 - ehuss:tidy-no-wasm, r=Mark-Simulacrum
tidy: Don't include wasm32 in compiler dependency check This changes the tidy compiler dependency check so that it does not include wasm32-unknown-unknown dependencies in the PERMITTED_RUSTC_DEPENDENCIES. This just helps keep the list cleaner under the assumption that the compiler will never work on wasm32-unknown-unknown. This also fixes a bug in the check to verify there are no unused dependencies in the PERMITTED_RUSTC_DEPENDENCIES. Previously the check was verifying that the dependency was used *anywhere* in the workspace, when it should have been checking if it was used for the compiler. There's also just a little general cleanup here. For example, the old `normal_deps_of_r` function was changed a while ago to return *all* dependencies, but the function name and description wasn't updated to remove `normal_`.
2 parents 47fa7fa + 1d7d10a commit 27db39b

File tree

3 files changed

+67
-103
lines changed

3 files changed

+67
-103
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -5601,6 +5601,7 @@ dependencies = [
56015601
name = "tidy"
56025602
version = "0.1.0"
56035603
dependencies = [
5604+
"cargo-platform 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
56045605
"cargo_metadata 0.14.0",
56055606
"ignore",
56065607
"lazy_static",

Diff for: src/tools/tidy/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ autobins = false
66

77
[dependencies]
88
cargo_metadata = "0.14"
9+
cargo-platform = "0.1.2"
910
regex = "1"
1011
miropt-test-tools = { path = "../miropt-test-tools" }
1112
lazy_static = "1"

Diff for: src/tools/tidy/src/deps.rs

+65-103
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Checks the licenses of third-party dependencies.
22
3-
use cargo_metadata::{Metadata, Package, PackageId, Resolve};
4-
use std::collections::{BTreeSet, HashSet};
3+
use cargo_metadata::{DepKindInfo, Metadata, Package, PackageId};
4+
use std::collections::HashSet;
55
use std::path::Path;
66

77
/// These are licenses that are allowed for all crates, including the runtime,
@@ -98,14 +98,12 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
9898
"autocfg",
9999
"bitflags",
100100
"block-buffer",
101-
"bumpalo", // Included in Cargo's dep graph but only activated on wasm32-*-unknown.
102101
"cc",
103102
"cfg-if",
104103
"chalk-derive",
105104
"chalk-engine",
106105
"chalk-ir",
107106
"chalk-solve",
108-
"chrono",
109107
"convert_case", // dependency of derive_more
110108
"compiler_builtins",
111109
"cpufeatures",
@@ -124,11 +122,9 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
124122
"dlmalloc",
125123
"either",
126124
"ena",
127-
"env_logger",
128125
"expect-test",
129126
"fallible-iterator", // dependency of `thorin`
130127
"fastrand",
131-
"filetime",
132128
"fixedbitset",
133129
"flate2",
134130
"fluent-bundle",
@@ -142,21 +138,18 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
142138
"gsgdt",
143139
"hashbrown",
144140
"hermit-abi",
145-
"humantime",
146141
"icu_list",
147142
"icu_locid",
148143
"icu_provider",
149144
"icu_provider_adapters",
150145
"icu_provider_macros",
151-
"if_chain",
152146
"indexmap",
153147
"instant",
154148
"intl-memoizer",
155149
"intl_pluralrules",
156150
"itertools",
157151
"itoa",
158152
"jobserver",
159-
"js-sys", // Included in Cargo's dep graph but only activated on wasm32-*-unknown.
160153
"lazy_static",
161154
"libc",
162155
"libloading",
@@ -171,8 +164,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
171164
"memmap2",
172165
"memoffset",
173166
"miniz_oxide",
174-
"num-integer",
175-
"num-traits",
176167
"num_cpus",
177168
"object",
178169
"odht",
@@ -190,7 +181,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
190181
"proc-macro2",
191182
"psm",
192183
"punycode",
193-
"quick-error",
194184
"quote",
195185
"rand",
196186
"rand_chacha",
@@ -235,7 +225,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
235225
"thiserror-impl",
236226
"thorin-dwp",
237227
"thread_local",
238-
"time",
239228
"tinystr",
240229
"tinyvec",
241230
"tinyvec_macros",
@@ -268,13 +257,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
268257
"valuable",
269258
"version_check",
270259
"wasi",
271-
// vvv Included in Cargo's dep graph but only activated on wasm32-*-unknown.
272-
"wasm-bindgen",
273-
"wasm-bindgen-backend",
274-
"wasm-bindgen-macro",
275-
"wasm-bindgen-macro-support",
276-
"wasm-bindgen-shared",
277-
// ^^^ Included in Cargo's dep graph but only activated on wasm32-*-unknown.
278260
"winapi",
279261
"winapi-i686-pc-windows-gnu",
280262
"winapi-util",
@@ -485,73 +467,55 @@ fn check_permitted_dependencies(
485467
restricted_dependency_crates: &[&'static str],
486468
bad: &mut bool,
487469
) {
470+
let mut deps = HashSet::new();
471+
for to_check in restricted_dependency_crates {
472+
let to_check = pkg_from_name(metadata, to_check);
473+
use cargo_platform::Cfg;
474+
use std::str::FromStr;
475+
// We don't expect the compiler to ever run on wasm32, so strip
476+
// out those dependencies to avoid polluting the permitted list.
477+
deps_of_filtered(metadata, &to_check.id, &mut deps, &|dep_kinds| {
478+
dep_kinds.iter().any(|dep_kind| {
479+
dep_kind
480+
.target
481+
.as_ref()
482+
.map(|target| {
483+
!target.matches(
484+
"wasm32-unknown-unknown",
485+
&[
486+
Cfg::from_str("target_arch=\"wasm32\"").unwrap(),
487+
Cfg::from_str("target_os=\"unknown\"").unwrap(),
488+
],
489+
)
490+
})
491+
.unwrap_or(true)
492+
})
493+
});
494+
}
495+
488496
// Check that the PERMITTED_DEPENDENCIES does not have unused entries.
489-
for name in permitted_dependencies {
490-
if !metadata.packages.iter().any(|p| p.name == *name) {
497+
for permitted in permitted_dependencies {
498+
if !deps.iter().any(|dep_id| &pkg_from_id(metadata, dep_id).name == permitted) {
491499
tidy_error!(
492500
bad,
493-
"could not find allowed package `{}`\n\
501+
"could not find allowed package `{permitted}`\n\
494502
Remove from PERMITTED_DEPENDENCIES list if it is no longer used.",
495-
name
496503
);
497504
}
498505
}
499-
// Get the list in a convenient form.
500-
let permitted_dependencies: HashSet<_> = permitted_dependencies.iter().cloned().collect();
501-
502-
// Check dependencies.
503-
let mut visited = BTreeSet::new();
504-
let mut unapproved = BTreeSet::new();
505-
for &krate in restricted_dependency_crates.iter() {
506-
let pkg = pkg_from_name(metadata, krate);
507-
let mut bad =
508-
check_crate_dependencies(&permitted_dependencies, metadata, &mut visited, pkg);
509-
unapproved.append(&mut bad);
510-
}
511-
512-
if !unapproved.is_empty() {
513-
tidy_error!(bad, "Dependencies for {} not explicitly permitted:", descr);
514-
for dep in unapproved {
515-
println!("* {dep}");
516-
}
517-
}
518-
}
519-
520-
/// Checks the dependencies of the given crate from the given cargo metadata to see if they are on
521-
/// the list of permitted dependencies. Returns a list of disallowed dependencies.
522-
fn check_crate_dependencies<'a>(
523-
permitted_dependencies: &'a HashSet<&'static str>,
524-
metadata: &'a Metadata,
525-
visited: &mut BTreeSet<&'a PackageId>,
526-
krate: &'a Package,
527-
) -> BTreeSet<&'a PackageId> {
528-
// This will contain bad deps.
529-
let mut unapproved = BTreeSet::new();
530-
531-
// Check if we have already visited this crate.
532-
if visited.contains(&krate.id) {
533-
return unapproved;
534-
}
535506

536-
visited.insert(&krate.id);
507+
// Get in a convenient form.
508+
let permitted_dependencies: HashSet<_> = permitted_dependencies.iter().cloned().collect();
537509

538-
// If this path is in-tree, we don't require it to be explicitly permitted.
539-
if krate.source.is_some() {
540-
// If this dependency is not on `PERMITTED_DEPENDENCIES`, add to bad set.
541-
if !permitted_dependencies.contains(krate.name.as_str()) {
542-
unapproved.insert(&krate.id);
510+
for dep in deps {
511+
let dep = pkg_from_id(metadata, dep);
512+
// If this path is in-tree, we don't require it to be explicitly permitted.
513+
if dep.source.is_some() {
514+
if !permitted_dependencies.contains(dep.name.as_str()) {
515+
tidy_error!(bad, "Dependency for {descr} not explicitly permitted: {}", dep.id);
516+
}
543517
}
544518
}
545-
546-
// Do a DFS in the crate graph.
547-
let to_check = deps_of(metadata, &krate.id);
548-
549-
for dep in to_check {
550-
let mut bad = check_crate_dependencies(permitted_dependencies, metadata, visited, dep);
551-
unapproved.append(&mut bad);
552-
}
553-
554-
unapproved
555519
}
556520

557521
/// Prevents multiple versions of some expensive crates.
@@ -588,24 +552,6 @@ fn check_crate_duplicate(
588552
}
589553
}
590554

591-
/// Returns a list of dependencies for the given package.
592-
fn deps_of<'a>(metadata: &'a Metadata, pkg_id: &'a PackageId) -> Vec<&'a Package> {
593-
let resolve = metadata.resolve.as_ref().unwrap();
594-
let node = resolve
595-
.nodes
596-
.iter()
597-
.find(|n| &n.id == pkg_id)
598-
.unwrap_or_else(|| panic!("could not find `{pkg_id}` in resolve"));
599-
node.deps
600-
.iter()
601-
.map(|dep| {
602-
metadata.packages.iter().find(|pkg| pkg.id == dep.pkg).unwrap_or_else(|| {
603-
panic!("could not find dep `{}` for pkg `{}` in resolve", dep.pkg, pkg_id)
604-
})
605-
})
606-
.collect()
607-
}
608-
609555
/// Finds a package with the given name.
610556
fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package {
611557
let mut i = metadata.packages.iter().filter(|p| p.name == name);
@@ -615,41 +561,57 @@ fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package
615561
result
616562
}
617563

564+
fn pkg_from_id<'a>(metadata: &'a Metadata, id: &PackageId) -> &'a Package {
565+
metadata.packages.iter().find(|p| &p.id == id).unwrap()
566+
}
567+
618568
/// Finds all the packages that are in the rust runtime.
619569
fn compute_runtime_crates<'a>(metadata: &'a Metadata) -> HashSet<&'a PackageId> {
620-
let resolve = metadata.resolve.as_ref().unwrap();
621570
let mut result = HashSet::new();
622571
for name in RUNTIME_CRATES {
623572
let id = &pkg_from_name(metadata, name).id;
624-
normal_deps_of_r(resolve, id, &mut result);
573+
deps_of_filtered(metadata, id, &mut result, &|_| true);
625574
}
626575
result
627576
}
628577

629-
/// Recursively find all normal dependencies.
630-
fn normal_deps_of_r<'a>(
631-
resolve: &'a Resolve,
578+
/// Recursively find all dependencies.
579+
fn deps_of_filtered<'a>(
580+
metadata: &'a Metadata,
632581
pkg_id: &'a PackageId,
633582
result: &mut HashSet<&'a PackageId>,
583+
filter: &dyn Fn(&[DepKindInfo]) -> bool,
634584
) {
635585
if !result.insert(pkg_id) {
636586
return;
637587
}
638-
let node = resolve
588+
let node = metadata
589+
.resolve
590+
.as_ref()
591+
.unwrap()
639592
.nodes
640593
.iter()
641594
.find(|n| &n.id == pkg_id)
642595
.unwrap_or_else(|| panic!("could not find `{pkg_id}` in resolve"));
643596
for dep in &node.deps {
644-
normal_deps_of_r(resolve, &dep.pkg, result);
597+
if !filter(&dep.dep_kinds) {
598+
continue;
599+
}
600+
deps_of_filtered(metadata, &dep.pkg, result, filter);
645601
}
646602
}
647603

604+
fn direct_deps_of<'a>(metadata: &'a Metadata, pkg_id: &'a PackageId) -> Vec<&'a Package> {
605+
let resolve = metadata.resolve.as_ref().unwrap();
606+
let node = resolve.nodes.iter().find(|n| &n.id == pkg_id).unwrap();
607+
node.deps.iter().map(|dep| pkg_from_id(metadata, &dep.pkg)).collect()
608+
}
609+
648610
fn check_rustfix(metadata: &Metadata, bad: &mut bool) {
649611
let cargo = pkg_from_name(metadata, "cargo");
650612
let compiletest = pkg_from_name(metadata, "compiletest");
651-
let cargo_deps = deps_of(metadata, &cargo.id);
652-
let compiletest_deps = deps_of(metadata, &compiletest.id);
613+
let cargo_deps = direct_deps_of(metadata, &cargo.id);
614+
let compiletest_deps = direct_deps_of(metadata, &compiletest.id);
653615
let cargo_rustfix = cargo_deps.iter().find(|p| p.name == "rustfix").unwrap();
654616
let compiletest_rustfix = compiletest_deps.iter().find(|p| p.name == "rustfix").unwrap();
655617
if cargo_rustfix.version != compiletest_rustfix.version {

0 commit comments

Comments
 (0)