diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index a10da08ddf347..fdca6b5654098 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -341,7 +341,7 @@ impl<'tcx> BorrowExplanation<'tcx> { } } } else if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() { - let sp = info.span.find_oldest_ancestor_in_same_ctxt(); + let sp = info.span.find_ancestor_not_from_macro().unwrap_or(info.span); if info.tail_result_is_ignored { // #85581: If the first mutable borrow's scope contains // the second borrow, this suggestion isn't helpful. diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index f138f2653203e..240c9a5223be0 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -969,13 +969,28 @@ fn for_each_late_bound_region_in_item<'tcx>( mir_def_id: LocalDefId, mut f: impl FnMut(ty::Region<'tcx>), ) { - if !tcx.def_kind(mir_def_id).is_fn_like() { - return; - } + let bound_vars = match tcx.def_kind(mir_def_id) { + DefKind::Fn | DefKind::AssocFn => { + tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id)) + } + // We extract the bound vars from the deduced closure signature, since we may have + // only deduced that a param in the closure signature is late-bound from a constraint + // that we discover during typeck. + DefKind::Closure => { + let ty = tcx.type_of(mir_def_id).instantiate_identity(); + match *ty.kind() { + ty::Closure(_, args) => args.as_closure().sig().bound_vars(), + ty::CoroutineClosure(_, args) => { + args.as_coroutine_closure().coroutine_closure_sig().bound_vars() + } + ty::Coroutine(_, _) | ty::Error(_) => return, + _ => unreachable!("unexpected type for closure: {ty}"), + } + } + _ => return, + }; - for (idx, bound_var) in - tcx.late_bound_vars(tcx.local_def_id_to_hir_id(mir_def_id)).iter().enumerate() - { + for (idx, bound_var) in bound_vars.iter().enumerate() { if let ty::BoundVariableKind::Region(kind) = bound_var { let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind); let liberated_region = ty::Region::new_late_param(tcx, mir_def_id.to_def_id(), kind); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 33ae4f6c45cf1..2345cdab208e3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1302,7 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => ".clone()".to_string(), }; - let span = expr.span.find_oldest_ancestor_in_same_ctxt().shrink_to_hi(); + let span = expr.span.find_ancestor_not_from_macro().unwrap_or(expr.span).shrink_to_hi(); diag.span_suggestion_verbose( span, @@ -1395,7 +1395,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .macro_backtrace() .any(|x| matches!(x.kind, ExpnKind::Macro(MacroKind::Attr | MacroKind::Derive, ..))) { - let span = expr.span.find_oldest_ancestor_in_same_ctxt(); + let span = expr + .span + .find_ancestor_not_from_extern_macro(&self.tcx.sess.source_map()) + .unwrap_or(expr.span); let mut sugg = if self.precedence(expr) >= ExprPrecedence::Unambiguous { vec![(span.shrink_to_hi(), ".into()".to_owned())] @@ -2062,7 +2065,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => sugg.to_string(), }; - let span = expr.span.find_oldest_ancestor_in_same_ctxt(); + let span = expr + .span + .find_ancestor_not_from_extern_macro(&self.tcx.sess.source_map()) + .unwrap_or(expr.span); err.span_suggestion_verbose(span.shrink_to_hi(), msg, sugg, Applicability::HasPlaceholders); true } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 11df071f0686f..00e40b515a327 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -185,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { let mut op_warned = false; if let Some(must_use_op) = must_use_op { - let span = expr.span.find_oldest_ancestor_in_same_ctxt(); + let span = expr.span.find_ancestor_not_from_macro().unwrap_or(expr.span); cx.emit_span_lint( UNUSED_MUST_USE, expr.span, @@ -511,7 +511,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { ); } MustUsePath::Def(span, def_id, reason) => { - let span = span.find_oldest_ancestor_in_same_ctxt(); + let span = span.find_ancestor_not_from_macro().unwrap_or(*span); cx.emit_span_lint( UNUSED_MUST_USE, span, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index dbc67da37b53c..3f72ccd9f89dc 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -716,12 +716,17 @@ impl Span { (!ctxt.is_root()).then(|| ctxt.outer_expn_data().call_site) } - /// Walk down the expansion ancestors to find a span that's contained within `outer`. + /// Find the first ancestor span that's contained within `outer`. /// - /// The span returned by this method may have a different [`SyntaxContext`] as `outer`. + /// This method traverses the macro expansion ancestors until it finds the first span + /// that's contained within `outer`. + /// + /// The span returned by this method may have a different [`SyntaxContext`] than `outer`. /// If you need to extend the span, use [`find_ancestor_inside_same_ctxt`] instead, /// because joining spans with different syntax contexts can create unexpected results. /// + /// This is used to find the span of the macro call when a parent expr span, i.e. `outer`, is known. + /// /// [`find_ancestor_inside_same_ctxt`]: Self::find_ancestor_inside_same_ctxt pub fn find_ancestor_inside(mut self, outer: Span) -> Option { while !outer.contains(self) { @@ -730,8 +735,10 @@ impl Span { Some(self) } - /// Walk down the expansion ancestors to find a span with the same [`SyntaxContext`] as - /// `other`. + /// Find the first ancestor span with the same [`SyntaxContext`] as `other`. + /// + /// This method traverses the macro expansion ancestors until it finds a span + /// that has the same [`SyntaxContext`] as `other`. /// /// Like [`find_ancestor_inside_same_ctxt`], but specifically for when spans might not /// overlap. Take care when using this, and prefer [`find_ancestor_inside`] or @@ -747,9 +754,12 @@ impl Span { Some(self) } - /// Walk down the expansion ancestors to find a span that's contained within `outer` and + /// Find the first ancestor span that's contained within `outer` and /// has the same [`SyntaxContext`] as `outer`. /// + /// This method traverses the macro expansion ancestors until it finds a span + /// that is both contained within `outer` and has the same [`SyntaxContext`] as `outer`. + /// /// This method is the combination of [`find_ancestor_inside`] and /// [`find_ancestor_in_same_ctxt`] and should be preferred when extending the returned span. /// If you do not need to modify the span, use [`find_ancestor_inside`] instead. @@ -763,43 +773,43 @@ impl Span { Some(self) } - /// Recursively walk down the expansion ancestors to find the oldest ancestor span with the same - /// [`SyntaxContext`] the initial span. + /// Find the first ancestor span that does not come from an external macro. /// - /// This method is suitable for peeling through *local* macro expansions to find the "innermost" - /// span that is still local and shares the same [`SyntaxContext`]. For example, given + /// This method traverses the macro expansion ancestors until it finds a span + /// that is either from user-written code or from a local macro (defined in the current crate). /// - /// ```ignore (illustrative example, contains type error) - /// macro_rules! outer { - /// ($x: expr) => { - /// inner!($x) - /// } - /// } + /// External macros are those defined in dependencies or the standard library. + /// This method is useful for reporting errors in user-controllable code and avoiding + /// diagnostics inside external macros. /// - /// macro_rules! inner { - /// ($x: expr) => { - /// format!("error: {}", $x) - /// //~^ ERROR mismatched types - /// } - /// } + /// # See also /// - /// fn bar(x: &str) -> Result<(), Box> { - /// Err(outer!(x)) - /// } - /// ``` + /// - [`Self::find_ancestor_not_from_macro`] + /// - [`Self::in_external_macro`] + pub fn find_ancestor_not_from_extern_macro(mut self, sm: &SourceMap) -> Option { + while self.in_external_macro(sm) { + self = self.parent_callsite()?; + } + Some(self) + } + + /// Find the first ancestor span that does not come from any macro expansion. /// - /// if provided the initial span of `outer!(x)` inside `bar`, this method will recurse - /// the parent callsites until we reach `format!("error: {}", $x)`, at which point it is the - /// oldest ancestor span that is both still local and shares the same [`SyntaxContext`] as the - /// initial span. - pub fn find_oldest_ancestor_in_same_ctxt(self) -> Span { - let mut cur = self; - while cur.eq_ctxt(self) - && let Some(parent_callsite) = cur.parent_callsite() - { - cur = parent_callsite; + /// This method traverses the macro expansion ancestors until it finds a span + /// that originates from user-written code rather than any macro-generated code. + /// + /// This method is useful for reporting errors at the exact location users wrote code + /// and providing suggestions at directly editable locations. + /// + /// # See also + /// + /// - [`Self::find_ancestor_not_from_extern_macro`] + /// - [`Span::from_expansion`] + pub fn find_ancestor_not_from_macro(mut self) -> Option { + while self.from_expansion() { + self = self.parent_callsite()?; } - cur + Some(self) } /// Edition of the crate from which this span came. diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 5c3ae359ba0bf..89e4d3e9b58ec 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -293,8 +293,6 @@ See [Pretty-printer](compiletest.md#pretty-printer-tests). - `no-auto-check-cfg` — disable auto check-cfg (only for `--check-cfg` tests) - [`revisions`](compiletest.md#revisions) — compile multiple times -- [`unused-revision-names`](compiletest.md#ignoring-unused-revision-names) - - suppress tidy checks for mentioning unknown revision names -[`forbid-output`](compiletest.md#incremental-tests) — incremental cfail rejects output pattern - [`should-ice`](compiletest.md#incremental-tests) — incremental cfail should @@ -315,6 +313,17 @@ test suites that use those tools: - `llvm-cov-flags` adds extra flags when running LLVM's `llvm-cov` tool. - Used by [coverage tests](compiletest.md#coverage-tests) in `coverage-run` mode. +### Tidy specific directives + +The following directives control how the [tidy script](../conventions.md#formatting) +verifies tests. + +- `ignore-tidy-target-specific-tests` disables checking that the appropriate + LLVM component is required (via a `needs-llvm-components` directive) when a + test is compiled for a specific target (via the `--target` flag in a + `compile-flag` directive). +- [`unused-revision-names`](compiletest.md#ignoring-unused-revision-names) - + suppress tidy checks for mentioning unknown revision names. ## Substitutions diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index a1f76a0755620..54511f4fd0855 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -12,6 +12,9 @@ use tracing::*; use crate::common::{CodegenBackend, Config, Debugger, FailMode, PassMode, RunFailMode, TestMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; use crate::directives::auxiliary::{AuxProps, parse_and_update_aux}; +use crate::directives::directive_names::{ + KNOWN_DIRECTIVE_NAMES, KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, KNOWN_JSONDOCCK_DIRECTIVE_NAMES, +}; use crate::directives::needs::CachedNeedsConditions; use crate::errors::ErrorKind; use crate::executor::{CollectedTestDesc, ShouldPanic}; @@ -20,6 +23,7 @@ use crate::util::static_regex; pub(crate) mod auxiliary; mod cfg; +mod directive_names; mod needs; #[cfg(test)] mod tests; @@ -59,9 +63,9 @@ impl EarlyProps { &mut poisoned, testfile, rdr, - &mut |DirectiveLine { raw_directive: ln, .. }| { - parse_and_update_aux(config, ln, &mut props.aux); - config.parse_and_update_revisions(testfile, ln, &mut props.revisions); + &mut |DirectiveLine { line_number, raw_directive: ln, .. }| { + parse_and_update_aux(config, ln, testfile, line_number, &mut props.aux); + config.parse_and_update_revisions(testfile, line_number, ln, &mut props.revisions); }, ); @@ -351,7 +355,7 @@ impl TestProps { &mut poisoned, testfile, file, - &mut |directive @ DirectiveLine { raw_directive: ln, .. }| { + &mut |directive @ DirectiveLine { line_number, raw_directive: ln, .. }| { if !directive.applies_to_test_revision(test_revision) { return; } @@ -361,17 +365,28 @@ impl TestProps { config.push_name_value_directive( ln, ERROR_PATTERN, + testfile, + line_number, &mut self.error_patterns, |r| r, ); config.push_name_value_directive( ln, REGEX_ERROR_PATTERN, + testfile, + line_number, &mut self.regex_error_patterns, |r| r, ); - config.push_name_value_directive(ln, DOC_FLAGS, &mut self.doc_flags, |r| r); + config.push_name_value_directive( + ln, + DOC_FLAGS, + testfile, + line_number, + &mut self.doc_flags, + |r| r, + ); fn split_flags(flags: &str) -> Vec { // Individual flags can be single-quoted to preserve spaces; see @@ -386,7 +401,9 @@ impl TestProps { .collect::>() } - if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) { + if let Some(flags) = + config.parse_name_value_directive(ln, COMPILE_FLAGS, testfile, line_number) + { let flags = split_flags(&flags); for flag in &flags { if flag == "--edition" || flag.starts_with("--edition=") { @@ -395,25 +412,40 @@ impl TestProps { } self.compile_flags.extend(flags); } - if config.parse_name_value_directive(ln, INCORRECT_COMPILER_FLAGS).is_some() { + if config + .parse_name_value_directive( + ln, + INCORRECT_COMPILER_FLAGS, + testfile, + line_number, + ) + .is_some() + { panic!("`compiler-flags` directive should be spelled `compile-flags`"); } - if let Some(edition) = config.parse_edition(ln) { + if let Some(edition) = config.parse_edition(ln, testfile, line_number) { // The edition is added at the start, since flags from //@compile-flags must // be passed to rustc last. self.compile_flags.insert(0, format!("--edition={}", edition.trim())); has_edition = true; } - config.parse_and_update_revisions(testfile, ln, &mut self.revisions); + config.parse_and_update_revisions( + testfile, + line_number, + ln, + &mut self.revisions, + ); - if let Some(flags) = config.parse_name_value_directive(ln, RUN_FLAGS) { + if let Some(flags) = + config.parse_name_value_directive(ln, RUN_FLAGS, testfile, line_number) + { self.run_flags.extend(split_flags(&flags)); } if self.pp_exact.is_none() { - self.pp_exact = config.parse_pp_exact(ln, testfile); + self.pp_exact = config.parse_pp_exact(ln, testfile, line_number); } config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice); @@ -435,7 +467,9 @@ impl TestProps { ); config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut self.no_prefer_dynamic); - if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE) { + if let Some(m) = + config.parse_name_value_directive(ln, PRETTY_MODE, testfile, line_number) + { self.pretty_mode = m; } @@ -446,35 +480,45 @@ impl TestProps { ); // Call a helper method to deal with aux-related directives. - parse_and_update_aux(config, ln, &mut self.aux); + parse_and_update_aux(config, ln, testfile, line_number, &mut self.aux); config.push_name_value_directive( ln, EXEC_ENV, + testfile, + line_number, &mut self.exec_env, Config::parse_env, ); config.push_name_value_directive( ln, UNSET_EXEC_ENV, + testfile, + line_number, &mut self.unset_exec_env, |r| r.trim().to_owned(), ); config.push_name_value_directive( ln, RUSTC_ENV, + testfile, + line_number, &mut self.rustc_env, Config::parse_env, ); config.push_name_value_directive( ln, UNSET_RUSTC_ENV, + testfile, + line_number, &mut self.unset_rustc_env, |r| r.trim().to_owned(), ); config.push_name_value_directive( ln, FORBID_OUTPUT, + testfile, + line_number, &mut self.forbid_output, |r| r, ); @@ -510,7 +554,7 @@ impl TestProps { } if let Some(code) = config - .parse_name_value_directive(ln, FAILURE_STATUS) + .parse_name_value_directive(ln, FAILURE_STATUS, testfile, line_number) .and_then(|code| code.trim().parse::().ok()) { self.failure_status = Some(code); @@ -531,6 +575,8 @@ impl TestProps { config.set_name_value_directive( ln, ASSEMBLY_OUTPUT, + testfile, + line_number, &mut self.assembly_output, |r| r.trim().to_string(), ); @@ -543,7 +589,9 @@ impl TestProps { // Unlike the other `name_value_directive`s this needs to be handled manually, // because it sets a `bool` flag. - if let Some(known_bug) = config.parse_name_value_directive(ln, KNOWN_BUG) { + if let Some(known_bug) = + config.parse_name_value_directive(ln, KNOWN_BUG, testfile, line_number) + { let known_bug = known_bug.trim(); if known_bug == "unknown" || known_bug.split(',').all(|issue_ref| { @@ -571,16 +619,25 @@ impl TestProps { config.set_name_value_directive( ln, TEST_MIR_PASS, + testfile, + line_number, &mut self.mir_unit_test, |s| s.trim().to_string(), ); config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base); - if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) { + if let Some(flags) = + config.parse_name_value_directive(ln, LLVM_COV_FLAGS, testfile, line_number) + { self.llvm_cov_flags.extend(split_flags(&flags)); } - if let Some(flags) = config.parse_name_value_directive(ln, FILECHECK_FLAGS) { + if let Some(flags) = config.parse_name_value_directive( + ln, + FILECHECK_FLAGS, + testfile, + line_number, + ) { self.filecheck_flags.extend(split_flags(&flags)); } @@ -588,9 +645,12 @@ impl TestProps { self.update_add_core_stubs(ln, config); - if let Some(err_kind) = - config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) - { + if let Some(err_kind) = config.parse_name_value_directive( + ln, + DONT_REQUIRE_ANNOTATIONS, + testfile, + line_number, + ) { self.dont_require_annotations .insert(ErrorKind::expect_from_user_str(err_kind.trim())); } @@ -769,296 +829,6 @@ fn line_directive<'line>( Some(DirectiveLine { line_number, revision, raw_directive }) } -/// This was originally generated by collecting directives from ui tests and then extracting their -/// directive names. This is **not** an exhaustive list of all possible directives. Instead, this is -/// a best-effort approximation for diagnostics. Add new directives to this list when needed. -const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ - // tidy-alphabetical-start - "add-core-stubs", - "assembly-output", - "aux-bin", - "aux-build", - "aux-codegen-backend", - "aux-crate", - "build-aux-docs", - "build-fail", - "build-pass", - "check-fail", - "check-pass", - "check-run-results", - "check-stdout", - "check-test-line-numbers-match", - "compile-flags", - "doc-flags", - "dont-check-compiler-stderr", - "dont-check-compiler-stdout", - "dont-check-failure-status", - "dont-require-annotations", - "edition", - "error-pattern", - "exact-llvm-major-version", - "exec-env", - "failure-status", - "filecheck-flags", - "forbid-output", - "force-host", - "ignore-16bit", - "ignore-32bit", - "ignore-64bit", - "ignore-aarch64", - "ignore-aarch64-pc-windows-msvc", - "ignore-aarch64-unknown-linux-gnu", - "ignore-aix", - "ignore-android", - "ignore-apple", - "ignore-arm", - "ignore-arm-unknown-linux-gnueabi", - "ignore-arm-unknown-linux-gnueabihf", - "ignore-arm-unknown-linux-musleabi", - "ignore-arm-unknown-linux-musleabihf", - "ignore-auxiliary", - "ignore-avr", - "ignore-backends", - "ignore-beta", - "ignore-cdb", - "ignore-compare-mode-next-solver", - "ignore-compare-mode-polonius", - "ignore-coverage-map", - "ignore-coverage-run", - "ignore-cross-compile", - "ignore-eabi", - "ignore-elf", - "ignore-emscripten", - "ignore-endian-big", - "ignore-enzyme", - "ignore-freebsd", - "ignore-fuchsia", - "ignore-gdb", - "ignore-gdb-version", - "ignore-gnu", - "ignore-haiku", - "ignore-horizon", - "ignore-i686-pc-windows-gnu", - "ignore-i686-pc-windows-msvc", - "ignore-illumos", - "ignore-ios", - "ignore-linux", - "ignore-lldb", - "ignore-llvm-version", - "ignore-loongarch32", - "ignore-loongarch64", - "ignore-macabi", - "ignore-macos", - "ignore-msp430", - "ignore-msvc", - "ignore-musl", - "ignore-netbsd", - "ignore-nightly", - "ignore-none", - "ignore-nto", - "ignore-nvptx64", - "ignore-nvptx64-nvidia-cuda", - "ignore-openbsd", - "ignore-pass", - "ignore-powerpc", - "ignore-powerpc64", - "ignore-remote", - "ignore-riscv64", - "ignore-rustc-debug-assertions", - "ignore-rustc_abi-x86-sse2", - "ignore-s390x", - "ignore-sgx", - "ignore-sparc64", - "ignore-spirv", - "ignore-stable", - "ignore-stage1", - "ignore-stage2", - "ignore-std-debug-assertions", - "ignore-test", - "ignore-thumb", - "ignore-thumbv8m.base-none-eabi", - "ignore-thumbv8m.main-none-eabi", - "ignore-tvos", - "ignore-unix", - "ignore-unknown", - "ignore-uwp", - "ignore-visionos", - "ignore-vxworks", - "ignore-wasi", - "ignore-wasm", - "ignore-wasm32", - "ignore-wasm32-bare", - "ignore-wasm64", - "ignore-watchos", - "ignore-windows", - "ignore-windows-gnu", - "ignore-windows-msvc", - "ignore-x32", - "ignore-x86", - "ignore-x86_64", - "ignore-x86_64-apple-darwin", - "ignore-x86_64-pc-windows-gnu", - "ignore-x86_64-unknown-linux-gnu", - "incremental", - "known-bug", - "llvm-cov-flags", - "max-llvm-major-version", - "min-cdb-version", - "min-gdb-version", - "min-lldb-version", - "min-llvm-version", - "min-system-llvm-version", - "needs-asm-support", - "needs-backends", - "needs-crate-type", - "needs-deterministic-layouts", - "needs-dlltool", - "needs-dynamic-linking", - "needs-enzyme", - "needs-force-clang-based-tests", - "needs-git-hash", - "needs-llvm-components", - "needs-llvm-zstd", - "needs-profiler-runtime", - "needs-relocation-model-pic", - "needs-run-enabled", - "needs-rust-lld", - "needs-rustc-debug-assertions", - "needs-sanitizer-address", - "needs-sanitizer-cfi", - "needs-sanitizer-dataflow", - "needs-sanitizer-hwaddress", - "needs-sanitizer-kcfi", - "needs-sanitizer-leak", - "needs-sanitizer-memory", - "needs-sanitizer-memtag", - "needs-sanitizer-safestack", - "needs-sanitizer-shadow-call-stack", - "needs-sanitizer-support", - "needs-sanitizer-thread", - "needs-std-debug-assertions", - "needs-subprocess", - "needs-symlink", - "needs-target-has-atomic", - "needs-target-std", - "needs-threads", - "needs-unwind", - "needs-wasmtime", - "needs-xray", - "no-auto-check-cfg", - "no-prefer-dynamic", - "normalize-stderr", - "normalize-stderr-32bit", - "normalize-stderr-64bit", - "normalize-stdout", - "only-16bit", - "only-32bit", - "only-64bit", - "only-aarch64", - "only-aarch64-apple-darwin", - "only-aarch64-unknown-linux-gnu", - "only-apple", - "only-arm", - "only-avr", - "only-beta", - "only-bpf", - "only-cdb", - "only-dist", - "only-elf", - "only-emscripten", - "only-gnu", - "only-i686-pc-windows-gnu", - "only-i686-pc-windows-msvc", - "only-i686-unknown-linux-gnu", - "only-ios", - "only-linux", - "only-loongarch32", - "only-loongarch64", - "only-loongarch64-unknown-linux-gnu", - "only-macos", - "only-mips", - "only-mips64", - "only-msp430", - "only-msvc", - "only-musl", - "only-nightly", - "only-nvptx64", - "only-powerpc", - "only-riscv64", - "only-rustc_abi-x86-sse2", - "only-s390x", - "only-sparc", - "only-sparc64", - "only-stable", - "only-thumb", - "only-tvos", - "only-uefi", - "only-unix", - "only-visionos", - "only-wasm32", - "only-wasm32-bare", - "only-wasm32-wasip1", - "only-watchos", - "only-windows", - "only-windows-gnu", - "only-windows-msvc", - "only-x86", - "only-x86_64", - "only-x86_64-apple-darwin", - "only-x86_64-fortanix-unknown-sgx", - "only-x86_64-pc-windows-gnu", - "only-x86_64-pc-windows-msvc", - "only-x86_64-unknown-linux-gnu", - "pp-exact", - "pretty-compare-only", - "pretty-mode", - "proc-macro", - "reference", - "regex-error-pattern", - "remap-src-base", - "revisions", - "run-crash", - "run-fail", - "run-fail-or-crash", - "run-flags", - "run-pass", - "run-rustfix", - "rustc-env", - "rustfix-only-machine-applicable", - "should-fail", - "should-ice", - "stderr-per-bitwidth", - "test-mir-pass", - "unique-doc-out-dir", - "unset-exec-env", - "unset-rustc-env", - // Used by the tidy check `unknown_revision`. - "unused-revision-names", - // tidy-alphabetical-end -]; - -const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[ - "count", - "!count", - "files", - "!files", - "has", - "!has", - "has-dir", - "!has-dir", - "hasraw", - "!hasraw", - "matches", - "!matches", - "matchesraw", - "!matchesraw", - "snapshot", - "!snapshot", -]; - -const KNOWN_JSONDOCCK_DIRECTIVE_NAMES: &[&str] = - &["count", "!count", "has", "!has", "is", "!is", "ismany", "!ismany", "set", "!set"]; - /// The (partly) broken-down contents of a line containing a test directive, /// which [`iter_directives`] passes to its callback function. /// @@ -1206,6 +976,7 @@ impl Config { fn parse_and_update_revisions( &self, testfile: &Utf8Path, + line_number: usize, line: &str, existing: &mut Vec, ) { @@ -1219,7 +990,8 @@ impl Config { const FILECHECK_FORBIDDEN_REVISION_NAMES: [&str; 9] = ["CHECK", "COM", "NEXT", "SAME", "EMPTY", "NOT", "COUNT", "DAG", "LABEL"]; - if let Some(raw) = self.parse_name_value_directive(line, "revisions") { + if let Some(raw) = self.parse_name_value_directive(line, "revisions", testfile, line_number) + { if self.mode == TestMode::RunMake { panic!("`run-make` tests do not support revisions: {}", testfile); } @@ -1264,8 +1036,13 @@ impl Config { (name.to_owned(), value.to_owned()) } - fn parse_pp_exact(&self, line: &str, testfile: &Utf8Path) -> Option { - if let Some(s) = self.parse_name_value_directive(line, "pp-exact") { + fn parse_pp_exact( + &self, + line: &str, + testfile: &Utf8Path, + line_number: usize, + ) -> Option { + if let Some(s) = self.parse_name_value_directive(line, "pp-exact", testfile, line_number) { Some(Utf8PathBuf::from(&s)) } else if self.parse_name_directive(line, "pp-exact") { testfile.file_name().map(Utf8PathBuf::from) @@ -1306,19 +1083,31 @@ impl Config { line.starts_with("no-") && self.parse_name_directive(&line[3..], directive) } - pub fn parse_name_value_directive(&self, line: &str, directive: &str) -> Option { + pub fn parse_name_value_directive( + &self, + line: &str, + directive: &str, + testfile: &Utf8Path, + line_number: usize, + ) -> Option { let colon = directive.len(); if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') { let value = line[(colon + 1)..].to_owned(); debug!("{}: {}", directive, value); - Some(expand_variables(value, self)) + let value = expand_variables(value, self); + if value.is_empty() { + error!("{testfile}:{line_number}: empty value for directive `{directive}`"); + help!("expected syntax is: `{directive}: value`"); + panic!("empty directive value detected"); + } + Some(value) } else { None } } - fn parse_edition(&self, line: &str) -> Option { - self.parse_name_value_directive(line, "edition") + fn parse_edition(&self, line: &str, testfile: &Utf8Path, line_number: usize) -> Option { + self.parse_name_value_directive(line, "edition", testfile, line_number) } fn set_name_directive(&self, line: &str, directive: &str, value: &mut bool) { @@ -1340,11 +1129,14 @@ impl Config { &self, line: &str, directive: &str, + testfile: &Utf8Path, + line_number: usize, value: &mut Option, parse: impl FnOnce(String) -> T, ) { if value.is_none() { - *value = self.parse_name_value_directive(line, directive).map(parse); + *value = + self.parse_name_value_directive(line, directive, testfile, line_number).map(parse); } } @@ -1352,10 +1144,14 @@ impl Config { &self, line: &str, directive: &str, + testfile: &Utf8Path, + line_number: usize, values: &mut Vec, parse: impl FnOnce(String) -> T, ) { - if let Some(value) = self.parse_name_value_directive(line, directive).map(parse) { + if let Some(value) = + self.parse_name_value_directive(line, directive, testfile, line_number).map(parse) + { values.push(value); } } @@ -1672,9 +1468,9 @@ pub(crate) fn make_test_description( decision!(cfg::handle_ignore(config, ln)); decision!(cfg::handle_only(config, ln)); decision!(needs::handle_needs(&cache.needs, config, ln)); - decision!(ignore_llvm(config, path, ln)); - decision!(ignore_backends(config, path, ln)); - decision!(needs_backends(config, path, ln)); + decision!(ignore_llvm(config, path, ln, line_number)); + decision!(ignore_backends(config, path, ln, line_number)); + decision!(needs_backends(config, path, ln, line_number)); decision!(ignore_cdb(config, ln)); decision!(ignore_gdb(config, ln)); decision!(ignore_lldb(config, ln)); @@ -1801,8 +1597,15 @@ fn ignore_lldb(config: &Config, line: &str) -> IgnoreDecision { IgnoreDecision::Continue } -fn ignore_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision { - if let Some(backends_to_ignore) = config.parse_name_value_directive(line, "ignore-backends") { +fn ignore_backends( + config: &Config, + path: &Utf8Path, + line: &str, + line_number: usize, +) -> IgnoreDecision { + if let Some(backends_to_ignore) = + config.parse_name_value_directive(line, "ignore-backends", path, line_number) + { for backend in backends_to_ignore.split_whitespace().map(|backend| { match CodegenBackend::try_from(backend) { Ok(backend) => backend, @@ -1821,8 +1624,15 @@ fn ignore_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecisi IgnoreDecision::Continue } -fn needs_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision { - if let Some(needed_backends) = config.parse_name_value_directive(line, "needs-backends") { +fn needs_backends( + config: &Config, + path: &Utf8Path, + line: &str, + line_number: usize, +) -> IgnoreDecision { + if let Some(needed_backends) = + config.parse_name_value_directive(line, "needs-backends", path, line_number) + { if !needed_backends .split_whitespace() .map(|backend| match CodegenBackend::try_from(backend) { @@ -1844,9 +1654,9 @@ fn needs_backends(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecisio IgnoreDecision::Continue } -fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision { +fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize) -> IgnoreDecision { if let Some(needed_components) = - config.parse_name_value_directive(line, "needs-llvm-components") + config.parse_name_value_directive(line, "needs-llvm-components", path, line_number) { let components: HashSet<_> = config.llvm_components.split_whitespace().collect(); if let Some(missing_component) = needed_components @@ -1867,7 +1677,9 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision { if let Some(actual_version) = &config.llvm_version { // Note that these `min` versions will check for not just major versions. - if let Some(version_string) = config.parse_name_value_directive(line, "min-llvm-version") { + if let Some(version_string) = + config.parse_name_value_directive(line, "min-llvm-version", path, line_number) + { let min_version = extract_llvm_version(&version_string); // Ignore if actual version is smaller than the minimum required version. if *actual_version < min_version { @@ -1878,7 +1690,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision { }; } } else if let Some(version_string) = - config.parse_name_value_directive(line, "max-llvm-major-version") + config.parse_name_value_directive(line, "max-llvm-major-version", path, line_number) { let max_version = extract_llvm_version(&version_string); // Ignore if actual major version is larger than the maximum required major version. @@ -1892,7 +1704,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision { }; } } else if let Some(version_string) = - config.parse_name_value_directive(line, "min-system-llvm-version") + config.parse_name_value_directive(line, "min-system-llvm-version", path, line_number) { let min_version = extract_llvm_version(&version_string); // Ignore if using system LLVM and actual version @@ -1905,7 +1717,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision { }; } } else if let Some(version_range) = - config.parse_name_value_directive(line, "ignore-llvm-version") + config.parse_name_value_directive(line, "ignore-llvm-version", path, line_number) { // Syntax is: "ignore-llvm-version: [- ]" let (v_min, v_max) = @@ -1931,7 +1743,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str) -> IgnoreDecision { } } } else if let Some(version_string) = - config.parse_name_value_directive(line, "exact-llvm-major-version") + config.parse_name_value_directive(line, "exact-llvm-major-version", path, line_number) { // Syntax is "exact-llvm-major-version: " let version = extract_llvm_version(&version_string); diff --git a/src/tools/compiletest/src/directives/auxiliary.rs b/src/tools/compiletest/src/directives/auxiliary.rs index cdb75f6ffa907..7c1ed2e700624 100644 --- a/src/tools/compiletest/src/directives/auxiliary.rs +++ b/src/tools/compiletest/src/directives/auxiliary.rs @@ -3,6 +3,8 @@ use std::iter; +use camino::Utf8Path; + use super::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO}; use crate::common::Config; @@ -41,17 +43,42 @@ impl AuxProps { /// If the given test directive line contains an `aux-*` directive, parse it /// and update [`AuxProps`] accordingly. -pub(super) fn parse_and_update_aux(config: &Config, ln: &str, aux: &mut AuxProps) { +pub(super) fn parse_and_update_aux( + config: &Config, + ln: &str, + testfile: &Utf8Path, + line_number: usize, + aux: &mut AuxProps, +) { if !(ln.starts_with("aux-") || ln.starts_with("proc-macro")) { return; } - config.push_name_value_directive(ln, AUX_BUILD, &mut aux.builds, |r| r.trim().to_string()); - config.push_name_value_directive(ln, AUX_BIN, &mut aux.bins, |r| r.trim().to_string()); - config.push_name_value_directive(ln, AUX_CRATE, &mut aux.crates, parse_aux_crate); - config - .push_name_value_directive(ln, PROC_MACRO, &mut aux.proc_macros, |r| r.trim().to_string()); - if let Some(r) = config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND) { + config.push_name_value_directive(ln, AUX_BUILD, testfile, line_number, &mut aux.builds, |r| { + r.trim().to_string() + }); + config.push_name_value_directive(ln, AUX_BIN, testfile, line_number, &mut aux.bins, |r| { + r.trim().to_string() + }); + config.push_name_value_directive( + ln, + AUX_CRATE, + testfile, + line_number, + &mut aux.crates, + parse_aux_crate, + ); + config.push_name_value_directive( + ln, + PROC_MACRO, + testfile, + line_number, + &mut aux.proc_macros, + |r| r.trim().to_string(), + ); + if let Some(r) = + config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND, testfile, line_number) + { aux.codegen_backend = Some(r.trim().to_owned()); } } diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs new file mode 100644 index 0000000000000..7fc76a42e0ca1 --- /dev/null +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -0,0 +1,289 @@ +/// This was originally generated by collecting directives from ui tests and then extracting their +/// directive names. This is **not** an exhaustive list of all possible directives. Instead, this is +/// a best-effort approximation for diagnostics. Add new directives to this list when needed. +pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ + // tidy-alphabetical-start + "add-core-stubs", + "assembly-output", + "aux-bin", + "aux-build", + "aux-codegen-backend", + "aux-crate", + "build-aux-docs", + "build-fail", + "build-pass", + "check-fail", + "check-pass", + "check-run-results", + "check-stdout", + "check-test-line-numbers-match", + "compile-flags", + "doc-flags", + "dont-check-compiler-stderr", + "dont-check-compiler-stdout", + "dont-check-failure-status", + "dont-require-annotations", + "edition", + "error-pattern", + "exact-llvm-major-version", + "exec-env", + "failure-status", + "filecheck-flags", + "forbid-output", + "force-host", + "ignore-16bit", + "ignore-32bit", + "ignore-64bit", + "ignore-aarch64", + "ignore-aarch64-pc-windows-msvc", + "ignore-aarch64-unknown-linux-gnu", + "ignore-aix", + "ignore-android", + "ignore-apple", + "ignore-arm", + "ignore-arm-unknown-linux-gnueabi", + "ignore-arm-unknown-linux-gnueabihf", + "ignore-arm-unknown-linux-musleabi", + "ignore-arm-unknown-linux-musleabihf", + "ignore-auxiliary", + "ignore-avr", + "ignore-backends", + "ignore-beta", + "ignore-cdb", + "ignore-compare-mode-next-solver", + "ignore-compare-mode-polonius", + "ignore-coverage-map", + "ignore-coverage-run", + "ignore-cross-compile", + "ignore-eabi", + "ignore-elf", + "ignore-emscripten", + "ignore-endian-big", + "ignore-enzyme", + "ignore-freebsd", + "ignore-fuchsia", + "ignore-gdb", + "ignore-gdb-version", + "ignore-gnu", + "ignore-haiku", + "ignore-horizon", + "ignore-i686-pc-windows-gnu", + "ignore-i686-pc-windows-msvc", + "ignore-illumos", + "ignore-ios", + "ignore-linux", + "ignore-lldb", + "ignore-llvm-version", + "ignore-loongarch32", + "ignore-loongarch64", + "ignore-macabi", + "ignore-macos", + "ignore-msp430", + "ignore-msvc", + "ignore-musl", + "ignore-netbsd", + "ignore-nightly", + "ignore-none", + "ignore-nto", + "ignore-nvptx64", + "ignore-nvptx64-nvidia-cuda", + "ignore-openbsd", + "ignore-pass", + "ignore-powerpc", + "ignore-powerpc64", + "ignore-remote", + "ignore-riscv64", + "ignore-rustc-debug-assertions", + "ignore-rustc_abi-x86-sse2", + "ignore-s390x", + "ignore-sgx", + "ignore-sparc64", + "ignore-spirv", + "ignore-stable", + "ignore-stage1", + "ignore-stage2", + "ignore-std-debug-assertions", + "ignore-test", + "ignore-thumb", + "ignore-thumbv8m.base-none-eabi", + "ignore-thumbv8m.main-none-eabi", + "ignore-tvos", + "ignore-unix", + "ignore-unknown", + "ignore-uwp", + "ignore-visionos", + "ignore-vxworks", + "ignore-wasi", + "ignore-wasm", + "ignore-wasm32", + "ignore-wasm32-bare", + "ignore-wasm64", + "ignore-watchos", + "ignore-windows", + "ignore-windows-gnu", + "ignore-windows-msvc", + "ignore-x32", + "ignore-x86", + "ignore-x86_64", + "ignore-x86_64-apple-darwin", + "ignore-x86_64-pc-windows-gnu", + "ignore-x86_64-unknown-linux-gnu", + "incremental", + "known-bug", + "llvm-cov-flags", + "max-llvm-major-version", + "min-cdb-version", + "min-gdb-version", + "min-lldb-version", + "min-llvm-version", + "min-system-llvm-version", + "needs-asm-support", + "needs-backends", + "needs-crate-type", + "needs-deterministic-layouts", + "needs-dlltool", + "needs-dynamic-linking", + "needs-enzyme", + "needs-force-clang-based-tests", + "needs-git-hash", + "needs-llvm-components", + "needs-llvm-zstd", + "needs-profiler-runtime", + "needs-relocation-model-pic", + "needs-run-enabled", + "needs-rust-lld", + "needs-rustc-debug-assertions", + "needs-sanitizer-address", + "needs-sanitizer-cfi", + "needs-sanitizer-dataflow", + "needs-sanitizer-hwaddress", + "needs-sanitizer-kcfi", + "needs-sanitizer-leak", + "needs-sanitizer-memory", + "needs-sanitizer-memtag", + "needs-sanitizer-safestack", + "needs-sanitizer-shadow-call-stack", + "needs-sanitizer-support", + "needs-sanitizer-thread", + "needs-std-debug-assertions", + "needs-subprocess", + "needs-symlink", + "needs-target-has-atomic", + "needs-target-std", + "needs-threads", + "needs-unwind", + "needs-wasmtime", + "needs-xray", + "no-auto-check-cfg", + "no-prefer-dynamic", + "normalize-stderr", + "normalize-stderr-32bit", + "normalize-stderr-64bit", + "normalize-stdout", + "only-16bit", + "only-32bit", + "only-64bit", + "only-aarch64", + "only-aarch64-apple-darwin", + "only-aarch64-unknown-linux-gnu", + "only-apple", + "only-arm", + "only-avr", + "only-beta", + "only-bpf", + "only-cdb", + "only-dist", + "only-elf", + "only-emscripten", + "only-gnu", + "only-i686-pc-windows-gnu", + "only-i686-pc-windows-msvc", + "only-i686-unknown-linux-gnu", + "only-ios", + "only-linux", + "only-loongarch32", + "only-loongarch64", + "only-loongarch64-unknown-linux-gnu", + "only-macos", + "only-mips", + "only-mips64", + "only-msp430", + "only-msvc", + "only-musl", + "only-nightly", + "only-nvptx64", + "only-powerpc", + "only-riscv64", + "only-rustc_abi-x86-sse2", + "only-s390x", + "only-sparc", + "only-sparc64", + "only-stable", + "only-thumb", + "only-tvos", + "only-uefi", + "only-unix", + "only-visionos", + "only-wasm32", + "only-wasm32-bare", + "only-wasm32-wasip1", + "only-watchos", + "only-windows", + "only-windows-gnu", + "only-windows-msvc", + "only-x86", + "only-x86_64", + "only-x86_64-apple-darwin", + "only-x86_64-fortanix-unknown-sgx", + "only-x86_64-pc-windows-gnu", + "only-x86_64-pc-windows-msvc", + "only-x86_64-unknown-linux-gnu", + "pp-exact", + "pretty-compare-only", + "pretty-mode", + "proc-macro", + "reference", + "regex-error-pattern", + "remap-src-base", + "revisions", + "run-crash", + "run-fail", + "run-fail-or-crash", + "run-flags", + "run-pass", + "run-rustfix", + "rustc-env", + "rustfix-only-machine-applicable", + "should-fail", + "should-ice", + "stderr-per-bitwidth", + "test-mir-pass", + "unique-doc-out-dir", + "unset-exec-env", + "unset-rustc-env", + // Used by the tidy check `unknown_revision`. + "unused-revision-names", + // tidy-alphabetical-end +]; + +pub(crate) const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[ + "count", + "!count", + "files", + "!files", + "has", + "!has", + "has-dir", + "!has-dir", + "hasraw", + "!hasraw", + "matches", + "!matches", + "matchesraw", + "!matchesraw", + "snapshot", + "!snapshot", +]; + +pub(crate) const KNOWN_JSONDOCCK_DIRECTIVE_NAMES: &[&str] = + &["count", "!count", "has", "!has", "is", "!is", "ismany", "!ismany", "set", "!set"]; diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs index a4103c5b4a9a4..ba824124e875d 100644 --- a/src/tools/compiletest/src/runtest/debugger.rs +++ b/src/tools/compiletest/src/runtest/debugger.rs @@ -47,10 +47,14 @@ impl DebuggerCommands { continue; }; - if let Some(command) = config.parse_name_value_directive(&line, &command_directive) { + if let Some(command) = + config.parse_name_value_directive(&line, &command_directive, file, line_no) + { commands.push(command); } - if let Some(pattern) = config.parse_name_value_directive(&line, &check_directive) { + if let Some(pattern) = + config.parse_name_value_directive(&line, &check_directive, file, line_no) + { check_lines.push((line_no, pattern)); } } diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 35ed61eacc73f..fca097c091b75 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -519,8 +519,11 @@ pub fn check(path: &Path, bad: &mut bool) { .any(|directive| matches!(directive, Directive::Ignore(_))); let has_alphabetical_directive = line.contains("tidy-alphabetical-start") || line.contains("tidy-alphabetical-end"); - let has_recognized_directive = - has_recognized_ignore_directive || has_alphabetical_directive; + let has_other_tidy_ignore_directive = + line.contains("ignore-tidy-target-specific-tests"); + let has_recognized_directive = has_recognized_ignore_directive + || has_alphabetical_directive + || has_other_tidy_ignore_directive; if contains_potential_directive && (!has_recognized_directive) { err("Unrecognized tidy directive") } diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index f4a6783abb679..b2d5f259eb2db 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -12,12 +12,16 @@ const COMPILE_FLAGS_HEADER: &str = "compile-flags:"; #[derive(Default, Debug)] struct RevisionInfo<'a> { - target_arch: Option<&'a str>, + target_arch: Option>, llvm_components: Option>, } pub fn check(tests_path: &Path, bad: &mut bool) { crate::walk::walk(tests_path, |path, _is_dir| filter_not_rust(path), &mut |entry, content| { + if content.contains("// ignore-tidy-target-specific-tests") { + return; + } + let file = entry.path().display(); let mut header_map = BTreeMap::new(); iter_header(content, &mut |HeaderLine { revision, directive, .. }| { @@ -34,10 +38,11 @@ pub fn check(tests_path: &Path, bad: &mut bool) { && let Some((_, v)) = compile_flags.split_once("--target") { let v = v.trim_start_matches([' ', '=']); - let v = if v == "{{target}}" { Some((v, v)) } else { v.split_once("-") }; - if let Some((arch, _)) = v { - let info = header_map.entry(revision).or_insert(RevisionInfo::default()); - info.target_arch.replace(arch); + let info = header_map.entry(revision).or_insert(RevisionInfo::default()); + if v.starts_with("{{") { + info.target_arch.replace(None); + } else if let Some((arch, _)) = v.split_once("-") { + info.target_arch.replace(Some(arch)); } else { eprintln!("{file}: seems to have a malformed --target value"); *bad = true; @@ -54,9 +59,11 @@ pub fn check(tests_path: &Path, bad: &mut bool) { let rev = rev.unwrap_or("[unspecified]"); match (target_arch, llvm_components) { (None, None) => {} - (Some(_), None) => { + (Some(target_arch), None) => { + let llvm_component = + target_arch.map_or_else(|| "".to_string(), arch_to_llvm_component); eprintln!( - "{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER}` as it has `--target` set" + "{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER} {llvm_component}` as it has `--target` set" ); *bad = true; } @@ -66,11 +73,45 @@ pub fn check(tests_path: &Path, bad: &mut bool) { ); *bad = true; } - (Some(_), Some(_)) => { - // FIXME: check specified components against the target architectures we - // gathered. + (Some(target_arch), Some(llvm_components)) => { + if let Some(target_arch) = target_arch { + let llvm_component = arch_to_llvm_component(target_arch); + if !llvm_components.contains(&llvm_component.as_str()) { + eprintln!( + "{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER} {llvm_component}` as it has `--target` set" + ); + *bad = true; + } + } } } } }); } + +fn arch_to_llvm_component(arch: &str) -> String { + // NOTE: This is an *approximate* mapping of Rust's `--target` architecture to LLVM component + // names. It is not intended to be an authoritative source, but rather a best-effort that's good + // enough for the purpose of this tidy check. + match arch { + "amdgcn" => "amdgpu".into(), + "aarch64_be" | "arm64_32" | "arm64e" | "arm64ec" => "aarch64".into(), + "i386" | "i586" | "i686" | "x86" | "x86_64" | "x86_64h" => "x86".into(), + "loongarch32" | "loongarch64" => "loongarch".into(), + "nvptx64" => "nvptx".into(), + "s390x" => "systemz".into(), + "sparc64" | "sparcv9" => "sparc".into(), + "wasm32" | "wasm32v1" | "wasm64" => "webassembly".into(), + _ if arch.starts_with("armeb") + || arch.starts_with("armv") + || arch.starts_with("thumbv") => + { + "arm".into() + } + _ if arch.starts_with("bpfe") => "bpf".into(), + _ if arch.starts_with("mips") => "mips".into(), + _ if arch.starts_with("powerpc") => "powerpc".into(), + _ if arch.starts_with("riscv") => "riscv".into(), + _ => arch.to_ascii_lowercase(), + } +} diff --git a/tests/codegen-llvm/abi-efiapi.rs b/tests/codegen-llvm/abi-efiapi.rs index 1736f0daf0fac..4cd645101a8b1 100644 --- a/tests/codegen-llvm/abi-efiapi.rs +++ b/tests/codegen-llvm/abi-efiapi.rs @@ -3,15 +3,15 @@ //@ add-core-stubs //@ revisions:x86_64 i686 aarch64 arm riscv //@[x86_64] compile-flags: --target x86_64-unknown-uefi -//@[x86_64] needs-llvm-components: aarch64 arm riscv +//@[x86_64] needs-llvm-components: x86 //@[i686] compile-flags: --target i686-unknown-linux-musl -//@[i686] needs-llvm-components: aarch64 arm riscv +//@[i686] needs-llvm-components: x86 //@[aarch64] compile-flags: --target aarch64-unknown-none -//@[aarch64] needs-llvm-components: aarch64 arm riscv +//@[aarch64] needs-llvm-components: aarch64 //@[arm] compile-flags: --target armv7r-none-eabi -//@[arm] needs-llvm-components: aarch64 arm riscv +//@[arm] needs-llvm-components: arm //@[riscv] compile-flags: --target riscv64gc-unknown-none-elf -//@[riscv] needs-llvm-components: aarch64 arm riscv +//@[riscv] needs-llvm-components: riscv //@ compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/tests/codegen-llvm/cast-target-abi.rs b/tests/codegen-llvm/cast-target-abi.rs index cbd49e2f022a1..28d3ad5f61c7f 100644 --- a/tests/codegen-llvm/cast-target-abi.rs +++ b/tests/codegen-llvm/cast-target-abi.rs @@ -4,7 +4,7 @@ //@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Zlint-llvm-ir //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu -//@[aarch64] needs-llvm-components: arm +//@[aarch64] needs-llvm-components: aarch64 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu //@[loongarch64] needs-llvm-components: loongarch //@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu diff --git a/tests/codegen-llvm/cf-protection.rs b/tests/codegen-llvm/cf-protection.rs index f1349a5dcb980..9efadb599322a 100644 --- a/tests/codegen-llvm/cf-protection.rs +++ b/tests/codegen-llvm/cf-protection.rs @@ -3,7 +3,7 @@ //@ add-core-stubs //@ revisions: undefined none branch return full //@ needs-llvm-components: x86 -//@ [undefined] compile-flags: +// [undefined] no extra compile-flags //@ [none] compile-flags: -Z cf-protection=none //@ [branch] compile-flags: -Z cf-protection=branch //@ [return] compile-flags: -Z cf-protection=return diff --git a/tests/codegen-llvm/codemodels.rs b/tests/codegen-llvm/codemodels.rs index 06d2eade78ae8..e82e094aab8ad 100644 --- a/tests/codegen-llvm/codemodels.rs +++ b/tests/codegen-llvm/codemodels.rs @@ -1,7 +1,7 @@ //@ only-x86_64 //@ revisions: NOMODEL MODEL-SMALL MODEL-KERNEL MODEL-MEDIUM MODEL-LARGE -//@[NOMODEL] compile-flags: +// [NOMODEL] no compile-flags //@[MODEL-SMALL] compile-flags: -C code-model=small //@[MODEL-KERNEL] compile-flags: -C code-model=kernel //@[MODEL-MEDIUM] compile-flags: -C code-model=medium diff --git a/tests/codegen-llvm/ehcontguard_disabled.rs b/tests/codegen-llvm/ehcontguard_disabled.rs index 9efb2721b3e82..962d14e7eb9bc 100644 --- a/tests/codegen-llvm/ehcontguard_disabled.rs +++ b/tests/codegen-llvm/ehcontguard_disabled.rs @@ -1,5 +1,3 @@ -//@ compile-flags: - #![crate_type = "lib"] // A basic test function. diff --git a/tests/codegen-llvm/naked-fn/naked-functions.rs b/tests/codegen-llvm/naked-fn/naked-functions.rs index 344af6eb42fa8..8a7ee4b4de563 100644 --- a/tests/codegen-llvm/naked-fn/naked-functions.rs +++ b/tests/codegen-llvm/naked-fn/naked-functions.rs @@ -8,7 +8,7 @@ //@[win_i686] compile-flags: --target i686-pc-windows-gnu //@[win_i686] needs-llvm-components: x86 //@[macos] compile-flags: --target aarch64-apple-darwin -//@[macos] needs-llvm-components: arm +//@[macos] needs-llvm-components: aarch64 //@[thumb] compile-flags: --target thumbv7em-none-eabi //@[thumb] needs-llvm-components: arm diff --git a/tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs b/tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs index f319306f93fd8..642bf5e75762b 100644 --- a/tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs +++ b/tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs @@ -19,9 +19,9 @@ //@ only-linux // //@ revisions:ASAN ASAN-FAT-LTO -//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static -//@[ASAN] compile-flags: -//@[ASAN-FAT-LTO] compile-flags: -Cprefer-dynamic=false -Clto=fat +//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static +// [ASAN] no extra compile-flags +//@[ASAN-FAT-LTO] compile-flags: -Cprefer-dynamic=false -Clto=fat #![crate_type = "staticlib"] diff --git a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs index 6b40918dd3af1..02c31fb8e9b03 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-attr-no-sanitize.rs @@ -5,7 +5,7 @@ //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 //@ [x86_64] compile-flags: --target x86_64-unknown-none -//@ [x86_64] needs-llvm-components: +//@ [x86_64] needs-llvm-components: x86 //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs index 942b50deb0284..9a60d51713f56 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs @@ -5,7 +5,7 @@ //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 //@ [x86_64] compile-flags: --target x86_64-unknown-none -//@ [x86_64] needs-llvm-components: +//@ [x86_64] needs-llvm-components: x86 //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-generalize-pointers #![crate_type = "lib"] diff --git a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs index c89d9bdd12176..134f4ff4bfd9a 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs @@ -5,7 +5,7 @@ //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 //@ [x86_64] compile-flags: --target x86_64-unknown-none -//@ [x86_64] needs-llvm-components: +//@ [x86_64] needs-llvm-components: x86 //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers #![crate_type = "lib"] diff --git a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs index 220cae1a4fa37..4328b7fa07dff 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs @@ -5,7 +5,7 @@ //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 //@ [x86_64] compile-flags: --target x86_64-unknown-none -//@ [x86_64] needs-llvm-components: +//@ [x86_64] needs-llvm-components: x86 //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers #![crate_type = "lib"] diff --git a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs index bb9a000590302..81a9db1b97a57 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle-itanium-cxx-abi.rs @@ -5,7 +5,7 @@ //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 //@ [x86_64] compile-flags: --target x86_64-unknown-none -//@ [x86_64] needs-llvm-components: +//@ [x86_64] needs-llvm-components: x86 //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle.rs b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle.rs index 8b844b991429b..61056c2a54e7b 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/emit-kcfi-operand-bundle.rs @@ -5,7 +5,7 @@ //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 //@ [x86_64] compile-flags: --target x86_64-unknown-none -//@ [x86_64] needs-llvm-components: +//@ [x86_64] needs-llvm-components: x86 //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/sanitizer/kcfi/emit-type-metadata-trait-objects.rs b/tests/codegen-llvm/sanitizer/kcfi/emit-type-metadata-trait-objects.rs index 15c107bea158b..182af162d7824 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/emit-type-metadata-trait-objects.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/emit-type-metadata-trait-objects.rs @@ -5,7 +5,7 @@ //@ [aarch64] compile-flags: --target aarch64-unknown-none //@ [aarch64] needs-llvm-components: aarch64 //@ [x86_64] compile-flags: --target x86_64-unknown-none -//@ [x86_64] needs-llvm-components: +//@ [x86_64] needs-llvm-components: x86 //@ compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/sanitizer/memory-track-origins.rs b/tests/codegen-llvm/sanitizer/memory-track-origins.rs index 318c277e10cba..5eb5b356b0510 100644 --- a/tests/codegen-llvm/sanitizer/memory-track-origins.rs +++ b/tests/codegen-llvm/sanitizer/memory-track-origins.rs @@ -5,7 +5,7 @@ //@ revisions:MSAN-0 MSAN-1 MSAN-2 MSAN-1-LTO MSAN-2-LTO // //@ compile-flags: -Zsanitizer=memory -Ctarget-feature=-crt-static -//@[MSAN-0] compile-flags: +// [MSAN-0] no extra compile-flags //@[MSAN-1] compile-flags: -Zsanitizer-memory-track-origins=1 //@[MSAN-2] compile-flags: -Zsanitizer-memory-track-origins //@[MSAN-1-LTO] compile-flags: -Zsanitizer-memory-track-origins=1 -C lto=fat diff --git a/tests/codegen-llvm/ub-checks.rs b/tests/codegen-llvm/ub-checks.rs index 67f5bff08d5bb..c40bc9acc52a1 100644 --- a/tests/codegen-llvm/ub-checks.rs +++ b/tests/codegen-llvm/ub-checks.rs @@ -6,7 +6,7 @@ // but ub-checks are explicitly disabled. //@ revisions: DEBUG NOCHECKS -//@ [DEBUG] compile-flags: +// [DEBUG] no extra compile-flags //@ [NOCHECKS] compile-flags: -Zub-checks=no //@ compile-flags: -Copt-level=3 -Cdebug-assertions=yes diff --git a/tests/debuginfo/unsized.rs b/tests/debuginfo/unsized.rs index 17c5e463fbac2..edd9f5af557d8 100644 --- a/tests/debuginfo/unsized.rs +++ b/tests/debuginfo/unsized.rs @@ -37,7 +37,6 @@ // cdb-check: [...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[4]] // cdb-command:dx _box -// cdb-check: // cdb-check:_box [Type: alloc::boxed::Box >,alloc::alloc::Global>] // cdb-check:[+0x000] pointer : 0x[...] [Type: unsized::Foo > *] // cdb-check:[...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[4]] diff --git a/tests/run-make/link-cfg/rmake.rs b/tests/run-make/link-cfg/rmake.rs index 732de5dbd0b80..18577fb836dd2 100644 --- a/tests/run-make/link-cfg/rmake.rs +++ b/tests/run-make/link-cfg/rmake.rs @@ -12,6 +12,7 @@ //@ ignore-cross-compile // Reason: the compiled binary is executed +//@ needs-llvm-components: x86 use run_make_support::{bare_rustc, build_native_dynamic_lib, build_native_static_lib, run, rustc}; diff --git a/tests/run-make/mismatching-target-triples/rmake.rs b/tests/run-make/mismatching-target-triples/rmake.rs index 6f41eac8cdaf4..1bbe945e0da54 100644 --- a/tests/run-make/mismatching-target-triples/rmake.rs +++ b/tests/run-make/mismatching-target-triples/rmake.rs @@ -4,6 +4,7 @@ // now replaced by a clearer normal error message. This test checks that this aforementioned // error message is used. // See https://github.com/rust-lang/rust/issues/10814 +//@ needs-llvm-components: x86 use run_make_support::rustc; diff --git a/tests/run-make/musl-default-linking/rmake.rs b/tests/run-make/musl-default-linking/rmake.rs index 017444cfcddcb..7bb54e2739c9d 100644 --- a/tests/run-make/musl-default-linking/rmake.rs +++ b/tests/run-make/musl-default-linking/rmake.rs @@ -4,6 +4,7 @@ use run_make_support::{rustc, serde_json}; // Per https://github.com/rust-lang/compiler-team/issues/422, // we should be trying to move these targets to dynamically link // musl libc by default. +//@ needs-llvm-components: aarch64 arm mips powerpc riscv systemz x86 static LEGACY_STATIC_LINKING_TARGETS: &[&'static str] = &[ "aarch64-unknown-linux-musl", "arm-unknown-linux-musleabi", diff --git a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs index fe9587f502228..d43aa9b90ac72 100644 --- a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs +++ b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs @@ -1,4 +1,5 @@ // Test that rustdoc will properly canonicalize the target spec json path just like rustc. +//@ needs-llvm-components: x86 use run_make_support::{cwd, rustc, rustdoc}; diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs index 7e565588ed6bc..7c30a5b21b339 100644 --- a/tests/run-make/target-specs/rmake.rs +++ b/tests/run-make/target-specs/rmake.rs @@ -4,6 +4,7 @@ // with the target flag's bundle of new features to check that compilation either succeeds while // using them correctly, or fails with the right error message when using them improperly. // See https://github.com/rust-lang/rust/pull/16156 +//@ needs-llvm-components: x86 use run_make_support::{diff, rfs, rustc}; diff --git a/tests/ui/README.md b/tests/ui/README.md index 86c9ad9c1ce8a..66c1bb905a792 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -654,10 +654,6 @@ Tests on range patterns where one of the bounds is not a direct value. Tests for the standard library collection [`std::collections::HashMap`](https://doc.rust-lang.org/std/collections/struct.HashMap.html). -## `tests/ui/hello_world/` - -Tests that the basic hello-world program is not somehow broken. - ## `tests/ui/higher-ranked/` Tests for higher-ranked trait bounds. diff --git a/tests/ui/borrowck/liberated-region-from-outer-closure.rs b/tests/ui/borrowck/liberated-region-from-outer-closure.rs new file mode 100644 index 0000000000000..dcc6370b4a12a --- /dev/null +++ b/tests/ui/borrowck/liberated-region-from-outer-closure.rs @@ -0,0 +1,12 @@ +// Regression test for . + +fn example(x: T) -> impl FnMut(&mut ()) { + move |_: &mut ()| { + move || needs_static_lifetime(x); + //~^ ERROR the parameter type `T` may not live long enough + } +} + +fn needs_static_lifetime(obj: T) {} + +fn main() {} diff --git a/tests/ui/borrowck/liberated-region-from-outer-closure.stderr b/tests/ui/borrowck/liberated-region-from-outer-closure.stderr new file mode 100644 index 0000000000000..98b45ac499dcf --- /dev/null +++ b/tests/ui/borrowck/liberated-region-from-outer-closure.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/liberated-region-from-outer-closure.rs:5:17 + | +LL | move || needs_static_lifetime(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the parameter type `T` must be valid for the static lifetime... + | ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | fn example(x: T) -> impl FnMut(&mut ()) { + | +++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/errors/remap-path-prefix-sysroot.rs b/tests/ui/errors/remap-path-prefix-sysroot.rs index 5e2e4fab51de3..f4a2766ff4c06 100644 --- a/tests/ui/errors/remap-path-prefix-sysroot.rs +++ b/tests/ui/errors/remap-path-prefix-sysroot.rs @@ -2,7 +2,7 @@ //@ compile-flags: -g -Ztranslate-remapped-path-to-local-path=yes //@ [with-remap]compile-flags: --remap-path-prefix={{rust-src-base}}=remapped //@ [with-remap]compile-flags: --remap-path-prefix={{src-base}}=remapped-tests-ui -//@ [without-remap]compile-flags: +// [without-remap] no extra compile-flags // The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically // as the remapped revision will not begin with $SRC_DIR_REAL, diff --git a/tests/ui/errors/wrong-target-spec.rs b/tests/ui/errors/wrong-target-spec.rs index a3a0e05d82662..1a9768881122f 100644 --- a/tests/ui/errors/wrong-target-spec.rs +++ b/tests/ui/errors/wrong-target-spec.rs @@ -2,6 +2,7 @@ // checks that such invalid target specs are rejected by the compiler. // See https://github.com/rust-lang/rust/issues/33329 +// ignore-tidy-target-specific-tests //@ needs-llvm-components: x86 //@ compile-flags: --target x86_64_unknown-linux-musl diff --git a/tests/ui/linkage-attr/unstable-flavor.rs b/tests/ui/linkage-attr/unstable-flavor.rs index 6aa9efb58d1f8..5412e248f341f 100644 --- a/tests/ui/linkage-attr/unstable-flavor.rs +++ b/tests/ui/linkage-attr/unstable-flavor.rs @@ -4,9 +4,9 @@ // //@ revisions: bpf ptx //@ [bpf] compile-flags: --target=bpfel-unknown-none -C linker-flavor=bpf --crate-type=rlib -//@ [bpf] needs-llvm-components: +//@ [bpf] needs-llvm-components: bpf //@ [ptx] compile-flags: --target=nvptx64-nvidia-cuda -C linker-flavor=ptx --crate-type=rlib -//@ [ptx] needs-llvm-components: +//@ [ptx] needs-llvm-components: nvptx #![feature(no_core)] #![no_core] diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr index a445534c8d801..2742162c82119 100644 --- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -9,6 +9,9 @@ LL | let mut closure = expect_sig(|p, y| *p = y); for extern "rust-call" fn((&'^0 mut &'^1 i32, &'^2 i32)), (), ] + = note: late-bound region is '?1 + = note: late-bound region is '?2 + = note: late-bound region is '?3 error: lifetime may not live long enough --> $DIR/escape-argument-callee.rs:26:45 diff --git a/tests/ui/nll/closure-requirements/escape-argument.stderr b/tests/ui/nll/closure-requirements/escape-argument.stderr index 7fd1cd8c3e422..22cb0367ad875 100644 --- a/tests/ui/nll/closure-requirements/escape-argument.stderr +++ b/tests/ui/nll/closure-requirements/escape-argument.stderr @@ -9,6 +9,8 @@ LL | let mut closure = expect_sig(|p, y| *p = y); for extern "rust-call" fn((&'^0 mut &'^1 i32, &'^1 i32)), (), ] + = note: late-bound region is '?1 + = note: late-bound region is '?2 note: no external requirements --> $DIR/escape-argument.rs:20:1 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 60087ec992bd6..134ce99014d8a 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -9,6 +9,8 @@ LL | |_outlives1, _outlives2, _outlives3, x, y| { for extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'?2 &'^0 u32>, std::cell::Cell<&'^1 &'?3 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)), (), ] + = note: late-bound region is '?7 + = note: late-bound region is '?8 = note: late-bound region is '?4 = note: late-bound region is '?5 = note: late-bound region is '?6 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr index 7325a9de8b294..f5527eeb2cdba 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -9,6 +9,12 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y for extern "rust-call" fn((&'^0 std::cell::Cell<&'?1 &'^1 u32>, &'^2 std::cell::Cell<&'^3 &'?2 u32>, &'^4 std::cell::Cell<&'^1 u32>, &'^5 std::cell::Cell<&'^3 u32>)), (), ] + = note: late-bound region is '?5 + = note: late-bound region is '?6 + = note: late-bound region is '?7 + = note: late-bound region is '?8 + = note: late-bound region is '?9 + = note: late-bound region is '?10 = note: late-bound region is '?3 = note: late-bound region is '?4 = note: number of external vids: 5 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 621c1ea083b25..e13653f342342 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -9,6 +9,7 @@ LL | foo(cell, |cell_a, cell_x| { for extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&'^0 u32>)), (), ] + = note: late-bound region is '?2 error[E0521]: borrowed data escapes outside of closure --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:22:9 @@ -43,6 +44,7 @@ LL | foo(cell, |cell_a, cell_x| { for extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&'^0 u32>)), (), ] + = note: late-bound region is '?2 = note: number of external vids: 2 = note: where '?1: '?0 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index b9365c94a1bed..9e9eae985973a 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -9,6 +9,11 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { for extern "rust-call" fn((&'^0 std::cell::Cell<&'?1 &'^1 u32>, &'^2 std::cell::Cell<&'^1 u32>, &'^3 std::cell::Cell<&'^4 u32>)), (), ] + = note: late-bound region is '?4 + = note: late-bound region is '?5 + = note: late-bound region is '?6 + = note: late-bound region is '?7 + = note: late-bound region is '?8 = note: late-bound region is '?2 = note: late-bound region is '?3 = note: number of external vids: 4 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index e5d2867103cfc..303fcd4cdfcf3 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -9,6 +9,12 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y for extern "rust-call" fn((&'^0 std::cell::Cell<&'?1 &'^1 u32>, &'^2 std::cell::Cell<&'?2 &'^3 u32>, &'^4 std::cell::Cell<&'^1 u32>, &'^5 std::cell::Cell<&'^3 u32>)), (), ] + = note: late-bound region is '?5 + = note: late-bound region is '?6 + = note: late-bound region is '?7 + = note: late-bound region is '?8 + = note: late-bound region is '?9 + = note: late-bound region is '?10 = note: late-bound region is '?3 = note: late-bound region is '?4 = note: number of external vids: 5 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr index a14bfb06e831e..aa75b4c811c19 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -9,6 +9,8 @@ LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { for extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'^1 &'?2 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)), (), ] + = note: late-bound region is '?5 + = note: late-bound region is '?6 = note: late-bound region is '?3 = note: late-bound region is '?4 = note: number of external vids: 5 diff --git a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr index 49c65d77ddded..30ee259d3dceb 100644 --- a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr +++ b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr @@ -9,6 +9,8 @@ LL | |_outlives1, _outlives2, x, y| { for extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'^1 &'?2 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)), (), ] + = note: late-bound region is '?4 + = note: late-bound region is '?5 = note: late-bound region is '?3 = note: number of external vids: 4 = note: where '?1: '?2 diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index f48ed2823ddb1..6b04e346c6971 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -9,6 +9,11 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { for extern "rust-call" fn((&'^0 std::cell::Cell<&'^1 &'?1 u32>, &'^2 std::cell::Cell<&'^3 u32>, &'^4 std::cell::Cell<&'^1 u32>)), (), ] + = note: late-bound region is '?4 + = note: late-bound region is '?5 + = note: late-bound region is '?6 + = note: late-bound region is '?7 + = note: late-bound region is '?8 = note: late-bound region is '?2 = note: late-bound region is '?3 diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index a090e94593fe6..ae2129c65f2c0 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -9,6 +9,12 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y for extern "rust-call" fn((&'^0 std::cell::Cell<&'^1 &'?1 u32>, &'^2 std::cell::Cell<&'^3 &'?2 u32>, &'^4 std::cell::Cell<&'^1 u32>, &'^5 std::cell::Cell<&'^3 u32>)), (), ] + = note: late-bound region is '?5 + = note: late-bound region is '?6 + = note: late-bound region is '?7 + = note: late-bound region is '?8 + = note: late-bound region is '?9 + = note: late-bound region is '?10 = note: late-bound region is '?3 = note: late-bound region is '?4 diff --git a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr index bc5c04a27a3e6..1f1cce1e88546 100644 --- a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -9,6 +9,8 @@ LL | expect_sig(|a, b| b); // ought to return `a` for extern "rust-call" fn((&'^0 i32, &'^1 i32)) -> &'^0 i32, (), ] + = note: late-bound region is '?1 + = note: late-bound region is '?2 error: lifetime may not live long enough --> $DIR/return-wrong-bound-region.rs:11:23 diff --git a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index e58764354c032..396e149554ce8 100644 --- a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -9,6 +9,8 @@ LL | twice(cell, value, |a, b| invoke(a, b)); for extern "rust-call" fn((std::option::Option>, &'^1 T)), (), ] + = note: late-bound region is '?2 + = note: late-bound region is '?3 = note: number of external vids: 2 = note: where T: '?1 @@ -31,6 +33,8 @@ LL | twice(cell, value, |a, b| invoke(a, b)); for extern "rust-call" fn((std::option::Option>, &'^1 T)), (), ] + = note: late-bound region is '?3 + = note: late-bound region is '?4 = note: late-bound region is '?2 = note: number of external vids: 3 = note: where T: '?1 diff --git a/tests/ui/target_modifiers/defaults_check.rs b/tests/ui/target_modifiers/defaults_check.rs index de72acd32bc18..ce1d534fd7573 100644 --- a/tests/ui/target_modifiers/defaults_check.rs +++ b/tests/ui/target_modifiers/defaults_check.rs @@ -6,7 +6,7 @@ //@ needs-llvm-components: x86 //@ revisions: ok ok_explicit error -//@[ok] compile-flags: +// [ok] no extra compile-flags //@[ok_explicit] compile-flags: -Zreg-struct-return=false //@[error] compile-flags: -Zreg-struct-return=true //@[ok] check-pass diff --git a/tests/ui/target_modifiers/incompatible_fixedx18.rs b/tests/ui/target_modifiers/incompatible_fixedx18.rs index 6c13984f608ec..5ba676406ee30 100644 --- a/tests/ui/target_modifiers/incompatible_fixedx18.rs +++ b/tests/ui/target_modifiers/incompatible_fixedx18.rs @@ -5,7 +5,7 @@ //@ revisions:allow_match allow_mismatch error_generated //@[allow_match] compile-flags: -Zfixed-x18 //@[allow_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=fixed-x18 -//@[error_generated] compile-flags: +// [error_generated] no extra compile-flags //@[allow_mismatch] check-pass //@[allow_match] check-pass diff --git a/tests/ui/target_modifiers/incompatible_regparm.rs b/tests/ui/target_modifiers/incompatible_regparm.rs index 395c26fc2c02d..e76bfc976a193 100644 --- a/tests/ui/target_modifiers/incompatible_regparm.rs +++ b/tests/ui/target_modifiers/incompatible_regparm.rs @@ -5,7 +5,7 @@ //@ revisions:allow_regparm_mismatch allow_no_value error_generated //@[allow_regparm_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=regparm //@[allow_no_value] compile-flags: -Cunsafe-allow-abi-mismatch -//@[error_generated] compile-flags: +// [error_generated] no extra compile-flags //@[allow_regparm_mismatch] check-pass #![feature(no_core)] diff --git a/tests/ui/target_modifiers/no_value_bool.rs b/tests/ui/target_modifiers/no_value_bool.rs index ceba40afa8968..72130f8737c02 100644 --- a/tests/ui/target_modifiers/no_value_bool.rs +++ b/tests/ui/target_modifiers/no_value_bool.rs @@ -8,7 +8,7 @@ //@ revisions: ok ok_explicit error error_explicit //@[ok] compile-flags: -Zreg-struct-return //@[ok_explicit] compile-flags: -Zreg-struct-return=true -//@[error] compile-flags: +// [error] no extra compile-flags //@[error_explicit] compile-flags: -Zreg-struct-return=false //@[ok] check-pass //@[ok_explicit] check-pass diff --git a/tests/ui/hello_world/main.rs b/tests/ui/warnings/hello-world.rs similarity index 100% rename from tests/ui/hello_world/main.rs rename to tests/ui/warnings/hello-world.rs