Auto merge of #146572 - matthiaskrgr:rollup-gotklb6, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang/rust#143314 (add reference id to test, and fix filename) - rust-lang/rust#146284 (Remove `div_rem` from `core::num::bignum`) - rust-lang/rust#146416 (Tidy dependency checks cleanups + QoL) - rust-lang/rust#146471 (bootstrap: Show target in "No such target exists" message) - rust-lang/rust#146478 (Improve `core::fmt` coverage) - rust-lang/rust#146480 (tests: update new test to accept new lifetime format) - rust-lang/rust#146488 (Improve `core::ptr` coverage) - rust-lang/rust#146501 (compiletest: Fix `--exact` test filtering) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d1ed52b1f5
16 changed files with 261 additions and 116 deletions
|
|
@ -335,43 +335,6 @@ macro_rules! define_bignum {
|
|||
}
|
||||
(self, borrow)
|
||||
}
|
||||
|
||||
/// Divide self by another bignum, overwriting `q` with the quotient and `r` with the
|
||||
/// remainder.
|
||||
pub fn div_rem(&self, d: &$name, q: &mut $name, r: &mut $name) {
|
||||
// Stupid slow base-2 long division taken from
|
||||
// https://en.wikipedia.org/wiki/Division_algorithm
|
||||
// FIXME use a greater base ($ty) for the long division.
|
||||
assert!(!d.is_zero());
|
||||
let digitbits = <$ty>::BITS as usize;
|
||||
for digit in &mut q.base[..] {
|
||||
*digit = 0;
|
||||
}
|
||||
for digit in &mut r.base[..] {
|
||||
*digit = 0;
|
||||
}
|
||||
r.size = d.size;
|
||||
q.size = 1;
|
||||
let mut q_is_zero = true;
|
||||
let end = self.bit_length();
|
||||
for i in (0..end).rev() {
|
||||
r.mul_pow2(1);
|
||||
r.base[0] |= self.get_bit(i) as $ty;
|
||||
if &*r >= d {
|
||||
r.sub(d);
|
||||
// Set bit `i` of q to 1.
|
||||
let digit_idx = i / digitbits;
|
||||
let bit_idx = i % digitbits;
|
||||
if q_is_zero {
|
||||
q.size = digit_idx + 1;
|
||||
q_is_zero = false;
|
||||
}
|
||||
q.base[digit_idx] |= 1 << bit_idx;
|
||||
}
|
||||
}
|
||||
debug_assert!(q.base[q.size..].iter().all(|&d| d == 0));
|
||||
debug_assert!(r.base[r.size..].iter().all(|&d| d == 0));
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::cmp::PartialEq for $name {
|
||||
|
|
|
|||
|
|
@ -173,6 +173,21 @@ mod debug_struct {
|
|||
format!("{Bar:#?}")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_field_with() {
|
||||
struct Foo;
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt.debug_struct("Foo")
|
||||
.field_with("bar", |f| f.write_str("true"))
|
||||
.field_with("baz", |f| f.write_str("false"))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Foo {\n bar: true,\n baz: false,\n}", format!("{Foo:#?}"))
|
||||
}
|
||||
}
|
||||
|
||||
mod debug_tuple {
|
||||
|
|
|
|||
|
|
@ -57,6 +57,36 @@ fn test_fmt_debug_of_raw_pointers() {
|
|||
check_fmt(vtable as *const dyn Debug, "Pointer { addr: ", ", metadata: DynMetadata(");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt_debug_of_mut_reference() {
|
||||
let mut x: u32 = 0;
|
||||
|
||||
assert_eq!(format!("{:?}", &mut x), "0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_write_impls() {
|
||||
use core::fmt::Write;
|
||||
|
||||
struct Buf(String);
|
||||
|
||||
impl Write for Buf {
|
||||
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||
self.0.write_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
let mut buf = Buf(String::new());
|
||||
buf.write_char('a').unwrap();
|
||||
|
||||
assert_eq!(buf.0, "a");
|
||||
|
||||
let mut buf = Buf(String::new());
|
||||
buf.write_fmt(format_args!("a")).unwrap();
|
||||
|
||||
assert_eq!(buf.0, "a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimated_capacity() {
|
||||
assert_eq!(format_args!("").estimated_capacity(), 0);
|
||||
|
|
|
|||
|
|
@ -323,3 +323,9 @@ fn test_format_debug_hex() {
|
|||
assert_eq!(format!("{:02x?}", b"Foo\0"), "[46, 6f, 6f, 00]");
|
||||
assert_eq!(format!("{:02X?}", b"Foo\0"), "[46, 6F, 6F, 00]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Formatting argument out of range"]
|
||||
fn test_rt_width_too_long() {
|
||||
let _ = format!("Hello {:width$}!", "x", width = u16::MAX as usize + 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#![feature(core_private_bignum)]
|
||||
#![feature(core_private_diy_float)]
|
||||
#![feature(cstr_display)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(dec2flt)]
|
||||
#![feature(drop_guard)]
|
||||
#![feature(duration_constants)]
|
||||
|
|
|
|||
|
|
@ -167,25 +167,6 @@ fn test_div_rem_small() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_div_rem() {
|
||||
fn div_rem(n: u64, d: u64) -> (Big, Big) {
|
||||
let mut q = Big::from_small(42);
|
||||
let mut r = Big::from_small(42);
|
||||
Big::from_u64(n).div_rem(&Big::from_u64(d), &mut q, &mut r);
|
||||
(q, r)
|
||||
}
|
||||
assert_eq!(div_rem(1, 1), (Big::from_small(1), Big::from_small(0)));
|
||||
assert_eq!(div_rem(4, 3), (Big::from_small(1), Big::from_small(1)));
|
||||
assert_eq!(div_rem(1, 7), (Big::from_small(0), Big::from_small(1)));
|
||||
assert_eq!(div_rem(45, 9), (Big::from_small(5), Big::from_small(0)));
|
||||
assert_eq!(div_rem(103, 9), (Big::from_small(11), Big::from_small(4)));
|
||||
assert_eq!(div_rem(123456, 77), (Big::from_u64(1603), Big::from_small(25)));
|
||||
assert_eq!(div_rem(0xffff, 1), (Big::from_u64(0xffff), Big::from_small(0)));
|
||||
assert_eq!(div_rem(0xeeee, 0xffff), (Big::from_small(0), Big::from_u64(0xeeee)));
|
||||
assert_eq!(div_rem(2_000_000, 2), (Big::from_u64(1_000_000), Big::from_u64(0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_zero() {
|
||||
assert!(Big::from_small(0).is_zero());
|
||||
|
|
|
|||
|
|
@ -489,6 +489,14 @@ fn is_aligned() {
|
|||
assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "is_aligned_to: align is not a power-of-two"]
|
||||
fn invalid_is_aligned() {
|
||||
let data = 42;
|
||||
let ptr: *const i32 = &data;
|
||||
assert!(ptr.is_aligned_to(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn offset_from() {
|
||||
let mut a = [0; 5];
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ than building it.
|
|||
|
||||
if !has_target {
|
||||
panic!(
|
||||
"No such target exists in the target list,\n\
|
||||
"{target_str}: No such target exists in the target list,\n\
|
||||
make sure to correctly specify the location \
|
||||
of the JSON specification file \
|
||||
for custom targets!\n\
|
||||
|
|
|
|||
|
|
@ -1446,6 +1446,7 @@ pub(crate) fn make_test_description<R: Read>(
|
|||
cache: &DirectivesCache,
|
||||
name: String,
|
||||
path: &Utf8Path,
|
||||
filterable_path: &Utf8Path,
|
||||
src: R,
|
||||
test_revision: Option<&str>,
|
||||
poisoned: &mut bool,
|
||||
|
|
@ -1520,7 +1521,13 @@ pub(crate) fn make_test_description<R: Read>(
|
|||
_ => ShouldPanic::No,
|
||||
};
|
||||
|
||||
CollectedTestDesc { name, ignore, ignore_message, should_panic }
|
||||
CollectedTestDesc {
|
||||
name,
|
||||
filterable_path: filterable_path.to_owned(),
|
||||
ignore,
|
||||
ignore_message,
|
||||
should_panic,
|
||||
}
|
||||
}
|
||||
|
||||
fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ fn make_test_description<R: Read>(
|
|||
config: &Config,
|
||||
name: String,
|
||||
path: &Utf8Path,
|
||||
filterable_path: &Utf8Path,
|
||||
src: R,
|
||||
revision: Option<&str>,
|
||||
) -> CollectedTestDesc {
|
||||
|
|
@ -24,6 +25,7 @@ fn make_test_description<R: Read>(
|
|||
&cache,
|
||||
name,
|
||||
path,
|
||||
filterable_path,
|
||||
src,
|
||||
revision,
|
||||
&mut poisoned,
|
||||
|
|
@ -221,7 +223,7 @@ fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
|
|||
fn check_ignore(config: &Config, contents: &str) -> bool {
|
||||
let tn = String::new();
|
||||
let p = Utf8Path::new("a.rs");
|
||||
let d = make_test_description(&config, tn, p, std::io::Cursor::new(contents), None);
|
||||
let d = make_test_description(&config, tn, p, p, std::io::Cursor::new(contents), None);
|
||||
d.ignore
|
||||
}
|
||||
|
||||
|
|
@ -231,9 +233,9 @@ fn should_fail() {
|
|||
let tn = String::new();
|
||||
let p = Utf8Path::new("a.rs");
|
||||
|
||||
let d = make_test_description(&config, tn.clone(), p, std::io::Cursor::new(""), None);
|
||||
let d = make_test_description(&config, tn.clone(), p, p, std::io::Cursor::new(""), None);
|
||||
assert_eq!(d.should_panic, ShouldPanic::No);
|
||||
let d = make_test_description(&config, tn, p, std::io::Cursor::new("//@ should-fail"), None);
|
||||
let d = make_test_description(&config, tn, p, p, std::io::Cursor::new("//@ should-fail"), None);
|
||||
assert_eq!(d.should_panic, ShouldPanic::Yes);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ use std::num::NonZero;
|
|||
use std::sync::{Arc, Mutex, mpsc};
|
||||
use std::{env, hint, io, mem, panic, thread};
|
||||
|
||||
use camino::Utf8PathBuf;
|
||||
|
||||
use crate::common::{Config, TestPaths};
|
||||
use crate::output_capture::{self, ConsoleOut};
|
||||
use crate::panic_hook;
|
||||
|
|
@ -293,8 +295,12 @@ fn filter_tests(opts: &Config, tests: Vec<CollectedTest>) -> Vec<CollectedTest>
|
|||
let mut filtered = tests;
|
||||
|
||||
let matches_filter = |test: &CollectedTest, filter_str: &str| {
|
||||
let test_name = &test.desc.name;
|
||||
if opts.filter_exact { test_name == filter_str } else { test_name.contains(filter_str) }
|
||||
let filterable_path = test.desc.filterable_path.as_str();
|
||||
if opts.filter_exact {
|
||||
filterable_path == filter_str
|
||||
} else {
|
||||
filterable_path.contains(filter_str)
|
||||
}
|
||||
};
|
||||
|
||||
// Remove tests that don't match the test filter
|
||||
|
|
@ -339,6 +345,7 @@ pub(crate) struct CollectedTest {
|
|||
/// Information that was historically needed to create a libtest `TestDesc`.
|
||||
pub(crate) struct CollectedTestDesc {
|
||||
pub(crate) name: String,
|
||||
pub(crate) filterable_path: Utf8PathBuf,
|
||||
pub(crate) ignore: bool,
|
||||
pub(crate) ignore_message: Option<Cow<'static, str>>,
|
||||
pub(crate) should_panic: ShouldPanic,
|
||||
|
|
|
|||
|
|
@ -317,11 +317,17 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
.free
|
||||
.iter()
|
||||
.map(|f| {
|
||||
// Here `f` is relative to `./tests/run-make`. So if you run
|
||||
//
|
||||
// ./x test tests/run-make/crate-loading
|
||||
//
|
||||
// then `f` is "crate-loading".
|
||||
let path = Utf8Path::new(f);
|
||||
let mut iter = path.iter().skip(1);
|
||||
|
||||
// We skip the test folder and check if the user passed `rmake.rs`.
|
||||
if iter.next().is_some_and(|s| s == "rmake.rs") && iter.next().is_none() {
|
||||
// Strip the "rmake.rs" suffix. For example, if `f` is
|
||||
// "crate-loading/rmake.rs" then this gives us "crate-loading".
|
||||
path.parent().unwrap().to_string()
|
||||
} else {
|
||||
f.to_string()
|
||||
|
|
@ -329,6 +335,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
})
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
// Note that the filters are relative to the root dir of the different test
|
||||
// suites. For example, with:
|
||||
//
|
||||
// ./x test tests/ui/lint/unused
|
||||
//
|
||||
// the filter is "lint/unused".
|
||||
matches.free.clone()
|
||||
};
|
||||
let compare_mode = matches.opt_str("compare-mode").map(|s| {
|
||||
|
|
@ -911,7 +923,8 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
|
|||
collector.tests.extend(revisions.into_iter().map(|revision| {
|
||||
// Create a test name and description to hand over to the executor.
|
||||
let src_file = fs::File::open(&test_path).expect("open test file to parse ignores");
|
||||
let test_name = make_test_name(&cx.config, testpaths, revision);
|
||||
let (test_name, filterable_path) =
|
||||
make_test_name_and_filterable_path(&cx.config, testpaths, revision);
|
||||
// Create a description struct for the test/revision.
|
||||
// This is where `ignore-*`/`only-*`/`needs-*` directives are handled,
|
||||
// because they historically needed to set the libtest ignored flag.
|
||||
|
|
@ -920,6 +933,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
|
|||
&cx.cache,
|
||||
test_name,
|
||||
&test_path,
|
||||
&filterable_path,
|
||||
src_file,
|
||||
revision,
|
||||
&mut collector.poisoned,
|
||||
|
|
@ -1072,7 +1086,11 @@ impl Stamp {
|
|||
}
|
||||
|
||||
/// Creates a name for this test/revision that can be handed over to the executor.
|
||||
fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> String {
|
||||
fn make_test_name_and_filterable_path(
|
||||
config: &Config,
|
||||
testpaths: &TestPaths,
|
||||
revision: Option<&str>,
|
||||
) -> (String, Utf8PathBuf) {
|
||||
// Print the name of the file, relative to the sources root.
|
||||
let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
|
||||
let debugger = match config.debugger {
|
||||
|
|
@ -1084,14 +1102,23 @@ fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>
|
|||
None => String::new(),
|
||||
};
|
||||
|
||||
format!(
|
||||
let name = format!(
|
||||
"[{}{}{}] {}{}",
|
||||
config.mode,
|
||||
debugger,
|
||||
mode_suffix,
|
||||
path,
|
||||
revision.map_or("".to_string(), |rev| format!("#{}", rev))
|
||||
)
|
||||
);
|
||||
|
||||
// `path` is the full path from the repo root like, `tests/ui/foo/bar.rs`.
|
||||
// Filtering is applied without the `tests/ui/` part, so strip that off.
|
||||
// First strip off "tests" to make sure we don't have some unexpected path.
|
||||
let mut filterable_path = path.strip_prefix("tests").unwrap().to_owned();
|
||||
// Now strip off e.g. "ui" or "run-make" component.
|
||||
filterable_path = filterable_path.components().skip(1).collect();
|
||||
|
||||
(name, filterable_path)
|
||||
}
|
||||
|
||||
/// Checks that test discovery didn't find any tests whose name stem is a prefix
|
||||
|
|
|
|||
|
|
@ -48,40 +48,116 @@ const LICENSES: &[&str] = &[
|
|||
|
||||
type ExceptionList = &'static [(&'static str, &'static str)];
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct WorkspaceInfo<'a> {
|
||||
/// Path to the directory containing the workspace root Cargo.toml file.
|
||||
pub(crate) path: &'a str,
|
||||
/// The list of license exceptions.
|
||||
pub(crate) exceptions: ExceptionList,
|
||||
/// Optionally:
|
||||
/// * A list of crates for which dependencies need to be explicitly allowed.
|
||||
/// * The list of allowed dependencies.
|
||||
/// * The source code location of the allowed dependencies list
|
||||
crates_and_deps: Option<(&'a [&'a str], &'a [&'a str], ListLocation)>,
|
||||
/// Submodules required for the workspace
|
||||
pub(crate) submodules: &'a [&'a str],
|
||||
}
|
||||
|
||||
/// The workspaces to check for licensing and optionally permitted dependencies.
|
||||
///
|
||||
/// Each entry consists of a tuple with the following elements:
|
||||
///
|
||||
/// * The path to the workspace root Cargo.toml file.
|
||||
/// * The list of license exceptions.
|
||||
/// * Optionally a tuple of:
|
||||
/// * A list of crates for which dependencies need to be explicitly allowed.
|
||||
/// * The list of allowed dependencies.
|
||||
/// * Submodules required for the workspace.
|
||||
// FIXME auto detect all cargo workspaces
|
||||
pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, &[&str])] = &[
|
||||
pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[
|
||||
// The root workspace has to be first for check_rustfix to work.
|
||||
(".", EXCEPTIONS, Some((&["rustc-main"], PERMITTED_RUSTC_DEPENDENCIES)), &[]),
|
||||
("library", EXCEPTIONS_STDLIB, Some((&["sysroot"], PERMITTED_STDLIB_DEPENDENCIES)), &[]),
|
||||
// Outside of the alphabetical section because rustfmt formats it using multiple lines.
|
||||
(
|
||||
"compiler/rustc_codegen_cranelift",
|
||||
EXCEPTIONS_CRANELIFT,
|
||||
Some((&["rustc_codegen_cranelift"], PERMITTED_CRANELIFT_DEPENDENCIES)),
|
||||
&[],
|
||||
),
|
||||
// tidy-alphabetical-start
|
||||
("compiler/rustc_codegen_gcc", EXCEPTIONS_GCC, None, &[]),
|
||||
("src/bootstrap", EXCEPTIONS_BOOTSTRAP, None, &[]),
|
||||
("src/tools/cargo", EXCEPTIONS_CARGO, None, &["src/tools/cargo"]),
|
||||
//("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored
|
||||
//("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored
|
||||
("src/tools/rust-analyzer", EXCEPTIONS_RUST_ANALYZER, None, &[]),
|
||||
("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book", "src/doc/reference"]),
|
||||
("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None, &["src/tools/rustc-perf"]),
|
||||
("src/tools/test-float-parse", EXCEPTIONS, None, &[]),
|
||||
("tests/run-make-cargo/uefi-qemu/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]),
|
||||
// tidy-alphabetical-end
|
||||
WorkspaceInfo {
|
||||
path: ".",
|
||||
exceptions: EXCEPTIONS,
|
||||
crates_and_deps: Some((
|
||||
&["rustc-main"],
|
||||
PERMITTED_RUSTC_DEPENDENCIES,
|
||||
PERMITTED_RUSTC_DEPS_LOCATION,
|
||||
)),
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "library",
|
||||
exceptions: EXCEPTIONS_STDLIB,
|
||||
crates_and_deps: Some((
|
||||
&["sysroot"],
|
||||
PERMITTED_STDLIB_DEPENDENCIES,
|
||||
PERMITTED_STDLIB_DEPS_LOCATION,
|
||||
)),
|
||||
submodules: &[],
|
||||
},
|
||||
{
|
||||
WorkspaceInfo {
|
||||
path: "compiler/rustc_codegen_cranelift",
|
||||
exceptions: EXCEPTIONS_CRANELIFT,
|
||||
crates_and_deps: Some((
|
||||
&["rustc_codegen_cranelift"],
|
||||
PERMITTED_CRANELIFT_DEPENDENCIES,
|
||||
PERMITTED_CRANELIFT_DEPS_LOCATION,
|
||||
)),
|
||||
submodules: &[],
|
||||
}
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "compiler/rustc_codegen_gcc",
|
||||
exceptions: EXCEPTIONS_GCC,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/bootstrap",
|
||||
exceptions: EXCEPTIONS_BOOTSTRAP,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/cargo",
|
||||
exceptions: EXCEPTIONS_CARGO,
|
||||
crates_and_deps: None,
|
||||
submodules: &["src/tools/cargo"],
|
||||
},
|
||||
// FIXME uncomment once all deps are vendored
|
||||
// WorkspaceInfo {
|
||||
// path: "src/tools/miri/test-cargo-miri",
|
||||
// crates_and_deps: None
|
||||
// submodules: &[],
|
||||
// },
|
||||
// WorkspaceInfo {
|
||||
// path: "src/tools/miri/test_dependencies",
|
||||
// crates_and_deps: None,
|
||||
// submodules: &[],
|
||||
// }
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/rust-analyzer",
|
||||
exceptions: EXCEPTIONS_RUST_ANALYZER,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/rustbook",
|
||||
exceptions: EXCEPTIONS_RUSTBOOK,
|
||||
crates_and_deps: None,
|
||||
submodules: &["src/doc/book", "src/doc/reference"],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/rustc-perf",
|
||||
exceptions: EXCEPTIONS_RUSTC_PERF,
|
||||
crates_and_deps: None,
|
||||
submodules: &["src/tools/rustc-perf"],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "src/tools/test-float-parse",
|
||||
exceptions: EXCEPTIONS,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
WorkspaceInfo {
|
||||
path: "tests/run-make-cargo/uefi-qemu/uefi_qemu_test",
|
||||
exceptions: EXCEPTIONS_UEFI_QEMU_TEST,
|
||||
crates_and_deps: None,
|
||||
submodules: &[],
|
||||
},
|
||||
];
|
||||
|
||||
/// These are exceptions to Rust's permissive licensing policy, and
|
||||
|
|
@ -226,7 +302,20 @@ const EXCEPTIONS_UEFI_QEMU_TEST: ExceptionList = &[
|
|||
("r-efi", "MIT OR Apache-2.0 OR LGPL-2.1-or-later"), // LGPL is not acceptable, but we use it under MIT OR Apache-2.0
|
||||
];
|
||||
|
||||
const PERMITTED_DEPS_LOCATION: &str = concat!(file!(), ":", line!());
|
||||
#[derive(Clone, Copy)]
|
||||
struct ListLocation {
|
||||
path: &'static str,
|
||||
line: u32,
|
||||
}
|
||||
|
||||
/// Creates a [`ListLocation`] for the current location (with an additional offset to the actual list start);
|
||||
macro_rules! location {
|
||||
(+ $offset:literal) => {
|
||||
ListLocation { path: file!(), line: line!() + $offset }
|
||||
};
|
||||
}
|
||||
|
||||
const PERMITTED_RUSTC_DEPS_LOCATION: ListLocation = location!(+6);
|
||||
|
||||
/// Crates rustc is allowed to depend on. Avoid adding to the list if possible.
|
||||
///
|
||||
|
|
@ -458,6 +547,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
|||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
const PERMITTED_STDLIB_DEPS_LOCATION: ListLocation = location!(+2);
|
||||
|
||||
const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
"addr2line",
|
||||
|
|
@ -499,6 +590,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
|
|||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
const PERMITTED_CRANELIFT_DEPS_LOCATION: ListLocation = location!(+2);
|
||||
|
||||
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
"allocator-api2",
|
||||
|
|
@ -573,29 +666,30 @@ pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) {
|
|||
|
||||
check_proc_macro_dep_list(root, cargo, bless, bad);
|
||||
|
||||
for &(workspace, exceptions, permitted_deps, submodules) in WORKSPACES {
|
||||
for &WorkspaceInfo { path, exceptions, crates_and_deps, submodules } in WORKSPACES {
|
||||
if has_missing_submodule(root, submodules) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !root.join(workspace).join("Cargo.lock").exists() {
|
||||
tidy_error!(bad, "the `{workspace}` workspace doesn't have a Cargo.lock");
|
||||
if !root.join(path).join("Cargo.lock").exists() {
|
||||
tidy_error!(bad, "the `{path}` workspace doesn't have a Cargo.lock");
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut cmd = cargo_metadata::MetadataCommand::new();
|
||||
cmd.cargo_path(cargo)
|
||||
.manifest_path(root.join(workspace).join("Cargo.toml"))
|
||||
.manifest_path(root.join(path).join("Cargo.toml"))
|
||||
.features(cargo_metadata::CargoOpt::AllFeatures)
|
||||
.other_options(vec!["--locked".to_owned()]);
|
||||
let metadata = t!(cmd.exec());
|
||||
|
||||
check_license_exceptions(&metadata, workspace, exceptions, bad);
|
||||
if let Some((crates, permitted_deps)) = permitted_deps {
|
||||
check_permitted_dependencies(&metadata, workspace, permitted_deps, crates, bad);
|
||||
check_license_exceptions(&metadata, path, exceptions, bad);
|
||||
if let Some((crates, permitted_deps, location)) = crates_and_deps {
|
||||
let descr = crates.get(0).unwrap_or(&path);
|
||||
check_permitted_dependencies(&metadata, descr, permitted_deps, crates, location, bad);
|
||||
}
|
||||
|
||||
if workspace == "library" {
|
||||
if path == "library" {
|
||||
check_runtime_license_exceptions(&metadata, bad);
|
||||
check_runtime_no_duplicate_dependencies(&metadata, bad);
|
||||
check_runtime_no_proc_macros(&metadata, bad);
|
||||
|
|
@ -840,6 +934,7 @@ fn check_permitted_dependencies(
|
|||
descr: &str,
|
||||
permitted_dependencies: &[&'static str],
|
||||
restricted_dependency_crates: &[&'static str],
|
||||
permitted_location: ListLocation,
|
||||
bad: &mut bool,
|
||||
) {
|
||||
let mut has_permitted_dep_error = false;
|
||||
|
|
@ -900,7 +995,7 @@ fn check_permitted_dependencies(
|
|||
}
|
||||
|
||||
if has_permitted_dep_error {
|
||||
eprintln!("Go to `{PERMITTED_DEPS_LOCATION}` for the list.");
|
||||
eprintln!("Go to `{}:{}` for the list.", permitted_location.path, permitted_location.line);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::deps::WorkspaceInfo;
|
||||
|
||||
/// List of allowed sources for packages.
|
||||
const ALLOWED_SOURCES: &[&str] = &[
|
||||
r#""registry+https://github.com/rust-lang/crates.io-index""#,
|
||||
|
|
@ -13,22 +15,22 @@ const ALLOWED_SOURCES: &[&str] = &[
|
|||
/// Checks for external package sources. `root` is the path to the directory that contains the
|
||||
/// workspace `Cargo.toml`.
|
||||
pub fn check(root: &Path, bad: &mut bool) {
|
||||
for &(workspace, _, _, submodules) in crate::deps::WORKSPACES {
|
||||
for &WorkspaceInfo { path, submodules, .. } in crate::deps::WORKSPACES {
|
||||
if crate::deps::has_missing_submodule(root, submodules) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME check other workspaces too
|
||||
// `Cargo.lock` of rust.
|
||||
let path = root.join(workspace).join("Cargo.lock");
|
||||
let lockfile = root.join(path).join("Cargo.lock");
|
||||
|
||||
if !path.exists() {
|
||||
tidy_error!(bad, "the `{workspace}` workspace doesn't have a Cargo.lock");
|
||||
if !lockfile.exists() {
|
||||
tidy_error!(bad, "the `{path}` workspace doesn't have a Cargo.lock");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Open and read the whole file.
|
||||
let cargo_lock = t!(fs::read_to_string(&path));
|
||||
let cargo_lock = t!(fs::read_to_string(&lockfile));
|
||||
|
||||
// Process each line.
|
||||
for line in cargo_lock.lines() {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
|
||||
// CHECK: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %args)
|
||||
// CHECK: call void @llvm.lifetime.start.p0({{(i64 [0-9]+, )?}}ptr nonnull %args)
|
||||
// CHECK: call void @llvm.va_start.p0(ptr nonnull %args)
|
||||
|
||||
let b = args.arg::<f64>();
|
||||
|
|
@ -17,5 +17,5 @@ unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
|
|||
a + b + c
|
||||
|
||||
// CHECK: call void @llvm.va_end.p0(ptr nonnull %args)
|
||||
// CHECK: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %args)
|
||||
// CHECK: call void @llvm.lifetime.end.p0({{(i64 [0-9]+, )?}}ptr nonnull %args)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ check-pass
|
||||
//@ reference: items.generics.const.inferred
|
||||
|
||||
struct Foo<const N: usize>;
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue