Auto merge of #154746 - matthiaskrgr:rollup-uWUN35u, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang/rust#154696 (rustdoc_missing_doc_code_examples: lint on macro_rules macros)
 - rust-lang/rust#154698 (Improve workings of the `desc` query modifier and custom query cycle handlers)
 - rust-lang/rust#154713 (Stop compiling when we get resolving crate failure)
 - rust-lang/rust#154736 (Add a regression test for the duplicated `crate` keyword in path suggestions)
 - rust-lang/rust#154739 (ci: update upload-artifact action to v7)
 - rust-lang/rust#154741 (Enforce `#![warn(unreachable_pub)]` in compiletest source)

Failed merges:

 - rust-lang/rust#154605 (Make `span_suggestions` always verbose)
This commit is contained in:
bors
2026-04-03 10:41:16 +00:00
39 changed files with 626 additions and 448 deletions
+1 -1
View File
@@ -254,7 +254,7 @@ jobs:
df -h
- name: upload artifacts to github
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
# name is set in previous step
name: ${{ env.DOC_ARTIFACT_NAME }}
+2 -2
View File
@@ -66,7 +66,7 @@ jobs:
run: ./src/tools/update-lockfile.sh
- name: upload Cargo.lock artifact for use in PR
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: Cargo-lock
path: |
@@ -75,7 +75,7 @@ jobs:
src/tools/rustbook/Cargo.lock
retention-days: 1
- name: upload cargo-update log artifact for use in PR
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: cargo-updates
path: cargo_update.log
+48 -64
View File
@@ -128,6 +128,7 @@ fn parse(input: ParseStream<'_>) -> Result<Self> {
}
struct Desc {
// This ident is always `desc` but we need it for its span, for `crate::query::modifiers`.
modifier: Ident,
expr_list: Punctuated<Expr, Token![,]>,
}
@@ -141,6 +142,7 @@ struct QueryModifiers {
desc: Desc,
eval_always: Option<Ident>,
feedable: Option<Ident>,
handle_cycle_error: Option<Ident>,
no_force: Option<Ident>,
no_hash: Option<Ident>,
separate_provide_extern: Option<Ident>,
@@ -148,15 +150,18 @@ struct QueryModifiers {
}
fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
// tidy-alphabetical-start
let mut arena_cache = None;
let mut cache_on_disk = None;
let mut depth_limit = None;
let mut desc = None;
let mut eval_always = None;
let mut feedable = None;
let mut handle_cycle_error = None;
let mut no_force = None;
let mut no_hash = None;
let mut eval_always = None;
let mut depth_limit = None;
let mut separate_provide_extern = None;
let mut feedable = None;
// tidy-alphabetical-end
while !input.is_empty() {
let modifier: Ident = input.parse()?;
@@ -170,29 +175,31 @@ macro_rules! try_insert {
};
}
if modifier == "desc" {
if modifier == "arena_cache" {
try_insert!(arena_cache = modifier);
} else if modifier == "cache_on_disk" {
try_insert!(cache_on_disk = modifier);
} else if modifier == "depth_limit" {
try_insert!(depth_limit = modifier);
} else if modifier == "desc" {
// Parse a description modifier like:
// `desc { "foo {}", tcx.item_path(key) }`
let attr_content;
braced!(attr_content in input);
let expr_list = attr_content.parse_terminated(Expr::parse, Token![,])?;
try_insert!(desc = Desc { modifier, expr_list });
} else if modifier == "cache_on_disk" {
try_insert!(cache_on_disk = modifier);
} else if modifier == "arena_cache" {
try_insert!(arena_cache = modifier);
} else if modifier == "eval_always" {
try_insert!(eval_always = modifier);
} else if modifier == "feedable" {
try_insert!(feedable = modifier);
} else if modifier == "handle_cycle_error" {
try_insert!(handle_cycle_error = modifier);
} else if modifier == "no_force" {
try_insert!(no_force = modifier);
} else if modifier == "no_hash" {
try_insert!(no_hash = modifier);
} else if modifier == "eval_always" {
try_insert!(eval_always = modifier);
} else if modifier == "depth_limit" {
try_insert!(depth_limit = modifier);
} else if modifier == "separate_provide_extern" {
try_insert!(separate_provide_extern = modifier);
} else if modifier == "feedable" {
try_insert!(feedable = modifier);
} else {
return Err(Error::new(modifier.span(), "unknown query modifier"));
}
@@ -201,15 +208,18 @@ macro_rules! try_insert {
return Err(input.error("no description provided"));
};
Ok(QueryModifiers {
// tidy-alphabetical-start
arena_cache,
cache_on_disk,
depth_limit,
desc,
eval_always,
feedable,
handle_cycle_error,
no_force,
no_hash,
eval_always,
depth_limit,
separate_provide_extern,
feedable,
// tidy-alphabetical-end
})
}
@@ -238,24 +248,40 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
arena_cache,
cache_on_disk,
depth_limit,
desc: _,
desc,
eval_always,
feedable,
handle_cycle_error,
no_force,
no_hash,
separate_provide_extern,
// tidy-alphabetical-end
} = &query.modifiers;
// tidy-alphabetical-start
let arena_cache = arena_cache.is_some();
let cache_on_disk = cache_on_disk.is_some();
let depth_limit = depth_limit.is_some();
let desc = {
// Put a description closure in the `desc` modifier.
let key_pat = &query.key_pat;
let key_ty = &query.key_ty;
let desc_expr_list = &desc.expr_list;
quote! {
{
#[allow(unused_variables)]
|tcx: TyCtxt<'tcx>, #key_pat: #key_ty| format!(#desc_expr_list)
}
}
};
let eval_always = eval_always.is_some();
let feedable = feedable.is_some();
let handle_cycle_error = handle_cycle_error.is_some();
let no_force = no_force.is_some();
let no_hash = no_hash.is_some();
let returns_error_guaranteed = returns_error_guaranteed(&query.return_ty);
let separate_provide_extern = separate_provide_extern.is_some();
// tidy-alphabetical-end
// Giving an input span to the modifier names in the modifier list seems
// to give slightly more helpful errors when one of the callback macros
@@ -268,8 +294,10 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
arena_cache: #arena_cache,
cache_on_disk: #cache_on_disk,
depth_limit: #depth_limit,
desc: #desc,
eval_always: #eval_always,
feedable: #feedable,
handle_cycle_error: #handle_cycle_error,
no_force: #no_force,
no_hash: #no_hash,
returns_error_guaranteed: #returns_error_guaranteed,
@@ -305,37 +333,6 @@ fn doc_comment_from_desc(list: &Punctuated<Expr, token::Comma>) -> Result<Attrib
Ok(parse_quote! { #[doc = #doc_string] })
}
/// Contains token streams that are used to accumulate per-query helper
/// functions, to be used by the final output of `rustc_queries!`.
///
/// Helper items typically have the same name as the query they relate to,
/// and expect to be interpolated into a dedicated module.
#[derive(Default)]
struct HelperTokenStreams {
description_fns_stream: proc_macro2::TokenStream,
}
fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) {
let Query { name, key_pat, key_ty, modifiers, .. } = &query;
// Replace span for `name` to make rust-analyzer ignore it.
let mut erased_name = name.clone();
erased_name.set_span(Span::call_site());
let Desc { expr_list, .. } = &modifiers.desc;
let desc = quote! {
#[allow(unused_variables)]
pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: #key_ty) -> String {
format!(#expr_list)
}
};
streams.description_fns_stream.extend(quote! {
#desc
});
}
/// Add hints for rust-analyzer
fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::TokenStream) {
// Add links to relevant modifiers
@@ -366,8 +363,10 @@ macro_rules! doc_link {
arena_cache,
cache_on_disk,
depth_limit,
// `desc` is handled above
eval_always,
feedable,
handle_cycle_error,
no_force,
no_hash,
separate_provide_extern,
@@ -409,7 +408,6 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
let mut query_stream = quote! {};
let mut non_query_stream = quote! {};
let mut helpers = HelperTokenStreams::default();
let mut analyzer_stream = quote! {};
let mut errors = quote! {};
@@ -462,11 +460,8 @@ fn #name(#key_ty) #return_ty
}
add_to_analyzer_stream(&query, &mut analyzer_stream);
make_helpers_for_query(&query, &mut helpers);
}
let HelperTokenStreams { description_fns_stream } = helpers;
TokenStream::from(quote! {
/// Higher-order macro that invokes the specified macro with (a) a list of all query
/// signatures (including modifiers), and (b) a list of non-query names. This allows
@@ -490,17 +485,6 @@ mod _analyzer_hints {
#analyzer_stream
}
/// Functions that format a human-readable description of each query
/// and its key, as specified by the `desc` query modifier.
///
/// (The leading `_` avoids collisions with actual query names when
/// expanded in `rustc_middle::queries`, and makes this macro-generated
/// module easier to search for.)
pub mod _description_fns {
use super::*;
#description_fns_stream
}
#errors
})
}
+15
View File
@@ -77,6 +77,9 @@ pub struct CStore {
unused_externs: Vec<Symbol>,
used_extern_options: FxHashSet<Symbol>,
/// Whether there was a failure in resolving crate,
/// it's used to suppress some diagnostics that would otherwise too noisey.
has_crate_resolve_with_fail: bool,
}
impl std::fmt::Debug for CStore {
@@ -328,6 +331,10 @@ pub(crate) fn has_alloc_error_handler(&self) -> bool {
self.has_alloc_error_handler
}
pub fn had_extern_crate_load_failure(&self) -> bool {
self.has_crate_resolve_with_fail
}
pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) {
let json_unused_externs = tcx.sess.opts.json_unused_externs;
@@ -514,6 +521,7 @@ pub fn new(metadata_loader: Box<MetadataLoaderDyn>) -> CStore {
resolved_externs: UnordMap::default(),
unused_externs: Vec::new(),
used_extern_options: Default::default(),
has_crate_resolve_with_fail: false,
}
}
@@ -723,6 +731,13 @@ fn resolve_crate<'tcx>(
}
Err(err) => {
debug!("failed to resolve crate {} {:?}", name, dep_kind);
// crate maybe injrected with `standard_library_imports::inject`, their span is dummy.
// we ignore compiler-injected prelude/sysroot loads here so they don't suppress
// unrelated diagnostics, such as `unsupported targets for std library` etc,
// these maybe helpful for users to resolve crate loading failure.
if !tcx.sess.dcx().has_errors().is_some() && !span.is_dummy() {
self.has_crate_resolve_with_fail = true;
}
let missing_core = self
.maybe_resolve_crate(
tcx,
+5
View File
@@ -583,6 +583,7 @@
// messages about cycles that then abort.)
query check_representability(key: LocalDefId) {
desc { "checking if `{}` is representable", tcx.def_path_str(key) }
handle_cycle_error
// We don't want recursive representability calls to be forced with
// incremental compilation because, if a cycle occurs, we need the
// entire cycle to be in memory for diagnostics.
@@ -593,6 +594,7 @@
/// details, particularly on the modifiers.
query check_representability_adt_ty(key: Ty<'tcx>) {
desc { "checking if `{}` is representable", key }
handle_cycle_error
no_force
}
@@ -1032,6 +1034,7 @@
query variances_of(def_id: DefId) -> &'tcx [ty::Variance] {
desc { "computing the variances of `{}`", tcx.def_path_str(def_id) }
cache_on_disk
handle_cycle_error
separate_provide_extern
}
@@ -1164,6 +1167,7 @@
query fn_sig(key: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
desc { "computing function signature of `{}`", tcx.def_path_str(key) }
cache_on_disk
handle_cycle_error
separate_provide_extern
}
@@ -1756,6 +1760,7 @@
) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
depth_limit
desc { "computing layout of `{}`", key.value }
handle_cycle_error
}
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
@@ -58,6 +58,14 @@
/// Generate a `feed` method to set the query's value from another query.
pub(crate) struct feedable;
/// # `handle_cycle_error` query modifier
///
/// The default behaviour for a query cycle is to emit a cycle error and halt
/// compilation. Queries with this modifier will instead use a custom handler,
/// which must be provided at `rustc_query_impl::handle_cycle_error::$name`,
/// where `$name` is the query name.
pub(crate) struct handle_cycle_error;
/// # `no_force` query modifier
///
/// Dep nodes of queries with this modifier will never be "forced" when trying
+3 -2
View File
@@ -301,8 +301,10 @@ fn $name:ident($($K:tt)*) -> $V:ty
arena_cache: $arena_cache:literal,
cache_on_disk: $cache_on_disk:literal,
depth_limit: $depth_limit:literal,
desc: $desc:expr,
eval_always: $eval_always:literal,
feedable: $feedable:literal,
handle_cycle_error: $handle_cycle_error:literal,
no_force: $no_force:literal,
no_hash: $no_hash:literal,
returns_error_guaranteed: $returns_error_guaranteed:literal,
@@ -435,8 +437,7 @@ pub fn query_name(&self) -> &'static str {
pub fn description(&self, tcx: TyCtxt<'tcx>) -> String {
let (name, description) = ty::print::with_no_queries!(match self {
$(
TaggedQueryKey::$name(key) =>
(stringify!($name), _description_fns::$name(tcx, *key)),
TaggedQueryKey::$name(key) => (stringify!($name), ($desc)(tcx, *key)),
)*
});
if tcx.sess.verbose_internals() {
@@ -135,8 +135,10 @@ fn $name:ident($K:ty) -> $V:ty
arena_cache: $arena_cache:literal,
cache_on_disk: $cache_on_disk:literal,
depth_limit: $depth_limit:literal,
desc: $desc:expr,
eval_always: $eval_always:literal,
feedable: $feedable:literal,
handle_cycle_error: $handle_cycle_error:literal,
no_force: $no_force:literal,
no_hash: $no_hash:literal,
returns_error_guaranteed: $returns_error_guaranteed:literal,
@@ -9,48 +9,29 @@
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::bug;
use rustc_middle::queries::{QueryVTables, TaggedQueryKey};
use rustc_middle::queries::TaggedQueryKey;
use rustc_middle::query::Cycle;
use rustc_middle::query::erase::erase_val;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::{ErrorGuaranteed, Span};
use crate::job::create_cycle_error;
pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) {
vtables.fn_sig.handle_cycle_error_fn = |tcx, key, _, err| {
let guar = err.delay_as_bug();
erase_val(fn_sig(tcx, key, guar))
};
vtables.check_representability.handle_cycle_error_fn =
|tcx, _, cycle, _err| check_representability(tcx, cycle);
vtables.check_representability_adt_ty.handle_cycle_error_fn =
|tcx, _, cycle, _err| check_representability(tcx, cycle);
vtables.variances_of.handle_cycle_error_fn = |tcx, key, _, err| {
let _guar = err.delay_as_bug();
erase_val(variances_of(tcx, key))
};
vtables.layout_of.handle_cycle_error_fn = |tcx, _, cycle, err| {
let _guar = err.delay_as_bug();
erase_val(Err(layout_of(tcx, cycle)))
}
}
// Default cycle handler used for all queries that don't use the `handle_cycle_error` query
// modifier.
pub(crate) fn default(err: Diag<'_>) -> ! {
let guar = err.emit();
guar.raise_fatal()
}
fn fn_sig<'tcx>(
pub(crate) fn fn_sig<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
guar: ErrorGuaranteed,
_: Cycle<'tcx>,
err: Diag<'_>,
) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
let guar = err.delay_as_bug();
let err = Ty::new_error(tcx, guar);
let arity = if let Some(node) = tcx.hir_get_if_local(def_id)
@@ -71,7 +52,25 @@ fn fn_sig<'tcx>(
)))
}
fn check_representability<'tcx>(tcx: TyCtxt<'tcx>, cycle: Cycle<'tcx>) -> ! {
pub(crate) fn check_representability<'tcx>(
tcx: TyCtxt<'tcx>,
_key: LocalDefId,
cycle: Cycle<'tcx>,
_err: Diag<'_>,
) {
check_representability_inner(tcx, cycle);
}
pub(crate) fn check_representability_adt_ty<'tcx>(
tcx: TyCtxt<'tcx>,
_key: Ty<'tcx>,
cycle: Cycle<'tcx>,
_err: Diag<'_>,
) {
check_representability_inner(tcx, cycle);
}
fn check_representability_inner<'tcx>(tcx: TyCtxt<'tcx>, cycle: Cycle<'tcx>) -> ! {
let mut item_and_field_ids = Vec::new();
let mut representable_ids = FxHashSet::default();
for frame in &cycle.frames {
@@ -102,7 +101,13 @@ fn check_representability<'tcx>(tcx: TyCtxt<'tcx>, cycle: Cycle<'tcx>) -> ! {
guar.raise_fatal()
}
fn variances_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [ty::Variance] {
pub(crate) fn variances_of<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
_cycle: Cycle<'tcx>,
err: Diag<'_>,
) -> &'tcx [ty::Variance] {
let _guar = err.delay_as_bug();
let n = tcx.generics_of(def_id).own_params.len();
tcx.arena.alloc_from_iter(iter::repeat_n(ty::Bivariant, n))
}
@@ -126,7 +131,13 @@ fn search_for_cycle_permutation<Q, T>(
otherwise()
}
fn layout_of<'tcx>(tcx: TyCtxt<'tcx>, cycle: Cycle<'tcx>) -> &'tcx ty::layout::LayoutError<'tcx> {
pub(crate) fn layout_of<'tcx>(
tcx: TyCtxt<'tcx>,
_key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
cycle: Cycle<'tcx>,
err: Diag<'_>,
) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
let _guar = err.delay_as_bug();
let diag = search_for_cycle_permutation(
&cycle.frames,
|frames| {
+1 -3
View File
@@ -48,11 +48,9 @@ pub fn query_system<'tcx>(
on_disk_cache: Option<OnDiskCache>,
incremental: bool,
) -> QuerySystem<'tcx> {
let mut query_vtables = query_impl::make_query_vtables(incremental);
handle_cycle_error::specialize_query_vtables(&mut query_vtables);
QuerySystem {
arenas: Default::default(),
query_vtables,
query_vtables: query_impl::make_query_vtables(incremental),
side_effects: Default::default(),
on_disk_cache,
local_providers,
+9 -4
View File
@@ -19,8 +19,10 @@ fn $name:ident($K:ty) -> $V:ty
arena_cache: $arena_cache:literal,
cache_on_disk: $cache_on_disk:literal,
depth_limit: $depth_limit:literal,
desc: $desc:expr,
eval_always: $eval_always:literal,
feedable: $feedable:literal,
handle_cycle_error: $handle_cycle_error:literal,
no_force: $no_force:literal,
no_hash: $no_hash:literal,
returns_error_guaranteed: $returns_error_guaranteed:literal,
@@ -143,7 +145,6 @@ pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
-> QueryVTable<'tcx, rustc_middle::queries::$name::Cache<'tcx>>
{
use rustc_middle::queries::$name::Value;
QueryVTable {
name: stringify!($name),
eval_always: $eval_always,
@@ -176,9 +177,13 @@ pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
#[cfg(not($cache_on_disk))]
try_load_from_disk_fn: |_tcx, _key, _prev_index, _index| None,
// The default just emits `err` and then aborts.
// `handle_cycle_error::specialize_query_vtables` overwrites this default
// for certain queries.
#[cfg($handle_cycle_error)]
handle_cycle_error_fn: |tcx, key, cycle, err| {
use rustc_middle::query::erase::erase_val;
erase_val($crate::handle_cycle_error::$name(tcx, key, cycle, err))
},
#[cfg(not($handle_cycle_error))]
handle_cycle_error_fn: |_tcx, _key, _cycle, err| {
$crate::handle_cycle_error::default(err)
},
+4
View File
@@ -674,6 +674,10 @@ pub(crate) fn finalize_imports(&mut self) {
}
}
if self.cstore().had_extern_crate_load_failure() {
self.tcx.sess.dcx().abort_if_errors();
}
if !errors.is_empty() {
self.throw_unresolved_import_error(errors, glob_error);
return;
+7
View File
@@ -453,6 +453,13 @@ pub(crate) fn is_unstable(&self) -> bool {
self.stability.is_some_and(|x| x.is_unstable())
}
pub(crate) fn is_exported_macro(&self) -> bool {
match self.kind {
ItemKind::MacroItem(..) => find_attr!(&self.attrs.other_attrs, MacroExport { .. }),
_ => false,
}
}
pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
self.item_id
.as_def_id()
@@ -56,7 +56,8 @@ fn visit_test(&mut self, _: String, config: LangString, _: MdRelLine) {
}
pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
if !cx.cache.effective_visibilities.is_directly_public(cx.tcx, item.item_id.expect_def_id())
if !(cx.cache.effective_visibilities.is_directly_public(cx.tcx, item.item_id.expect_def_id())
|| item.is_exported_macro())
|| matches!(
item.kind,
clean::StructFieldItem(_)
+1 -4
View File
@@ -3,7 +3,6 @@
use std::mem;
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::find_attr;
use rustc_middle::ty::TyCtxt;
use tracing::debug;
@@ -113,9 +112,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
clean::ImplItem(..) => true,
// If the macro has the `#[macro_export]` attribute, it means it's accessible at the
// crate level so it should be handled differently.
clean::MacroItem(..) => {
find_attr!(&i.attrs.other_attrs, MacroExport { .. })
}
clean::MacroItem(..) => i.is_exported_macro(),
_ => false,
};
let mut is_hidden = has_doc_hidden;
+158 -158
View File
@@ -14,7 +14,7 @@
string_enum! {
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum TestMode {
pub(crate) enum TestMode {
Pretty => "pretty",
DebugInfo => "debuginfo",
Codegen => "codegen",
@@ -34,7 +34,7 @@ pub enum TestMode {
}
impl TestMode {
pub fn aux_dir_disambiguator(self) -> &'static str {
pub(crate) fn aux_dir_disambiguator(self) -> &'static str {
// Pretty-printing tests could run concurrently, and if they do,
// they need to keep their output segregated.
match self {
@@ -43,7 +43,7 @@ pub fn aux_dir_disambiguator(self) -> &'static str {
}
}
pub fn output_dir_disambiguator(self) -> &'static str {
pub(crate) fn output_dir_disambiguator(self) -> &'static str {
// Coverage tests use the same test files for multiple test modes,
// so each mode should have a separate output directory.
match self {
@@ -56,7 +56,7 @@ pub fn output_dir_disambiguator(self) -> &'static str {
// Note that coverage tests use the same test files for multiple test modes.
string_enum! {
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum TestSuite {
pub(crate) enum TestSuite {
AssemblyLlvm => "assembly-llvm",
CodegenLlvm => "codegen-llvm",
CodegenUnits => "codegen-units",
@@ -83,7 +83,7 @@ pub enum TestSuite {
string_enum! {
#[derive(Clone, Copy, PartialEq, Debug, Hash)]
pub enum PassMode {
pub(crate) enum PassMode {
Check => "check",
Build => "build",
Run => "run",
@@ -92,7 +92,7 @@ pub enum PassMode {
string_enum! {
#[derive(Clone, Copy, PartialEq, Debug, Hash)]
pub enum RunResult {
pub(crate) enum RunResult {
Pass => "run-pass",
Fail => "run-fail",
Crash => "run-crash",
@@ -100,7 +100,7 @@ pub enum RunResult {
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub enum RunFailMode {
pub(crate) enum RunFailMode {
/// Running the program must make it exit with a regular failure exit code
/// in the range `1..=127`. If the program is terminated by e.g. a signal
/// the test will fail.
@@ -117,7 +117,7 @@ pub enum RunFailMode {
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub enum FailMode {
pub(crate) enum FailMode {
Check,
Build,
Run(RunFailMode),
@@ -125,7 +125,7 @@ pub enum FailMode {
string_enum! {
#[derive(Clone, Debug, PartialEq)]
pub enum CompareMode {
pub(crate) enum CompareMode {
Polonius => "polonius",
NextSolver => "next-solver",
NextSolverCoherence => "next-solver-coherence",
@@ -136,7 +136,7 @@ pub enum CompareMode {
string_enum! {
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Debugger {
pub(crate) enum Debugger {
Cdb => "cdb",
Gdb => "gdb",
Lldb => "lldb",
@@ -145,7 +145,7 @@ pub enum Debugger {
#[derive(Clone, Copy, Debug, PartialEq, Default, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum PanicStrategy {
pub(crate) enum PanicStrategy {
#[default]
Unwind,
Abort,
@@ -162,7 +162,7 @@ pub(crate) fn for_miropt_test_tools(&self) -> miropt_test_tools::PanicStrategy {
#[derive(Clone, Debug, PartialEq, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Sanitizer {
pub(crate) enum Sanitizer {
Address,
Cfi,
Dataflow,
@@ -180,7 +180,7 @@ pub enum Sanitizer {
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CodegenBackend {
pub(crate) enum CodegenBackend {
Cranelift,
Gcc,
Llvm,
@@ -200,7 +200,7 @@ fn try_from(value: &'a str) -> Result<Self, Self::Error> {
}
impl CodegenBackend {
pub fn as_str(self) -> &'static str {
pub(crate) fn as_str(self) -> &'static str {
match self {
Self::Cranelift => "cranelift",
Self::Gcc => "gcc",
@@ -208,7 +208,7 @@ pub fn as_str(self) -> &'static str {
}
}
pub fn is_llvm(self) -> bool {
pub(crate) fn is_llvm(self) -> bool {
matches!(self, Self::Llvm)
}
}
@@ -235,7 +235,7 @@ pub fn is_llvm(self) -> bool {
/// FIXME: audit these options to make sure we are not hashing less than necessary for build stamp
/// (for changed test detection).
#[derive(Debug, Clone)]
pub struct Config {
pub(crate) struct Config {
/// Some [`TestMode`]s support [snapshot testing], where a *reference snapshot* of outputs (of
/// `stdout`, `stderr`, or other form of artifacts) can be compared to the *actual output*.
///
@@ -243,17 +243,17 @@ pub struct Config {
/// `compiletest` will only try to compare.
///
/// [snapshot testing]: https://jestjs.io/docs/snapshot-testing
pub bless: bool,
pub(crate) bless: bool,
/// Attempt to stop as soon as possible after any test fails. We may still run a few more tests
/// before stopping when multiple test threads are used.
pub fail_fast: bool,
pub(crate) fail_fast: bool,
/// Path to libraries needed to run the *staged* `rustc`-under-test on the **host** platform.
///
/// For example:
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/stage1/bin/lib`
pub host_compile_lib_path: Utf8PathBuf,
pub(crate) host_compile_lib_path: Utf8PathBuf,
/// Path to libraries needed to run the compiled executable for the **target** platform. This
/// corresponds to the **target** sysroot libraries, including the **target** standard library.
@@ -264,7 +264,7 @@ pub struct Config {
/// FIXME: this is very under-documented in conjunction with the `remote-test-client` scheme and
/// `RUNNER` scheme to actually run the target executable under the target platform environment,
/// cf. [`Self::remote_test_client`] and [`Self::runner`].
pub target_run_lib_path: Utf8PathBuf,
pub(crate) target_run_lib_path: Utf8PathBuf,
/// Path to the `rustc`-under-test.
///
@@ -283,7 +283,7 @@ pub struct Config {
///
/// It is possible for this `rustc` to be a stage 0 `rustc` if explicitly configured with the
/// bootstrap option `build.compiletest-allow-stage0=true` and specifying `--stage=0`.
pub rustc_path: Utf8PathBuf,
pub(crate) rustc_path: Utf8PathBuf,
/// Path to a *staged* **host** platform cargo executable (unless stage 0 is forced). This
/// staged `cargo` is only used within `run-make` test recipes during recipe run time (and is
@@ -294,14 +294,14 @@ pub struct Config {
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/stage1-tools-bin/cargo`
///
/// FIXME: maybe rename this to reflect that this is a *staged* host cargo.
pub cargo_path: Option<Utf8PathBuf>,
pub(crate) cargo_path: Option<Utf8PathBuf>,
/// Path to the stage 0 `rustc` used to build `run-make` recipes. This must not be confused with
/// [`Self::rustc_path`].
///
/// For example:
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/stage0/bin/rustc`
pub stage0_rustc_path: Option<Utf8PathBuf>,
pub(crate) stage0_rustc_path: Option<Utf8PathBuf>,
/// Path to the stage 1 or higher `rustc` used to obtain target information via
/// `--print=all-target-specs-json` and similar queries.
@@ -310,35 +310,35 @@ pub struct Config {
/// But when running "stage 1" ui-fulldeps tests, `rustc_path` is a stage 0
/// compiler, whereas target specs must be obtained from a stage 1+ compiler
/// (in case the JSON format has changed since the last bootstrap bump).
pub query_rustc_path: Option<Utf8PathBuf>,
pub(crate) query_rustc_path: Option<Utf8PathBuf>,
/// Path to the `rustdoc`-under-test. Like [`Self::rustc_path`], this `rustdoc` is *staged*.
pub rustdoc_path: Option<Utf8PathBuf>,
pub(crate) rustdoc_path: Option<Utf8PathBuf>,
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
pub coverage_dump_path: Option<Utf8PathBuf>,
pub(crate) coverage_dump_path: Option<Utf8PathBuf>,
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
pub python: String,
pub(crate) python: String,
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
pub jsondocck_path: Option<Utf8PathBuf>,
pub(crate) jsondocck_path: Option<Utf8PathBuf>,
/// Path to the `src/tools/jsondoclint/` bootstrap tool executable.
pub jsondoclint_path: Option<Utf8PathBuf>,
pub(crate) jsondoclint_path: Option<Utf8PathBuf>,
/// Path to a host LLVM `FileCheck` executable.
pub llvm_filecheck: Option<Utf8PathBuf>,
pub(crate) llvm_filecheck: Option<Utf8PathBuf>,
/// Path to a host LLVM bintools directory.
///
/// For example:
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/llvm/bin`
pub llvm_bin_dir: Option<Utf8PathBuf>,
pub(crate) llvm_bin_dir: Option<Utf8PathBuf>,
/// The path to the **target** `clang` executable to run `clang`-based tests with. If `None`,
/// then these tests will be ignored.
pub run_clang_based_tests_with: Option<Utf8PathBuf>,
pub(crate) run_clang_based_tests_with: Option<Utf8PathBuf>,
/// Path to the directory containing the sources. This corresponds to the root folder of a
/// `rust-lang/rust` checkout.
@@ -348,27 +348,27 @@ pub struct Config {
///
/// FIXME: this name is confusing, because this is actually `$checkout_root`, **not** the
/// `$checkout_root/src/` folder.
pub src_root: Utf8PathBuf,
pub(crate) src_root: Utf8PathBuf,
/// Absolute path to the test suite directory.
///
/// For example:
/// - `/home/ferris/rust/tests/ui`
/// - `/home/ferris/rust/tests/coverage`
pub src_test_suite_root: Utf8PathBuf,
pub(crate) src_test_suite_root: Utf8PathBuf,
/// Path to the top-level build directory used by bootstrap.
///
/// For example:
/// - `/home/ferris/rust/build`
pub build_root: Utf8PathBuf,
pub(crate) build_root: Utf8PathBuf,
/// Path to the build directory used by the current test suite.
///
/// For example:
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/test/ui`
/// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/test/coverage`
pub build_test_suite_root: Utf8PathBuf,
pub(crate) build_test_suite_root: Utf8PathBuf,
/// Path to the directory containing the sysroot of the `rustc`-under-test.
///
@@ -384,21 +384,21 @@ pub struct Config {
/// stage 0 is forced and no custom stage 0 `rustc` was otherwise specified (so that it
/// *happens* to run against the bootstrap `rustc`, but this non-custom bootstrap `rustc` case
/// is not really supported).
pub sysroot_base: Utf8PathBuf,
pub(crate) sysroot_base: Utf8PathBuf,
/// The number of the stage under test.
pub stage: u32,
pub(crate) stage: u32,
/// The id of the stage under test (stage1-xxx, etc).
///
/// FIXME: reconsider this string; this is hashed for test build stamp.
pub stage_id: String,
pub(crate) stage_id: String,
/// The [`TestMode`]. E.g. [`TestMode::Ui`]. Each test mode can correspond to one or more test
/// suites.
///
/// FIXME: stop using stringly-typed test suites!
pub mode: TestMode,
pub(crate) mode: TestMode,
/// The test suite.
///
@@ -408,7 +408,7 @@ pub struct Config {
/// Note that the same test suite (e.g. `tests/coverage/`) may correspond to multiple test
/// modes, e.g. `tests/coverage/` can be run under both [`TestMode::CoverageRun`] and
/// [`TestMode::CoverageMap`].
pub suite: TestSuite,
pub(crate) suite: TestSuite,
/// When specified, **only** the specified [`Debugger`] will be used to run against the
/// `tests/debuginfo` test suite. When unspecified, `compiletest` will attempt to find all three
@@ -420,30 +420,30 @@ pub struct Config {
/// should have `bootstrap` allow the user to *explicitly* configure the debuggers, and *not*
/// try to implicitly discover some random debugger from the user environment. This makes the
/// debuginfo test suite particularly hard to work with.
pub debugger: Option<Debugger>,
pub(crate) debugger: Option<Debugger>,
/// Run ignored tests *unconditionally*, overriding their ignore reason.
///
/// FIXME: this is wired up through the test execution logic, but **not** accessible from
/// `bootstrap` directly; `compiletest` exposes this as `--ignored`. I.e. you'd have to use `./x
/// test $test_suite -- --ignored=true`.
pub run_ignored: bool,
pub(crate) run_ignored: bool,
/// Whether *staged* `rustc`-under-test was built with debug assertions.
///
/// FIXME: make it clearer that this refers to the staged `rustc`-under-test, not stage 0
/// `rustc`.
pub with_rustc_debug_assertions: bool,
pub(crate) with_rustc_debug_assertions: bool,
/// Whether *staged* `std` was built with debug assertions.
///
/// FIXME: make it clearer that this refers to the staged `std`, not stage 0 `std`.
pub with_std_debug_assertions: bool,
pub(crate) with_std_debug_assertions: bool,
/// Whether *staged* `std` was built with remapping of debuginfo.
///
/// FIXME: make it clearer that this refers to the staged `std`, not stage 0 `std`.
pub with_std_remap_debuginfo: bool,
pub(crate) with_std_remap_debuginfo: bool,
/// Only run tests that match these filters (using `libtest` "test name contains" filter logic).
///
@@ -452,25 +452,25 @@ pub struct Config {
/// but this is often not intuitive. We should consider changing that behavior with an MCP to do
/// test path *prefix* matching which better corresponds to how `compiletest` `tests/` are
/// organized, and how users would intuitively expect the filtering logic to work like.
pub filters: Vec<String>,
pub(crate) filters: Vec<String>,
/// Skip tests matching these substrings. The matching logic exactly corresponds to
/// [`Self::filters`] but inverted.
///
/// FIXME(#139660): ditto on test matching behavior.
pub skip: Vec<String>,
pub(crate) skip: Vec<String>,
/// Exactly match the filter, rather than a substring.
///
/// FIXME(#139660): ditto on test matching behavior.
pub filter_exact: bool,
pub(crate) filter_exact: bool,
/// Force the pass mode of a check/build/run test to instead use this mode instead.
///
/// FIXME: make it even more obvious (especially in PR CI where `--pass=check` is used) when a
/// pass mode is forced when the test fails, because it can be very non-obvious when e.g. an
/// error is emitted only when `//@ build-pass` but not `//@ check-pass`.
pub force_pass_mode: Option<PassMode>,
pub(crate) force_pass_mode: Option<PassMode>,
/// Explicitly enable or disable running of the target test binary.
///
@@ -480,7 +480,7 @@ pub struct Config {
/// FIXME: Currently `--run` is a tri-state, it can be `--run={auto,always,never}`, and when
/// `--run=auto` is specified, it's run if the platform doesn't end with `-fuchsia`. See
/// [`Config::run_enabled`].
pub run: Option<bool>,
pub(crate) run: Option<bool>,
/// A command line to prefix target program execution with, for running under valgrind for
/// example, i.e. `$runner target.exe [args..]`. Similar to `CARGO_*_RUNNER` configuration.
@@ -489,45 +489,45 @@ pub struct Config {
/// scheme.
///
/// FIXME: the runner scheme is very under-documented.
pub runner: Option<String>,
pub(crate) runner: Option<String>,
/// Compiler flags to pass to the *staged* `rustc`-under-test when building for the **host**
/// platform.
pub host_rustcflags: Vec<String>,
pub(crate) host_rustcflags: Vec<String>,
/// Compiler flags to pass to the *staged* `rustc`-under-test when building for the **target**
/// platform.
pub target_rustcflags: Vec<String>,
pub(crate) target_rustcflags: Vec<String>,
/// Whether the *staged* `rustc`-under-test and the associated *staged* `std` has been built
/// with randomized struct layouts.
pub rust_randomized_layout: bool,
pub(crate) rust_randomized_layout: bool,
/// Whether tests should be optimized by default (`-O`). Individual test suites and test files
/// may override this setting.
///
/// FIXME: this flag / config option is somewhat misleading. For instance, in ui tests, it's
/// *only* applied to the [`PassMode::Run`] test crate and not its auxiliaries.
pub optimize_tests: bool,
pub(crate) optimize_tests: bool,
/// Target platform tuple.
pub target: String,
pub(crate) target: String,
/// Host platform tuple.
pub host: String,
pub(crate) host: String,
/// Path to / name of the Microsoft Console Debugger (CDB) executable.
///
/// FIXME: this is an *opt-in* "override" option. When this isn't provided, we try to conjure a
/// cdb by looking at the user's program files on Windows... See `debuggers::find_cdb`.
pub cdb: Option<Utf8PathBuf>,
pub(crate) cdb: Option<Utf8PathBuf>,
/// Version of CDB.
///
/// FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config!
///
/// FIXME: audit cdb version gating.
pub cdb_version: Option<[u16; 4]>,
pub(crate) cdb_version: Option<[u16; 4]>,
/// Path to / name of the GDB executable.
///
@@ -536,7 +536,7 @@ pub struct Config {
///
/// FIXME: we are propagating a python from `PYTHONPATH`, not from an explicit config for gdb
/// debugger script.
pub gdb: Option<Utf8PathBuf>,
pub(crate) gdb: Option<Utf8PathBuf>,
/// Version of GDB, encoded as ((major * 1000) + minor) * 1000 + patch
///
@@ -547,24 +547,24 @@ pub struct Config {
/// purposes of debuginfo tests?
///
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
pub gdb_version: Option<u32>,
pub(crate) gdb_version: Option<u32>,
/// Path to or name of the LLDB executable to use for debuginfo tests.
pub lldb: Option<Utf8PathBuf>,
pub(crate) lldb: Option<Utf8PathBuf>,
/// Version of LLDB.
///
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
pub lldb_version: Option<u32>,
pub(crate) lldb_version: Option<u32>,
/// Version of LLVM.
///
/// FIXME: Audit the fallback derivation of
/// [`crate::directives::extract_llvm_version_from_binary`], that seems very questionable?
pub llvm_version: Option<Version>,
pub(crate) llvm_version: Option<Version>,
/// Is LLVM a system LLVM.
pub system_llvm: bool,
pub(crate) system_llvm: bool,
/// Path to the android tools.
///
@@ -572,7 +572,7 @@ pub struct Config {
///
/// FIXME: take a look at this; this is piggy-backing off of gdb code paths but only for
/// `arm-linux-androideabi` target.
pub android_cross_path: Option<Utf8PathBuf>,
pub(crate) android_cross_path: Option<Utf8PathBuf>,
/// Extra parameter to run adb on `arm-linux-androideabi`.
///
@@ -581,7 +581,7 @@ pub struct Config {
///
/// FIXME: take a look at this; this is piggy-backing off of gdb code paths but only for
/// `arm-linux-androideabi` target.
pub adb_path: Option<Utf8PathBuf>,
pub(crate) adb_path: Option<Utf8PathBuf>,
/// Extra parameter to run test suite on `arm-linux-androideabi`.
///
@@ -590,18 +590,18 @@ pub struct Config {
///
/// FIXME: take a look at this; this is piggy-backing off of gdb code paths but only for
/// `arm-linux-androideabi` target.
pub adb_test_dir: Option<Utf8PathBuf>,
pub(crate) adb_test_dir: Option<Utf8PathBuf>,
/// Status whether android device available or not. When unavailable, this will cause tests to
/// panic when the test binary is attempted to be run.
///
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
pub adb_device_status: bool,
pub(crate) adb_device_status: bool,
/// Verbose dump a lot of info.
///
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.
pub verbose: bool,
pub(crate) verbose: bool,
/// Where to find the remote test client process, if we're using it.
///
@@ -611,67 +611,67 @@ pub struct Config {
/// Note: this is not to be confused with [`Self::runner`], which is a different scheme.
///
/// FIXME: the `remote_test_client` scheme is very under-documented.
pub remote_test_client: Option<Utf8PathBuf>,
pub(crate) remote_test_client: Option<Utf8PathBuf>,
/// [`CompareMode`] describing what file the actual ui output will be compared to.
///
/// FIXME: currently, [`CompareMode`] is a mishmash of lot of things (different borrow-checker
/// model, different trait solver, different debugger, etc.).
pub compare_mode: Option<CompareMode>,
pub(crate) compare_mode: Option<CompareMode>,
/// If true, this will generate a coverage file with UI test files that run `MachineApplicable`
/// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is
/// created in `$test_suite_build_root/rustfix_missing_coverage.txt`
pub rustfix_coverage: bool,
pub(crate) rustfix_coverage: bool,
/// Whether to run `enzyme` autodiff tests.
pub has_enzyme: bool,
pub(crate) has_enzyme: bool,
/// Whether to run `offload` autodiff tests.
pub has_offload: bool,
pub(crate) has_offload: bool,
/// The current Rust channel info.
///
/// FIXME: treat this more carefully; "stable", "beta" and "nightly" are definitely valid, but
/// channel might also be "dev" or such, which should be treated as "nightly".
pub channel: String,
pub(crate) channel: String,
/// Whether adding git commit information such as the commit hash has been enabled for building.
///
/// FIXME: `compiletest` cannot trust `bootstrap` for this information, because `bootstrap` can
/// have bugs and had bugs on that logic. We need to figure out how to obtain this e.g. directly
/// from CI or via git locally.
pub git_hash: bool,
pub(crate) git_hash: bool,
/// The default Rust edition.
pub edition: Option<Edition>,
pub(crate) edition: Option<Edition>,
// Configuration for various run-make tests frobbing things like C compilers or querying about
// various LLVM component information.
//
// FIXME: this really should be better packaged together.
// FIXME: these need better docs, e.g. for *host*, or for *target*?
pub cc: String,
pub cxx: String,
pub cflags: String,
pub cxxflags: String,
pub ar: String,
pub target_linker: Option<String>,
pub host_linker: Option<String>,
pub llvm_components: String,
pub(crate) cc: String,
pub(crate) cxx: String,
pub(crate) cflags: String,
pub(crate) cxxflags: String,
pub(crate) ar: String,
pub(crate) target_linker: Option<String>,
pub(crate) host_linker: Option<String>,
pub(crate) llvm_components: String,
/// Path to a NodeJS executable. Used for JS doctests, emscripten and WASM tests.
pub nodejs: Option<Utf8PathBuf>,
pub(crate) nodejs: Option<Utf8PathBuf>,
/// Whether to rerun tests even if the inputs are unchanged.
pub force_rerun: bool,
pub(crate) force_rerun: bool,
/// Only rerun the tests that result has been modified according to `git status`.
///
/// FIXME: this is undocumented.
///
/// FIXME: how does this interact with [`Self::force_rerun`]?
pub only_modified: bool,
pub(crate) only_modified: bool,
// FIXME: these are really not "config"s, but rather are information derived from
// `rustc`-under-test. This poses an interesting conundrum: if we're testing the
@@ -684,72 +684,72 @@ pub struct Config {
// from print requests produced by the `rustc`-under-test.
//
// FIXME: move them out from `Config`, because they are *not* configs.
pub target_cfgs: OnceLock<TargetCfgs>,
pub builtin_cfg_names: OnceLock<HashSet<String>>,
pub supported_crate_types: OnceLock<HashSet<String>>,
pub(crate) target_cfgs: OnceLock<TargetCfgs>,
pub(crate) builtin_cfg_names: OnceLock<HashSet<String>>,
pub(crate) supported_crate_types: OnceLock<HashSet<String>>,
/// Should we capture console output that would be printed by test runners via their `stdout`
/// and `stderr` trait objects, or via the custom panic hook.
///
/// The default is `true`. This can be disabled via the compiletest cli flag `--no-capture`
/// (which mirrors the libtest `--no-capture` flag).
pub capture: bool,
pub(crate) capture: bool,
/// Needed both to construct [`build_helper::git::GitConfig`].
pub nightly_branch: String,
pub git_merge_commit_email: String,
pub(crate) nightly_branch: String,
pub(crate) git_merge_commit_email: String,
/// True if the profiler runtime is enabled for this target. Used by the
/// `needs-profiler-runtime` directive in test files.
pub profiler_runtime: bool,
pub(crate) profiler_runtime: bool,
/// Command for visual diff display, e.g. `diff-tool --color=always`.
pub diff_command: Option<String>,
pub(crate) diff_command: Option<String>,
/// Path to minicore aux library (`tests/auxiliary/minicore.rs`), used for `no_core` tests that
/// need `core` stubs in cross-compilation scenarios that do not otherwise want/need to
/// `-Zbuild-std`. Used in e.g. ABI tests.
pub minicore_path: Utf8PathBuf,
pub(crate) minicore_path: Utf8PathBuf,
/// Current codegen backend used.
pub default_codegen_backend: CodegenBackend,
pub(crate) default_codegen_backend: CodegenBackend,
/// Name/path of the backend to use instead of `default_codegen_backend`.
pub override_codegen_backend: Option<String>,
pub(crate) override_codegen_backend: Option<String>,
/// Whether to ignore `//@ ignore-backends`.
pub bypass_ignore_backends: bool,
pub(crate) bypass_ignore_backends: bool,
/// Number of parallel jobs configured for the build.
///
/// This is forwarded from bootstrap's `jobs` configuration.
pub jobs: u32,
pub(crate) jobs: u32,
/// Number of parallel threads to use for the frontend when building test artifacts.
pub parallel_frontend_threads: u32,
pub(crate) parallel_frontend_threads: u32,
/// Number of times to execute each test.
pub iteration_count: u32,
pub(crate) iteration_count: u32,
}
impl Config {
pub const DEFAULT_PARALLEL_FRONTEND_THREADS: u32 = 1;
pub const DEFAULT_ITERATION_COUNT: u32 = 1;
pub(crate) const DEFAULT_PARALLEL_FRONTEND_THREADS: u32 = 1;
pub(crate) const DEFAULT_ITERATION_COUNT: u32 = 1;
/// FIXME: this run scheme is... confusing.
pub fn run_enabled(&self) -> bool {
pub(crate) fn run_enabled(&self) -> bool {
self.run.unwrap_or_else(|| {
// Auto-detect whether to run based on the platform.
!self.target.ends_with("-fuchsia")
})
}
pub fn target_cfgs(&self) -> &TargetCfgs {
pub(crate) fn target_cfgs(&self) -> &TargetCfgs {
self.target_cfgs.get_or_init(|| TargetCfgs::new(self))
}
pub fn target_cfg(&self) -> &TargetCfg {
pub(crate) fn target_cfg(&self) -> &TargetCfg {
&self.target_cfgs().current
}
pub fn matches_arch(&self, arch: &str) -> bool {
pub(crate) fn matches_arch(&self, arch: &str) -> bool {
self.target_cfg().arch == arch
|| {
// Matching all the thumb variants as one can be convenient.
@@ -759,15 +759,15 @@ pub fn matches_arch(&self, arch: &str) -> bool {
|| (arch == "i586" && self.target.starts_with("i586-"))
}
pub fn matches_os(&self, os: &str) -> bool {
pub(crate) fn matches_os(&self, os: &str) -> bool {
self.target_cfg().os == os
}
pub fn matches_env(&self, env: &str) -> bool {
pub(crate) fn matches_env(&self, env: &str) -> bool {
self.target_cfg().env == env
}
pub fn matches_abi(&self, abi: &str) -> bool {
pub(crate) fn matches_abi(&self, abi: &str) -> bool {
self.target_cfg().abi == abi
}
@@ -776,29 +776,29 @@ pub(crate) fn matches_family(&self, family: &str) -> bool {
self.target_cfg().families.iter().any(|f| f == family)
}
pub fn is_big_endian(&self) -> bool {
pub(crate) fn is_big_endian(&self) -> bool {
self.target_cfg().endian == Endian::Big
}
pub fn get_pointer_width(&self) -> u32 {
pub(crate) fn get_pointer_width(&self) -> u32 {
*&self.target_cfg().pointer_width
}
pub fn can_unwind(&self) -> bool {
pub(crate) fn can_unwind(&self) -> bool {
self.target_cfg().panic == PanicStrategy::Unwind
}
/// Get the list of builtin, 'well known' cfg names
pub fn builtin_cfg_names(&self) -> &HashSet<String> {
pub(crate) fn builtin_cfg_names(&self) -> &HashSet<String> {
self.builtin_cfg_names.get_or_init(|| builtin_cfg_names(self))
}
/// Get the list of crate types that the target platform supports.
pub fn supported_crate_types(&self) -> &HashSet<String> {
pub(crate) fn supported_crate_types(&self) -> &HashSet<String> {
self.supported_crate_types.get_or_init(|| supported_crate_types(self))
}
pub fn has_threads(&self) -> bool {
pub(crate) fn has_threads(&self) -> bool {
// Wasm targets don't have threads unless `-threads` is in the target
// name, such as `wasm32-wasip1-threads`.
if self.target.starts_with("wasm") {
@@ -807,7 +807,7 @@ pub fn has_threads(&self) -> bool {
true
}
pub fn has_asm_support(&self) -> bool {
pub(crate) fn has_asm_support(&self) -> bool {
// This should match the stable list in `LoweringContext::lower_inline_asm`.
static ASM_SUPPORTED_ARCHS: &[&str] = &[
"x86",
@@ -826,14 +826,14 @@ pub fn has_asm_support(&self) -> bool {
ASM_SUPPORTED_ARCHS.contains(&self.target_cfg().arch.as_str())
}
pub fn git_config(&self) -> GitConfig<'_> {
pub(crate) fn git_config(&self) -> GitConfig<'_> {
GitConfig {
nightly_branch: &self.nightly_branch,
git_merge_commit_email: &self.git_merge_commit_email,
}
}
pub fn has_subprocess_support(&self) -> bool {
pub(crate) fn has_subprocess_support(&self) -> bool {
// FIXME(#135928): compiletest is always a **host** tool. Building and running an
// capability detection executable against the **target** is not trivial. The short term
// solution here is to hard-code some targets to allow/deny, unfortunately.
@@ -851,26 +851,26 @@ pub fn has_subprocess_support(&self) -> bool {
/// But we treat it as the parallel frontend being enabled in this case.
/// - `1` means single-threaded (parallel frontend disabled).
/// - `>1` means an explicitly configured thread count.
pub fn parallel_frontend_enabled(&self) -> bool {
pub(crate) fn parallel_frontend_enabled(&self) -> bool {
self.parallel_frontend_threads != 1
}
}
/// Known widths of `target_has_atomic`.
pub const KNOWN_TARGET_HAS_ATOMIC_WIDTHS: &[&str] = &["8", "16", "32", "64", "128", "ptr"];
pub(crate) const KNOWN_TARGET_HAS_ATOMIC_WIDTHS: &[&str] = &["8", "16", "32", "64", "128", "ptr"];
#[derive(Debug, Clone)]
pub struct TargetCfgs {
pub current: TargetCfg,
pub all_targets: HashSet<String>,
pub all_archs: HashSet<String>,
pub all_oses: HashSet<String>,
pub all_oses_and_envs: HashSet<String>,
pub all_envs: HashSet<String>,
pub all_abis: HashSet<String>,
pub all_families: HashSet<String>,
pub all_pointer_widths: HashSet<String>,
pub all_rustc_abis: HashSet<String>,
pub(crate) struct TargetCfgs {
pub(crate) current: TargetCfg,
pub(crate) all_targets: HashSet<String>,
pub(crate) all_archs: HashSet<String>,
pub(crate) all_oses: HashSet<String>,
pub(crate) all_oses_and_envs: HashSet<String>,
pub(crate) all_envs: HashSet<String>,
pub(crate) all_abis: HashSet<String>,
pub(crate) all_families: HashSet<String>,
pub(crate) all_pointer_widths: HashSet<String>,
pub(crate) all_rustc_abis: HashSet<String>,
}
impl TargetCfgs {
@@ -1017,7 +1017,7 @@ fn get_current_target_config(
#[derive(Clone, Debug, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct TargetCfg {
pub(crate) struct TargetCfg {
pub(crate) arch: String,
#[serde(default = "default_os")]
pub(crate) os: String,
@@ -1080,7 +1080,7 @@ fn default_binary_format_elf() -> Cow<'static, str> {
#[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Endian {
pub(crate) enum Endian {
#[default]
Little,
Big,
@@ -1114,7 +1114,7 @@ fn extract_cfg_name(check_cfg_line: &str) -> Result<&str, &'static str> {
Ok(inner[..first_comma].trim())
}
pub const KNOWN_CRATE_TYPES: &[&str] =
pub(crate) const KNOWN_CRATE_TYPES: &[&str] =
&["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
fn supported_crate_types(config: &Config) -> HashSet<String> {
@@ -1196,7 +1196,7 @@ pub(crate) struct TestPaths {
}
/// Used by `ui` tests to generate things like `foo.stderr` from `foo.rs`.
pub fn expected_output_path(
pub(crate) fn expected_output_path(
testpaths: &TestPaths,
revision: Option<&str>,
compare_mode: &Option<CompareMode>,
@@ -1217,7 +1217,7 @@ pub fn expected_output_path(
testpaths.file.with_extension(extension)
}
pub const UI_EXTENSIONS: &[&str] = &[
pub(crate) const UI_EXTENSIONS: &[&str] = &[
UI_STDERR,
UI_SVG,
UI_WINDOWS_SVG,
@@ -1231,18 +1231,18 @@ pub fn expected_output_path(
UI_COVERAGE,
UI_COVERAGE_MAP,
];
pub const UI_STDERR: &str = "stderr";
pub const UI_SVG: &str = "svg";
pub const UI_WINDOWS_SVG: &str = "windows.svg";
pub const UI_STDOUT: &str = "stdout";
pub const UI_FIXED: &str = "fixed";
pub const UI_RUN_STDERR: &str = "run.stderr";
pub const UI_RUN_STDOUT: &str = "run.stdout";
pub const UI_STDERR_64: &str = "64bit.stderr";
pub const UI_STDERR_32: &str = "32bit.stderr";
pub const UI_STDERR_16: &str = "16bit.stderr";
pub const UI_COVERAGE: &str = "coverage";
pub const UI_COVERAGE_MAP: &str = "cov-map";
pub(crate) const UI_STDERR: &str = "stderr";
pub(crate) const UI_SVG: &str = "svg";
pub(crate) const UI_WINDOWS_SVG: &str = "windows.svg";
pub(crate) const UI_STDOUT: &str = "stdout";
pub(crate) const UI_FIXED: &str = "fixed";
pub(crate) const UI_RUN_STDERR: &str = "run.stderr";
pub(crate) const UI_RUN_STDOUT: &str = "run.stdout";
pub(crate) const UI_STDERR_64: &str = "64bit.stderr";
pub(crate) const UI_STDERR_32: &str = "32bit.stderr";
pub(crate) const UI_STDERR_16: &str = "16bit.stderr";
pub(crate) const UI_COVERAGE: &str = "coverage";
pub(crate) const UI_COVERAGE_MAP: &str = "cov-map";
/// Absolute path to the directory where all output for all tests in the given `relative_dir` group
/// should reside. Example:
@@ -1252,12 +1252,12 @@ pub fn expected_output_path(
/// ```
///
/// This is created early when tests are collected to avoid race conditions.
pub fn output_relative_path(config: &Config, relative_dir: &Utf8Path) -> Utf8PathBuf {
pub(crate) fn output_relative_path(config: &Config, relative_dir: &Utf8Path) -> Utf8PathBuf {
config.build_test_suite_root.join(relative_dir)
}
/// Generates a unique name for the test, such as `testname.revision.mode`.
pub fn output_testname_unique(
pub(crate) fn output_testname_unique(
config: &Config,
testpaths: &TestPaths,
revision: Option<&str>,
@@ -1274,7 +1274,7 @@ pub fn output_testname_unique(
/// Absolute path to the directory where all output for the given
/// test/revision should reside. Example:
/// /path/to/build/host-tuple/test/ui/relative/testname.revision.mode/
pub fn output_base_dir(
pub(crate) fn output_base_dir(
config: &Config,
testpaths: &TestPaths,
revision: Option<&str>,
@@ -1286,7 +1286,7 @@ pub fn output_base_dir(
/// Absolute path to the base filename used as output for the given
/// test/revision. Example:
/// /path/to/build/host-tuple/test/ui/relative/testname.revision.mode/testname
pub fn output_base_name(
pub(crate) fn output_base_name(
config: &Config,
testpaths: &TestPaths,
revision: Option<&str>,
@@ -1296,7 +1296,7 @@ pub fn output_base_name(
/// Absolute path to the directory to use for incremental compilation. Example:
/// /path/to/build/host-tuple/test/ui/relative/testname.mode/testname.inc
pub fn incremental_dir(
pub(crate) fn incremental_dir(
config: &Config,
testpaths: &TestPaths,
revision: Option<&str>,
+102 -102
View File
@@ -36,7 +36,7 @@
#[cfg(test)]
mod tests;
pub struct DirectivesCache {
pub(crate) struct DirectivesCache {
/// "Conditions" used by `ignore-*` and `only-*` directives, prepared in
/// advance so that they don't have to be evaluated repeatedly.
cfg_conditions: cfg::PreparedConditions,
@@ -44,7 +44,7 @@ pub struct DirectivesCache {
}
impl DirectivesCache {
pub fn load(config: &Config) -> Self {
pub(crate) fn load(config: &Config) -> Self {
Self {
cfg_conditions: cfg::prepare_conditions(config),
needs: CachedNeedsConditions::load(config),
@@ -82,68 +82,68 @@ pub(crate) fn from_file_directives(
#[derive(Clone, Debug)]
pub(crate) struct TestProps {
// Lines that should be expected, in order, on standard out
pub error_patterns: Vec<String>,
pub(crate) error_patterns: Vec<String>,
// Regexes that should be expected, in order, on standard out
pub regex_error_patterns: Vec<String>,
pub(crate) regex_error_patterns: Vec<String>,
/// Edition selected by an `//@ edition` directive, if any.
///
/// Automatically added to `compile_flags` during directive processing.
pub edition: Option<Edition>,
pub(crate) edition: Option<Edition>,
// Extra flags to pass to the compiler
pub compile_flags: Vec<String>,
pub(crate) compile_flags: Vec<String>,
// Extra flags to pass when the compiled code is run (such as --bench)
pub run_flags: Vec<String>,
pub(crate) run_flags: Vec<String>,
/// Extra flags to pass to rustdoc but not the compiler.
pub doc_flags: Vec<String>,
pub(crate) doc_flags: Vec<String>,
// If present, the name of a file that this test should match when
// pretty-printed
pub pp_exact: Option<Utf8PathBuf>,
pub(crate) pp_exact: Option<Utf8PathBuf>,
/// Auxiliary crates that should be built and made available to this test.
pub(crate) aux: AuxProps,
// Environment settings to use for compiling
pub rustc_env: Vec<(String, String)>,
pub(crate) rustc_env: Vec<(String, String)>,
// Environment variables to unset prior to compiling.
// Variables are unset before applying 'rustc_env'.
pub unset_rustc_env: Vec<String>,
pub(crate) unset_rustc_env: Vec<String>,
// Environment settings to use during execution
pub exec_env: Vec<(String, String)>,
pub(crate) exec_env: Vec<(String, String)>,
// Environment variables to unset prior to execution.
// Variables are unset before applying 'exec_env'
pub unset_exec_env: Vec<String>,
pub(crate) unset_exec_env: Vec<String>,
// Build documentation for all specified aux-builds as well
pub build_aux_docs: bool,
pub(crate) build_aux_docs: bool,
/// Build the documentation for each crate in a unique output directory.
/// Uses `<root output directory>/docs/<test name>/doc`.
pub unique_doc_out_dir: bool,
pub(crate) unique_doc_out_dir: bool,
// Flag to force a crate to be built with the host architecture
pub force_host: bool,
pub(crate) force_host: bool,
// Check stdout for error-pattern output as well as stderr
pub check_stdout: bool,
pub(crate) check_stdout: bool,
// Check stdout & stderr for output of run-pass test
pub check_run_results: bool,
pub(crate) check_run_results: bool,
// For UI tests, allows compiler to generate arbitrary output to stdout
pub dont_check_compiler_stdout: bool,
pub(crate) dont_check_compiler_stdout: bool,
// For UI tests, allows compiler to generate arbitrary output to stderr
pub dont_check_compiler_stderr: bool,
pub(crate) dont_check_compiler_stderr: bool,
// Don't force a --crate-type=dylib flag on the command line
//
// Set this for example if you have an auxiliary test file that contains
// a proc-macro and needs `#![crate_type = "proc-macro"]`. This ensures
// that the aux file is compiled as a `proc-macro` and not as a `dylib`.
pub no_prefer_dynamic: bool,
pub(crate) no_prefer_dynamic: bool,
// Which pretty mode are we testing with, default to 'normal'
pub pretty_mode: String,
pub(crate) pretty_mode: String,
// Only compare pretty output and don't try compiling
pub pretty_compare_only: bool,
pub(crate) pretty_compare_only: bool,
// Patterns which must not appear in the output of a cfail test.
pub forbid_output: Vec<String>,
pub(crate) forbid_output: Vec<String>,
// Revisions to test for incremental compilation.
pub revisions: Vec<String>,
pub(crate) revisions: Vec<String>,
// Directory (if any) to use for incremental compilation. This is
// not set by end-users; rather it is set by the incremental
// testing harness and used when generating compilation
// arguments. (In particular, it propagates to the aux-builds.)
pub incremental_dir: Option<Utf8PathBuf>,
pub(crate) incremental_dir: Option<Utf8PathBuf>,
// If `true`, this test will use incremental compilation.
//
// This can be set manually with the `incremental` directive, or implicitly
@@ -158,113 +158,113 @@ pub(crate) struct TestProps {
// Compiletest will create the incremental directory, and ensure it is
// empty before the test starts. Incremental mode tests will reuse the
// incremental directory between passes in the same test.
pub incremental: bool,
pub(crate) incremental: bool,
// If `true`, this test is a known bug.
//
// When set, some requirements are relaxed. Currently, this only means no
// error annotations are needed, but this may be updated in the future to
// include other relaxations.
pub known_bug: bool,
pub(crate) known_bug: bool,
// How far should the test proceed while still passing.
pass_mode: Option<PassMode>,
// Ignore `--pass` overrides from the command line for this test.
ignore_pass: bool,
// How far this test should proceed to start failing.
pub fail_mode: Option<FailMode>,
pub(crate) fail_mode: Option<FailMode>,
// rustdoc will test the output of the `--test` option
pub check_test_line_numbers_match: bool,
pub(crate) check_test_line_numbers_match: bool,
// customized normalization rules
pub normalize_stdout: Vec<(String, String)>,
pub normalize_stderr: Vec<(String, String)>,
pub failure_status: Option<i32>,
pub(crate) normalize_stdout: Vec<(String, String)>,
pub(crate) normalize_stderr: Vec<(String, String)>,
pub(crate) failure_status: Option<i32>,
// For UI tests, allows compiler to exit with arbitrary failure status
pub dont_check_failure_status: bool,
pub(crate) dont_check_failure_status: bool,
// Whether or not `rustfix` should apply the `CodeSuggestion`s of this test and compile the
// resulting Rust code.
pub run_rustfix: bool,
pub(crate) run_rustfix: bool,
// If true, `rustfix` will only apply `MachineApplicable` suggestions.
pub rustfix_only_machine_applicable: bool,
pub assembly_output: Option<String>,
pub(crate) rustfix_only_machine_applicable: bool,
pub(crate) assembly_output: Option<String>,
// If true, the test is expected to ICE
pub should_ice: bool,
pub(crate) should_ice: bool,
// If true, the stderr is expected to be different across bit-widths.
pub stderr_per_bitwidth: bool,
pub(crate) stderr_per_bitwidth: bool,
// The MIR opt to unit test, if any
pub mir_unit_test: Option<String>,
pub(crate) mir_unit_test: Option<String>,
// Whether to tell `rustc` to remap the "src base" directory to a fake
// directory.
pub remap_src_base: bool,
pub(crate) remap_src_base: bool,
/// Extra flags to pass to `llvm-cov` when producing coverage reports.
/// Only used by the "coverage-run" test mode.
pub llvm_cov_flags: Vec<String>,
pub(crate) llvm_cov_flags: Vec<String>,
/// Extra flags to pass to LLVM's `filecheck` tool, in tests that use it.
pub filecheck_flags: Vec<String>,
pub(crate) filecheck_flags: Vec<String>,
/// Don't automatically insert any `--check-cfg` args
pub no_auto_check_cfg: bool,
pub(crate) no_auto_check_cfg: bool,
/// Build and use `minicore` as `core` stub for `no_core` tests in cross-compilation scenarios
/// that don't otherwise want/need `-Z build-std`.
pub add_minicore: bool,
pub(crate) add_minicore: bool,
/// Add these flags to the build of `minicore`.
pub minicore_compile_flags: Vec<String>,
pub(crate) minicore_compile_flags: Vec<String>,
/// Whether line annotations are required for the given error kind.
pub dont_require_annotations: HashSet<ErrorKind>,
pub(crate) dont_require_annotations: HashSet<ErrorKind>,
/// Whether pretty printers should be disabled in gdb.
pub disable_gdb_pretty_printers: bool,
pub(crate) disable_gdb_pretty_printers: bool,
/// Compare the output by lines, rather than as a single string.
pub compare_output_by_lines: bool,
pub(crate) compare_output_by_lines: bool,
}
mod directives {
pub const ERROR_PATTERN: &'static str = "error-pattern";
pub const REGEX_ERROR_PATTERN: &'static str = "regex-error-pattern";
pub const COMPILE_FLAGS: &'static str = "compile-flags";
pub const RUN_FLAGS: &'static str = "run-flags";
pub const DOC_FLAGS: &'static str = "doc-flags";
pub const SHOULD_ICE: &'static str = "should-ice";
pub const BUILD_AUX_DOCS: &'static str = "build-aux-docs";
pub const UNIQUE_DOC_OUT_DIR: &'static str = "unique-doc-out-dir";
pub const FORCE_HOST: &'static str = "force-host";
pub const CHECK_STDOUT: &'static str = "check-stdout";
pub const CHECK_RUN_RESULTS: &'static str = "check-run-results";
pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout";
pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr";
pub const DONT_REQUIRE_ANNOTATIONS: &'static str = "dont-require-annotations";
pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic";
pub const PRETTY_MODE: &'static str = "pretty-mode";
pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only";
pub const AUX_BIN: &'static str = "aux-bin";
pub const AUX_BUILD: &'static str = "aux-build";
pub const AUX_CRATE: &'static str = "aux-crate";
pub const PROC_MACRO: &'static str = "proc-macro";
pub const AUX_CODEGEN_BACKEND: &'static str = "aux-codegen-backend";
pub const EXEC_ENV: &'static str = "exec-env";
pub const RUSTC_ENV: &'static str = "rustc-env";
pub const UNSET_EXEC_ENV: &'static str = "unset-exec-env";
pub const UNSET_RUSTC_ENV: &'static str = "unset-rustc-env";
pub const FORBID_OUTPUT: &'static str = "forbid-output";
pub const CHECK_TEST_LINE_NUMBERS_MATCH: &'static str = "check-test-line-numbers-match";
pub const IGNORE_PASS: &'static str = "ignore-pass";
pub const FAILURE_STATUS: &'static str = "failure-status";
pub const DONT_CHECK_FAILURE_STATUS: &'static str = "dont-check-failure-status";
pub const RUN_RUSTFIX: &'static str = "run-rustfix";
pub const RUSTFIX_ONLY_MACHINE_APPLICABLE: &'static str = "rustfix-only-machine-applicable";
pub const ASSEMBLY_OUTPUT: &'static str = "assembly-output";
pub const STDERR_PER_BITWIDTH: &'static str = "stderr-per-bitwidth";
pub const INCREMENTAL: &'static str = "incremental";
pub const KNOWN_BUG: &'static str = "known-bug";
pub const TEST_MIR_PASS: &'static str = "test-mir-pass";
pub const REMAP_SRC_BASE: &'static str = "remap-src-base";
pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags";
pub const FILECHECK_FLAGS: &'static str = "filecheck-flags";
pub const NO_AUTO_CHECK_CFG: &'static str = "no-auto-check-cfg";
pub const ADD_MINICORE: &'static str = "add-minicore";
pub const MINICORE_COMPILE_FLAGS: &'static str = "minicore-compile-flags";
pub const DISABLE_GDB_PRETTY_PRINTERS: &'static str = "disable-gdb-pretty-printers";
pub const COMPARE_OUTPUT_BY_LINES: &'static str = "compare-output-by-lines";
pub(crate) const ERROR_PATTERN: &str = "error-pattern";
pub(crate) const REGEX_ERROR_PATTERN: &str = "regex-error-pattern";
pub(crate) const COMPILE_FLAGS: &str = "compile-flags";
pub(crate) const RUN_FLAGS: &str = "run-flags";
pub(crate) const DOC_FLAGS: &str = "doc-flags";
pub(crate) const SHOULD_ICE: &str = "should-ice";
pub(crate) const BUILD_AUX_DOCS: &str = "build-aux-docs";
pub(crate) const UNIQUE_DOC_OUT_DIR: &str = "unique-doc-out-dir";
pub(crate) const FORCE_HOST: &str = "force-host";
pub(crate) const CHECK_STDOUT: &str = "check-stdout";
pub(crate) const CHECK_RUN_RESULTS: &str = "check-run-results";
pub(crate) const DONT_CHECK_COMPILER_STDOUT: &str = "dont-check-compiler-stdout";
pub(crate) const DONT_CHECK_COMPILER_STDERR: &str = "dont-check-compiler-stderr";
pub(crate) const DONT_REQUIRE_ANNOTATIONS: &str = "dont-require-annotations";
pub(crate) const NO_PREFER_DYNAMIC: &str = "no-prefer-dynamic";
pub(crate) const PRETTY_MODE: &str = "pretty-mode";
pub(crate) const PRETTY_COMPARE_ONLY: &str = "pretty-compare-only";
pub(crate) const AUX_BIN: &str = "aux-bin";
pub(crate) const AUX_BUILD: &str = "aux-build";
pub(crate) const AUX_CRATE: &str = "aux-crate";
pub(crate) const PROC_MACRO: &str = "proc-macro";
pub(crate) const AUX_CODEGEN_BACKEND: &str = "aux-codegen-backend";
pub(crate) const EXEC_ENV: &str = "exec-env";
pub(crate) const RUSTC_ENV: &str = "rustc-env";
pub(crate) const UNSET_EXEC_ENV: &str = "unset-exec-env";
pub(crate) const UNSET_RUSTC_ENV: &str = "unset-rustc-env";
pub(crate) const FORBID_OUTPUT: &str = "forbid-output";
pub(crate) const CHECK_TEST_LINE_NUMBERS_MATCH: &str = "check-test-line-numbers-match";
pub(crate) const IGNORE_PASS: &str = "ignore-pass";
pub(crate) const FAILURE_STATUS: &str = "failure-status";
pub(crate) const DONT_CHECK_FAILURE_STATUS: &str = "dont-check-failure-status";
pub(crate) const RUN_RUSTFIX: &str = "run-rustfix";
pub(crate) const RUSTFIX_ONLY_MACHINE_APPLICABLE: &str = "rustfix-only-machine-applicable";
pub(crate) const ASSEMBLY_OUTPUT: &str = "assembly-output";
pub(crate) const STDERR_PER_BITWIDTH: &str = "stderr-per-bitwidth";
pub(crate) const INCREMENTAL: &str = "incremental";
pub(crate) const KNOWN_BUG: &str = "known-bug";
pub(crate) const TEST_MIR_PASS: &str = "test-mir-pass";
pub(crate) const REMAP_SRC_BASE: &str = "remap-src-base";
pub(crate) const LLVM_COV_FLAGS: &str = "llvm-cov-flags";
pub(crate) const FILECHECK_FLAGS: &str = "filecheck-flags";
pub(crate) const NO_AUTO_CHECK_CFG: &str = "no-auto-check-cfg";
pub(crate) const ADD_MINICORE: &str = "add-minicore";
pub(crate) const MINICORE_COMPILE_FLAGS: &str = "minicore-compile-flags";
pub(crate) const DISABLE_GDB_PRETTY_PRINTERS: &str = "disable-gdb-pretty-printers";
pub(crate) const COMPARE_OUTPUT_BY_LINES: &str = "compare-output-by-lines";
}
impl TestProps {
pub fn new() -> Self {
pub(crate) fn new() -> Self {
TestProps {
error_patterns: vec![],
regex_error_patterns: vec![],
@@ -322,7 +322,7 @@ pub fn new() -> Self {
}
}
pub fn from_aux_file(
pub(crate) fn from_aux_file(
&self,
testfile: &Utf8Path,
revision: Option<&str>,
@@ -338,7 +338,7 @@ pub fn from_aux_file(
props
}
pub fn from_file(testfile: &Utf8Path, revision: Option<&str>, config: &Config) -> Self {
pub(crate) fn from_file(testfile: &Utf8Path, revision: Option<&str>, config: &Config) -> Self {
let mut props = TestProps::new();
props.load_from(testfile, revision, config);
props.exec_env.push(("RUSTC".to_string(), config.rustc_path.to_string()));
@@ -475,7 +475,7 @@ fn update_pass_mode(&mut self, ln: &DirectiveLine<'_>, config: &Config) {
}
}
pub fn pass_mode(&self, config: &Config) -> Option<PassMode> {
pub(crate) fn pass_mode(&self, config: &Config) -> Option<PassMode> {
if !self.ignore_pass && self.fail_mode.is_none() {
if let mode @ Some(_) = config.force_pass_mode {
return mode;
@@ -485,7 +485,7 @@ pub fn pass_mode(&self, config: &Config) -> Option<PassMode> {
}
// does not consider CLI override for pass mode
pub fn local_pass_mode(&self) -> Option<PassMode> {
pub(crate) fn local_pass_mode(&self) -> Option<PassMode> {
self.pass_mode
}
@@ -872,7 +872,7 @@ fn parse_normalize_rule(raw_value: &str) -> Option<(String, String)> {
/// error handling strategy.
///
/// FIXME(jieyouxu): improve error handling
pub fn extract_llvm_version(version: &str) -> Version {
pub(crate) fn extract_llvm_version(version: &str) -> Version {
// The version substring we're interested in usually looks like the `1.2.3`, without any of the
// fancy suffix like `-rc1` or `meow`.
let version = version.trim();
@@ -895,7 +895,7 @@ pub fn extract_llvm_version(version: &str) -> Version {
}
}
pub fn extract_llvm_version_from_binary(binary_path: &str) -> Option<Version> {
pub(crate) fn extract_llvm_version_from_binary(binary_path: &str) -> Option<Version> {
let output = Command::new(binary_path).arg("--version").output().ok()?;
if !output.status.success() {
return None;
@@ -13,16 +13,16 @@
/// The value of an `aux-crate` directive.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AuxCrate {
pub(crate) struct AuxCrate {
/// Contains `--extern` modifiers, if any. See the tracking issue for more
/// info: <https://github.com/rust-lang/rust/issues/98405>
/// With `aux-crate: noprelude:foo=bar.rs` this will be `noprelude`.
pub extern_modifiers: Option<String>,
pub(crate) extern_modifiers: Option<String>,
/// With `aux-crate: foo=bar.rs` this will be `foo`.
/// With `aux-crate: noprelude:foo=bar.rs` this will be `foo`.
pub name: String,
pub(crate) name: String,
/// With `aux-crate: foo=bar.rs` this will be `bar.rs`.
pub path: String,
pub(crate) path: String,
}
/// The value of a `proc-macro` directive.
@@ -31,9 +31,9 @@ pub(crate) struct ProcMacro {
/// Contains `--extern` modifiers, if any. See the tracking issue for more
/// info: <https://github.com/rust-lang/rust/issues/98405>
/// With `proc-macro: noprelude:bar.rs` this will be `noprelude`.
pub extern_modifiers: Option<String>,
pub(crate) extern_modifiers: Option<String>,
/// With `proc-macro: bar.rs` this will be `bar.rs`.
pub path: String,
pub(crate) path: String,
}
/// Properties parsed from `aux-*` test directives.
+2 -2
View File
@@ -1,7 +1,7 @@
use crate::fatal;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Edition {
pub(crate) enum Edition {
// Note that the ordering here is load-bearing, as we want the future edition to be greater than
// any year-based edition.
Year(u32),
@@ -23,7 +23,7 @@ fn from(value: u32) -> Self {
}
}
pub fn parse_edition(mut input: &str) -> Edition {
pub(crate) fn parse_edition(mut input: &str) -> Edition {
input = input.trim();
if input == "future" {
Edition::Future
+10 -10
View File
@@ -9,7 +9,7 @@
use tracing::*;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ErrorKind {
pub(crate) enum ErrorKind {
Help,
Error,
Note,
@@ -21,7 +21,7 @@ pub enum ErrorKind {
}
impl ErrorKind {
pub fn from_compiler_str(s: &str) -> ErrorKind {
pub(crate) fn from_compiler_str(s: &str) -> ErrorKind {
match s {
"help" => ErrorKind::Help,
"error" | "error: internal compiler error" => ErrorKind::Error,
@@ -45,7 +45,7 @@ fn from_user_str(s: &str) -> Option<ErrorKind> {
})
}
pub fn expect_from_user_str(s: &str) -> ErrorKind {
pub(crate) fn expect_from_user_str(s: &str) -> ErrorKind {
ErrorKind::from_user_str(s).unwrap_or_else(|| {
panic!(
"unexpected diagnostic kind `{s}`, expected \
@@ -70,16 +70,16 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
#[derive(Debug)]
pub struct Error {
pub line_num: Option<usize>,
pub column_num: Option<usize>,
pub(crate) struct Error {
pub(crate) line_num: Option<usize>,
pub(crate) column_num: Option<usize>,
/// What kind of message we expect (e.g., warning, error, suggestion).
pub kind: ErrorKind,
pub msg: String,
pub(crate) kind: ErrorKind,
pub(crate) msg: String,
/// For some `Error`s, like secondary lines of multi-line diagnostics, line annotations
/// are not mandatory, even if they would otherwise be mandatory for primary errors.
/// Only makes sense for "actual" errors, not for "expected" errors.
pub require_annotation: bool,
pub(crate) require_annotation: bool,
}
/// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE"
@@ -92,7 +92,7 @@ pub struct Error {
///
/// If revision is not None, then we look
/// for `//[X]~` instead, where `X` is the current revision.
pub fn load_errors(testfile: &Utf8Path, revision: Option<&str>) -> Vec<Error> {
pub(crate) fn load_errors(testfile: &Utf8Path, revision: Option<&str>) -> Vec<Error> {
let rdr = BufReader::new(File::open(testfile.as_std_path()).unwrap());
// `last_nonfollow_error` tracks the most recently seen
+3 -3
View File
@@ -83,14 +83,14 @@ struct DiagnosticCode {
code: String,
}
pub fn rustfix_diagnostics_only(output: &str) -> String {
pub(crate) fn rustfix_diagnostics_only(output: &str) -> String {
output
.lines()
.filter(|line| line.starts_with('{') && serde_json::from_str::<Diagnostic>(line).is_ok())
.collect()
}
pub fn extract_rendered(output: &str) -> String {
pub(crate) fn extract_rendered(output: &str) -> String {
output
.lines()
.filter_map(|line| {
@@ -137,7 +137,7 @@ pub fn extract_rendered(output: &str) -> String {
.collect()
}
pub fn parse_output(file_name: &str, output: &str) -> Vec<Error> {
pub(crate) fn parse_output(file_name: &str, output: &str) -> Vec<Error> {
let mut errors = Vec::new();
for line in output.lines() {
// Compiler can emit non-json lines in non-`--error-format=json` modes,
+4 -1
View File
@@ -1,9 +1,13 @@
#![crate_name = "compiletest"]
#![warn(unreachable_pub)]
#[cfg(test)]
mod tests;
// Public modules needed by the compiletest binary or by `rustdoc-gui-test`.
pub mod cli;
pub mod rustdoc_gui_test;
mod common;
mod debuggers;
mod diagnostics;
@@ -17,7 +21,6 @@
mod raise_fd_limit;
mod read2;
mod runtest;
pub mod rustdoc_gui_test;
mod util;
use core::panic;
+1 -1
View File
@@ -2,7 +2,7 @@
use std::panic::RefUnwindSafe;
use std::sync::Mutex;
pub trait ConsoleOut: fmt::Debug + RefUnwindSafe {
pub(crate) trait ConsoleOut: fmt::Debug + RefUnwindSafe {
fn write_fmt(&self, args: fmt::Arguments<'_>);
}
+2 -2
View File
@@ -7,7 +7,7 @@
#[cfg(target_vendor = "apple")]
#[allow(non_camel_case_types)]
// FIXME(#139616): document caller contract.
pub unsafe fn raise_fd_limit() {
pub(crate) unsafe fn raise_fd_limit() {
use std::ptr::null_mut;
use std::{cmp, io};
@@ -54,4 +54,4 @@ pub unsafe fn raise_fd_limit() {
}
#[cfg(not(target_vendor = "apple"))]
pub unsafe fn raise_fd_limit() {}
pub(crate) unsafe fn raise_fd_limit() {}
+6 -6
View File
@@ -7,15 +7,15 @@
use std::io::{self, Write};
use std::process::{Child, Output};
pub use self::imp::read2;
use self::imp::read2;
#[derive(Copy, Clone, Debug)]
pub enum Truncated {
pub(crate) enum Truncated {
Yes,
No,
}
pub fn read2_abbreviated(
pub(crate) fn read2_abbreviated(
mut child: Child,
filter_paths_from_len: &[String],
) -> io::Result<(Output, Truncated)> {
@@ -138,7 +138,7 @@ mod imp {
use std::io::{self, Read};
use std::process::{ChildStderr, ChildStdout};
pub fn read2(
pub(crate) fn read2(
out_pipe: ChildStdout,
err_pipe: ChildStderr,
data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
@@ -160,7 +160,7 @@ mod imp {
use std::process::{ChildStderr, ChildStdout};
use std::{io, mem};
pub fn read2(
pub(crate) fn read2(
mut out_pipe: ChildStdout,
mut err_pipe: ChildStderr,
data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
@@ -247,7 +247,7 @@ struct Pipe<'a> {
done: bool,
}
pub fn read2(
pub(crate) fn read2(
out_pipe: ChildStdout,
err_pipe: ChildStderr,
data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
+4 -4
View File
@@ -106,7 +106,7 @@ fn dylib_name(name: &str) -> String {
format!("{}{name}.{}", std::env::consts::DLL_PREFIX, std::env::consts::DLL_EXTENSION)
}
pub fn run(
pub(crate) fn run(
config: &Config,
stdout: &dyn ConsoleOut,
stderr: &dyn ConsoleOut,
@@ -181,7 +181,7 @@ pub fn run(
cx.create_stamp();
}
pub fn compute_stamp_hash(config: &Config) -> String {
pub(crate) fn compute_stamp_hash(config: &Config) -> String {
let mut hash = DefaultHasher::new();
config.stage_id.hash(&mut hash);
config.run.hash(&mut hash);
@@ -2985,7 +2985,7 @@ struct ProcArgs {
}
#[derive(Debug)]
pub struct ProcRes {
pub(crate) struct ProcRes {
status: ExitStatus,
stdout: String,
stderr: String,
@@ -2995,7 +2995,7 @@ pub struct ProcRes {
impl ProcRes {
#[must_use]
pub fn format_info(&self) -> String {
pub(crate) fn format_info(&self) -> String {
fn render(name: &str, contents: &str) -> String {
let contents = json::extract_rendered(contents);
let contents = contents.trim_end();
@@ -1,16 +1,16 @@
use std::collections::VecDeque;
#[derive(Debug, PartialEq)]
pub enum DiffLine {
pub(crate) enum DiffLine {
Context(String),
Expected(String),
Resulting(String),
}
#[derive(Debug, PartialEq)]
pub struct Mismatch {
pub line_number: u32,
pub lines: Vec<DiffLine>,
pub(crate) struct Mismatch {
pub(crate) line_number: u32,
pub(crate) lines: Vec<DiffLine>,
}
impl Mismatch {
@@ -20,7 +20,7 @@ fn new(line_number: u32) -> Mismatch {
}
// Produces a diff between the expected output and actual output.
pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
pub(crate) fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
let mut line_number = 1;
let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
let mut lines_since_mismatch = context_size + 1;
@@ -8,11 +8,11 @@
use crate::runtest::ProcRes;
/// Representation of information to invoke a debugger and check its output
pub(super) struct DebuggerCommands {
pub(crate) struct DebuggerCommands {
/// Commands for the debuuger
pub commands: Vec<String>,
pub(crate) commands: Vec<String>,
/// Lines to insert breakpoints at
pub breakpoint_lines: Vec<LineNumber>,
pub(crate) breakpoint_lines: Vec<LineNumber>,
/// Contains the source line number to check and the line itself
check_lines: Vec<(LineNumber, String)>,
/// Source file name
@@ -22,7 +22,7 @@ pub(super) struct DebuggerCommands {
}
impl DebuggerCommands {
pub fn parse_from(
pub(crate) fn parse_from(
file: &Utf8Path,
debugger_prefix: &str,
test_revision: Option<&str>,
@@ -75,7 +75,7 @@ pub fn parse_from(
/// Given debugger output and lines to check, ensure that every line is
/// contained in the debugger output. The check lines need to be found in
/// order, but there can be extra lines between.
pub fn check_output(&self, debugger_run_result: &ProcRes) -> Result<(), String> {
pub(crate) fn check_output(&self, debugger_run_result: &ProcRes) -> Result<(), String> {
// (src_lineno, ck_line) that we did find
let mut found = vec![];
// (src_lineno, ck_line) that we couldn't find
+6 -6
View File
@@ -6,7 +6,7 @@
#[cfg(test)]
mod tests;
pub fn make_new_path(path: &str) -> String {
pub(crate) fn make_new_path(path: &str) -> String {
assert!(cfg!(windows));
// Windows just uses PATH as the library search path, so we have to
// maintain the current value while adding our own
@@ -16,14 +16,14 @@ pub fn make_new_path(path: &str) -> String {
}
}
pub fn lib_path_env_var() -> &'static str {
pub(crate) fn lib_path_env_var() -> &'static str {
"PATH"
}
fn path_div() -> &'static str {
";"
}
pub trait Utf8PathBufExt {
pub(crate) trait Utf8PathBufExt {
/// Append an extension to the path, even if it already has one.
fn with_extra_extension(&self, extension: &str) -> Utf8PathBuf;
}
@@ -44,7 +44,7 @@ fn with_extra_extension(&self, extension: &str) -> Utf8PathBuf {
}
/// The name of the environment variable that holds dynamic library locations.
pub fn dylib_env_var() -> &'static str {
pub(crate) fn dylib_env_var() -> &'static str {
if cfg!(any(windows, target_os = "cygwin")) {
"PATH"
} else if cfg!(target_vendor = "apple") {
@@ -60,7 +60,7 @@ pub fn dylib_env_var() -> &'static str {
/// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
/// If the dylib_path_var is already set for this cmd, the old value will be overwritten!
pub fn add_dylib_path(
pub(crate) fn add_dylib_path(
cmd: &mut Command,
paths: impl Iterator<Item = impl Into<std::path::PathBuf>>,
) {
@@ -70,7 +70,7 @@ pub fn add_dylib_path(
cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap());
}
pub fn copy_dir_all(src: &Utf8Path, dst: &Utf8Path) -> std::io::Result<()> {
pub(crate) fn copy_dir_all(src: &Utf8Path, dst: &Utf8Path) -> std::io::Result<()> {
std::fs::create_dir_all(dst.as_std_path())?;
for entry in std::fs::read_dir(src.as_std_path())? {
let entry = entry?;
+12
View File
@@ -4,6 +4,7 @@
#![feature(rustdoc_missing_doc_code_examples)] //~ WARN no documentation found for this crate's top-level module
//~^ WARN
#![feature(decl_macro)]
#![warn(missing_docs)]
#![warn(rustdoc::missing_doc_code_examples)]
@@ -12,3 +13,14 @@
pub fn foo() {}
//~^ WARN
//~^^ WARN
#[macro_export]
macro_rules! bar {
//~^ WARN missing documentation
//~^^ WARN missing code example
() => {};
}
pub macro bar_v2() {}
//~^ WARN missing documentation
//~^^ WARN missing code example
+40 -14
View File
@@ -3,55 +3,81 @@ warning: missing documentation for the crate
|
LL | / #![feature(rustdoc_missing_doc_code_examples)]
LL | |
LL | |
LL | | #![warn(missing_docs)]
LL | | #![feature(decl_macro)]
... |
LL | | pub fn foo() {}
| |_______________^
LL | | pub macro bar_v2() {}
| |_____________________^
|
note: the lint level is defined here
--> $DIR/check.rs:8:9
--> $DIR/check.rs:9:9
|
LL | #![warn(missing_docs)]
| ^^^^^^^^^^^^
warning: missing documentation for a function
--> $DIR/check.rs:12:1
--> $DIR/check.rs:13:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^
warning: missing documentation for a macro
--> $DIR/check.rs:18:1
|
LL | macro_rules! bar {
| ^^^^^^^^^^^^^^^^
warning: missing documentation for a macro
--> $DIR/check.rs:24:1
|
LL | pub macro bar_v2() {}
| ^^^^^^^^^^^^^^^^
warning: no documentation found for this crate's top-level module
--> $DIR/check.rs:5:1
|
LL | / #![feature(rustdoc_missing_doc_code_examples)]
LL | |
LL | |
LL | | #![warn(missing_docs)]
LL | | #![feature(decl_macro)]
... |
LL | | pub fn foo() {}
| |_______________^
LL | | pub macro bar_v2() {}
| |_____________________^
|
= help: The following guide may be of use:
https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
note: the lint level is defined here
--> $DIR/check.rs:10:9
--> $DIR/check.rs:11:9
|
LL | #![warn(rustdoc::all)]
| ^^^^^^^^^^^^
= note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc::all)]`
warning: missing code example in this documentation
--> $DIR/check.rs:12:1
--> $DIR/check.rs:13:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/check.rs:9:9
--> $DIR/check.rs:10:9
|
LL | #![warn(rustdoc::missing_doc_code_examples)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: 4 warnings emitted
warning: missing code example in this documentation
--> $DIR/check.rs:24:1
|
LL | pub macro bar_v2() {}
| ^^^^^^^^^^^^^^^^^^^^^
warning: missing code example in this documentation
--> $DIR/check.rs:18:1
|
LL | / macro_rules! bar {
LL | |
LL | |
LL | | () => {};
LL | | }
| |_^
warning: 8 warnings emitted
@@ -0,0 +1,24 @@
//@ edition: 2024
extern crate missing_154096;
//~^ ERROR can't find crate for `missing_154096`
mod defs {
pub use missing_154096::Thing;
}
pub use defs::Thing;
mod first {
use crate::Thing;
pub fn take(_: Thing) {}
}
mod second {
use crate::Thing;
pub fn take(_: Thing) {}
}
fn main() {}
@@ -0,0 +1,9 @@
error[E0463]: can't find crate for `missing_154096`
--> $DIR/missing-extern-crate-cascade-issue-154096.rs:3:1
|
LL | extern crate missing_154096;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0463`.
@@ -0,0 +1,20 @@
//@ aux-build:crateresolve1-1.rs
//@ aux-build:crateresolve1-2.rs
//@ aux-build:crateresolve1-3.rs
//@ normalize-stderr: "multiple-candidates-cascade-issue-118130\..+/auxiliary/" -> "multiple-candidates-cascade-issue-118130/auxiliary/"
//@ normalize-stderr: "\\\?\\" -> ""
//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"
extern crate crateresolve1;
//~^ ERROR multiple candidates for `rlib` dependency `crateresolve1` found
mod defs {
pub use crateresolve1::f;
}
pub use defs::f;
fn main() {
let _ = f();
}
@@ -0,0 +1,13 @@
error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found
--> $DIR/multiple-candidates-cascade-issue-118130.rs:9:1
|
LL | extern crate crateresolve1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib
= note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib
= note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0464`.
@@ -0,0 +1,20 @@
//! Regression test for <https://github.com/rust-lang/rust/issues/115858>.
//!
//! The compiler used to suggest `crate::crate::unix::linux::system::Y`
//! (duplicating the `crate` keyword) instead of `crate::unix::linux::system::Y`.
pub mod unix {
pub mod linux {
pub mod utils {
pub fn f() {
let _x = crate::linux::system::Y;
//~^ ERROR cannot find `linux` in `crate`
}
}
pub mod system {
pub const Y: u32 = 0;
}
}
}
fn main() {}
@@ -0,0 +1,23 @@
error[E0433]: cannot find `linux` in `crate`
--> $DIR/path-suggestion-duplicated-crate-keyword.rs:10:33
|
LL | let _x = crate::linux::system::Y;
| ^^^^^ unresolved import
|
help: a similar path exists
|
LL | let _x = crate::unix::linux::system::Y;
| ++++++
help: consider importing this module
|
LL + use unix::linux::system;
|
help: if you import `system`, refer to it directly
|
LL - let _x = crate::linux::system::Y;
LL + let _x = system::Y;
|
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0433`.
@@ -3,6 +3,5 @@
use bar::foo; //~ ERROR can't find crate for `bar`
use foo::bar;
//~^^ ERROR unresolved imports `bar::foo`, `foo::bar`
fn main() {}
@@ -4,15 +4,6 @@ error[E0463]: can't find crate for `bar`
LL | use bar::foo;
| ^^^ can't find crate
error[E0432]: unresolved imports `bar::foo`, `foo::bar`
--> $DIR/deadlock.rs:4:5
|
LL | use bar::foo;
| ^^^^^^^^
LL | use foo::bar;
| ^^^^^^^^
error: aborting due to 1 previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0432, E0463.
For more information about an error, try `rustc --explain E0432`.
For more information about this error, try `rustc --explain E0463`.