Auto merge of #149891 - matthiaskrgr:rollup-jh6xrhz, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang/rust#142380 (Put negative implementors first and apply same ordering logic to foreign implementors) - rust-lang/rust#146584 (remove duplicated columns from `rustc_error_code::error_codes!`) - rust-lang/rust#148717 (Point at span within local macros even when error happens in nested external macro) - rust-lang/rust#149565 (rustdoc: Add unstable `--merge-doctests=yes/no/auto` flag) - rust-lang/rust#149770 (Rename some issue-* tests) - rust-lang/rust#149807 (Use ubuntu:24.04 for the `x86_64-gnu-miri` job) - rust-lang/rust#149850 (Remove "tidy" tool for `tests/rustdoc` testsuite) - rust-lang/rust#149863 (Do not suggest moving expression out of for loop when hitting `break` from desugaring) - rust-lang/rust#149867 (only resolve main in bin crates) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c4dc70ee0a
115 changed files with 1697 additions and 1104 deletions
|
|
@ -4521,7 +4521,9 @@ struct BreakFinder {
|
|||
impl<'hir> Visitor<'hir> for BreakFinder {
|
||||
fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
|
||||
match ex.kind {
|
||||
hir::ExprKind::Break(destination, _) => {
|
||||
hir::ExprKind::Break(destination, _)
|
||||
if !ex.span.is_desugaring(DesugaringKind::ForLoop) =>
|
||||
{
|
||||
self.found_breaks.push((destination, ex.span));
|
||||
}
|
||||
hir::ExprKind::Continue(destination) => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#### this error code is no longer emitted by the compiler.
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
This was triggered when multiple macro definitions used the same
|
||||
`#[rustc_builtin_macro(..)]`. This is no longer an error.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -23,15 +23,15 @@ impl fmt::Display for ErrCode {
|
|||
rustc_error_messages::into_diag_arg_using_display!(ErrCode);
|
||||
|
||||
macro_rules! define_error_code_constants_and_diagnostics_table {
|
||||
($($name:ident: $num:literal,)*) => (
|
||||
($($num:literal,)*) => (
|
||||
$(
|
||||
pub const $name: $crate::ErrCode = $crate::ErrCode::from_u32($num);
|
||||
pub const ${concat(E, $num)}: $crate::ErrCode = $crate::ErrCode::from_u32($num);
|
||||
)*
|
||||
pub static DIAGNOSTICS: &[($crate::ErrCode, &str)] = &[
|
||||
$( (
|
||||
$name,
|
||||
${concat(E, $num)},
|
||||
include_str!(
|
||||
concat!("../../rustc_error_codes/src/error_codes/", stringify!($name), ".md")
|
||||
concat!("../../rustc_error_codes/src/error_codes/E", stringify!($num), ".md")
|
||||
)
|
||||
), )*
|
||||
];
|
||||
|
|
|
|||
|
|
@ -474,9 +474,12 @@ pub trait Emitter {
|
|||
.chain(span.span_labels().iter().map(|sp_label| sp_label.span))
|
||||
.filter_map(|sp| {
|
||||
if !sp.is_dummy() && source_map.is_imported(sp) {
|
||||
let maybe_callsite = sp.source_callsite();
|
||||
if sp != maybe_callsite {
|
||||
return Some((sp, maybe_callsite));
|
||||
let mut span = sp;
|
||||
while let Some(callsite) = span.parent_callsite() {
|
||||
span = callsite;
|
||||
if !source_map.is_imported(span) {
|
||||
return Some((sp, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#![feature(box_patterns)]
|
||||
#![feature(default_field_values)]
|
||||
#![feature(error_reporter)]
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ use rustc_middle::ty::{
|
|||
ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
|
||||
};
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
|
||||
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
|
||||
use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym};
|
||||
|
|
@ -2430,6 +2431,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
|
||||
fn resolve_main(&mut self) {
|
||||
let any_exe = self.tcx.crate_types().contains(&CrateType::Executable);
|
||||
// Don't try to resolve main unless it's an executable
|
||||
if !any_exe {
|
||||
return;
|
||||
}
|
||||
|
||||
let module = self.graph_root;
|
||||
let ident = Ident::with_dummy_span(sym::main);
|
||||
let parent_scope = &ParentScope::module(module, self.arenas);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM ubuntu:22.04
|
||||
FROM ghcr.io/rust-lang/ubuntu:24.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM ghcr.io/rust-lang/ubuntu:22.04
|
||||
FROM ghcr.io/rust-lang/ubuntu:24.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
|
|
|||
|
|
@ -63,6 +63,15 @@ pub(crate) enum InputMode {
|
|||
HasFile(Input),
|
||||
}
|
||||
|
||||
/// Whether to run multiple doctests in the same binary.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
|
||||
pub(crate) enum MergeDoctests {
|
||||
#[default]
|
||||
Never,
|
||||
Always,
|
||||
Auto,
|
||||
}
|
||||
|
||||
/// Configuration options for rustdoc.
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Options {
|
||||
|
|
@ -121,6 +130,8 @@ pub(crate) struct Options {
|
|||
/// Optional path to persist the doctest executables to, defaults to a
|
||||
/// temporary directory if not set.
|
||||
pub(crate) persist_doctests: Option<PathBuf>,
|
||||
/// Whether to merge
|
||||
pub(crate) merge_doctests: MergeDoctests,
|
||||
/// Runtool to run doctests with
|
||||
pub(crate) test_runtool: Option<String>,
|
||||
/// Arguments to pass to the runtool
|
||||
|
|
@ -801,6 +812,8 @@ impl Options {
|
|||
Ok(result) => result,
|
||||
Err(e) => dcx.fatal(format!("--merge option error: {e}")),
|
||||
};
|
||||
let merge_doctests = parse_merge_doctests(matches, edition, dcx);
|
||||
tracing::debug!("merge_doctests: {merge_doctests:?}");
|
||||
|
||||
if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) {
|
||||
dcx.struct_warn(
|
||||
|
|
@ -852,6 +865,7 @@ impl Options {
|
|||
crate_version,
|
||||
test_run_directory,
|
||||
persist_doctests,
|
||||
merge_doctests,
|
||||
test_runtool,
|
||||
test_runtool_args,
|
||||
test_builder,
|
||||
|
|
@ -1048,3 +1062,20 @@ fn parse_merge(m: &getopts::Matches) -> Result<ShouldMerge, &'static str> {
|
|||
Some(_) => Err("argument to --merge must be `none`, `shared`, or `finalize`"),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_merge_doctests(
|
||||
m: &getopts::Matches,
|
||||
edition: Edition,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
) -> MergeDoctests {
|
||||
match m.opt_str("merge-doctests").as_deref() {
|
||||
Some("y") | Some("yes") | Some("on") | Some("true") => MergeDoctests::Always,
|
||||
Some("n") | Some("no") | Some("off") | Some("false") => MergeDoctests::Never,
|
||||
Some("auto") => MergeDoctests::Auto,
|
||||
None if edition < Edition::Edition2024 => MergeDoctests::Never,
|
||||
None => MergeDoctests::Auto,
|
||||
Some(_) => {
|
||||
dcx.fatal("argument to --merge-doctests must be a boolean (true/false) or 'auto'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ use tempfile::{Builder as TempFileBuilder, TempDir};
|
|||
use tracing::debug;
|
||||
|
||||
use self::rust::HirCollector;
|
||||
use crate::config::{Options as RustdocOptions, OutputFormat};
|
||||
use crate::config::{MergeDoctests, Options as RustdocOptions, OutputFormat};
|
||||
use crate::html::markdown::{ErrorCodes, Ignore, LangString, MdRelLine};
|
||||
use crate::lint::init_lints;
|
||||
|
||||
|
|
@ -125,8 +125,13 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) ->
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn get_doctest_dir() -> io::Result<TempDir> {
|
||||
TempFileBuilder::new().prefix("rustdoctest").tempdir()
|
||||
fn get_doctest_dir(opts: &RustdocOptions) -> io::Result<TempDir> {
|
||||
let mut builder = TempFileBuilder::new();
|
||||
builder.prefix("rustdoctest");
|
||||
if opts.codegen_options.save_temps {
|
||||
builder.disable_cleanup(true);
|
||||
}
|
||||
builder.tempdir()
|
||||
}
|
||||
|
||||
pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions) {
|
||||
|
|
@ -199,7 +204,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
|
|||
let externs = options.externs.clone();
|
||||
let json_unused_externs = options.json_unused_externs;
|
||||
|
||||
let temp_dir = match get_doctest_dir()
|
||||
let temp_dir = match get_doctest_dir(&options)
|
||||
.map_err(|error| format!("failed to create temporary directory: {error:?}"))
|
||||
{
|
||||
Ok(temp_dir) => temp_dir,
|
||||
|
|
@ -209,6 +214,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
|
|||
crate::wrap_return(dcx, generate_args_file(&args_path, &options));
|
||||
|
||||
let extract_doctests = options.output_format == OutputFormat::Doctest;
|
||||
let save_temps = options.codegen_options.save_temps;
|
||||
let result = interface::run_compiler(config, |compiler| {
|
||||
let krate = rustc_interface::passes::parse(&compiler.sess);
|
||||
|
||||
|
|
@ -260,12 +266,15 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
|
|||
eprintln!("{error}");
|
||||
// Since some files in the temporary folder are still owned and alive, we need
|
||||
// to manually remove the folder.
|
||||
let _ = std::fs::remove_dir_all(temp_dir.path());
|
||||
if !save_temps {
|
||||
let _ = std::fs::remove_dir_all(temp_dir.path());
|
||||
}
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
run_tests(
|
||||
dcx,
|
||||
opts,
|
||||
&rustdoc_options,
|
||||
&unused_extern_reports,
|
||||
|
|
@ -317,6 +326,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
|
|||
}
|
||||
|
||||
pub(crate) fn run_tests(
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
opts: GlobalTestOptions,
|
||||
rustdoc_options: &Arc<RustdocOptions>,
|
||||
unused_extern_reports: &Arc<Mutex<Vec<UnusedExterns>>>,
|
||||
|
|
@ -369,6 +379,13 @@ pub(crate) fn run_tests(
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if rustdoc_options.merge_doctests == MergeDoctests::Always {
|
||||
let mut diag = dcx.struct_fatal("failed to merge doctests");
|
||||
diag.note("requested explicitly on the command line with `--merge-doctests=yes`");
|
||||
diag.emit();
|
||||
}
|
||||
|
||||
// We failed to compile all compatible tests as one so we push them into the
|
||||
// `standalone_tests` doctests.
|
||||
debug!("Failed to compile compatible doctests for edition {} all at once", edition);
|
||||
|
|
@ -653,9 +670,9 @@ fn run_test(
|
|||
// tested as standalone tests.
|
||||
return (Duration::default(), Err(TestFailure::CompileError));
|
||||
}
|
||||
if !rustdoc_options.no_capture {
|
||||
// If `no_capture` is disabled, then we don't display rustc's output when compiling
|
||||
// the merged doctests.
|
||||
if !rustdoc_options.no_capture && rustdoc_options.merge_doctests == MergeDoctests::Auto {
|
||||
// If `no_capture` is disabled, and we might fallback to standalone tests, then we don't
|
||||
// display rustc's output when compiling the merged doctests.
|
||||
compiler.stderr(Stdio::null());
|
||||
}
|
||||
// bundled tests are an rlib, loaded by a separate runner executable
|
||||
|
|
@ -736,10 +753,12 @@ fn run_test(
|
|||
// tested as standalone tests.
|
||||
return (instant.elapsed(), Err(TestFailure::CompileError));
|
||||
}
|
||||
if !rustdoc_options.no_capture {
|
||||
// If `no_capture` is disabled, then we don't display rustc's output when compiling
|
||||
// the merged doctests.
|
||||
if !rustdoc_options.no_capture && rustdoc_options.merge_doctests == MergeDoctests::Auto {
|
||||
// If `no_capture` is disabled and we're autodetecting whether to merge,
|
||||
// we don't display rustc's output when compiling the merged doctests.
|
||||
runner_compiler.stderr(Stdio::null());
|
||||
} else {
|
||||
runner_compiler.stderr(Stdio::inherit());
|
||||
}
|
||||
runner_compiler.arg("--error-format=short");
|
||||
debug!("compiler invocation for doctest runner: {runner_compiler:?}");
|
||||
|
|
@ -896,7 +915,7 @@ impl IndividualTestOptions {
|
|||
|
||||
DirState::Perm(path)
|
||||
} else {
|
||||
DirState::Temp(get_doctest_dir().expect("rustdoc needs a tempdir"))
|
||||
DirState::Temp(get_doctest_dir(options).expect("rustdoc needs a tempdir"))
|
||||
};
|
||||
|
||||
Self { outdir, path: test_path }
|
||||
|
|
@ -985,21 +1004,20 @@ struct CreateRunnableDocTests {
|
|||
visited_tests: FxHashMap<(String, usize), usize>,
|
||||
unused_extern_reports: Arc<Mutex<Vec<UnusedExterns>>>,
|
||||
compiling_test_count: AtomicUsize,
|
||||
can_merge_doctests: bool,
|
||||
can_merge_doctests: MergeDoctests,
|
||||
}
|
||||
|
||||
impl CreateRunnableDocTests {
|
||||
fn new(rustdoc_options: RustdocOptions, opts: GlobalTestOptions) -> CreateRunnableDocTests {
|
||||
let can_merge_doctests = rustdoc_options.edition >= Edition::Edition2024;
|
||||
CreateRunnableDocTests {
|
||||
standalone_tests: Vec::new(),
|
||||
mergeable_tests: FxIndexMap::default(),
|
||||
rustdoc_options: Arc::new(rustdoc_options),
|
||||
opts,
|
||||
visited_tests: FxHashMap::default(),
|
||||
unused_extern_reports: Default::default(),
|
||||
compiling_test_count: AtomicUsize::new(0),
|
||||
can_merge_doctests,
|
||||
can_merge_doctests: rustdoc_options.merge_doctests,
|
||||
rustdoc_options: Arc::new(rustdoc_options),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use rustc_span::{DUMMY_SP, FileName, Span, kw};
|
|||
use tracing::debug;
|
||||
|
||||
use super::GlobalTestOptions;
|
||||
use crate::config::MergeDoctests;
|
||||
use crate::display::Joined as _;
|
||||
use crate::html::markdown::LangString;
|
||||
|
||||
|
|
@ -41,7 +42,7 @@ pub(crate) struct BuildDocTestBuilder<'a> {
|
|||
source: &'a str,
|
||||
crate_name: Option<&'a str>,
|
||||
edition: Edition,
|
||||
can_merge_doctests: bool,
|
||||
can_merge_doctests: MergeDoctests,
|
||||
// If `test_id` is `None`, it means we're generating code for a code example "run" link.
|
||||
test_id: Option<String>,
|
||||
lang_str: Option<&'a LangString>,
|
||||
|
|
@ -55,7 +56,7 @@ impl<'a> BuildDocTestBuilder<'a> {
|
|||
source,
|
||||
crate_name: None,
|
||||
edition: DEFAULT_EDITION,
|
||||
can_merge_doctests: false,
|
||||
can_merge_doctests: MergeDoctests::Never,
|
||||
test_id: None,
|
||||
lang_str: None,
|
||||
span: DUMMY_SP,
|
||||
|
|
@ -70,7 +71,7 @@ impl<'a> BuildDocTestBuilder<'a> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn can_merge_doctests(mut self, can_merge_doctests: bool) -> Self {
|
||||
pub(crate) fn can_merge_doctests(mut self, can_merge_doctests: MergeDoctests) -> Self {
|
||||
self.can_merge_doctests = can_merge_doctests;
|
||||
self
|
||||
}
|
||||
|
|
@ -117,10 +118,6 @@ impl<'a> BuildDocTestBuilder<'a> {
|
|||
span,
|
||||
global_crate_attrs,
|
||||
} = self;
|
||||
let can_merge_doctests = can_merge_doctests
|
||||
&& lang_str.is_some_and(|lang_str| {
|
||||
!lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate
|
||||
});
|
||||
|
||||
let result = rustc_driver::catch_fatal_errors(|| {
|
||||
rustc_span::create_session_if_not_set_then(edition, |_| {
|
||||
|
|
@ -155,14 +152,27 @@ impl<'a> BuildDocTestBuilder<'a> {
|
|||
debug!("crate_attrs:\n{crate_attrs}{maybe_crate_attrs}");
|
||||
debug!("crates:\n{crates}");
|
||||
debug!("after:\n{everything_else}");
|
||||
debug!("merge-doctests: {can_merge_doctests:?}");
|
||||
|
||||
// If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either.
|
||||
let can_be_merged = can_merge_doctests
|
||||
&& !has_global_allocator
|
||||
&& crate_attrs.is_empty()
|
||||
// If this is a merged doctest and a defined macro uses `$crate`, then the path will
|
||||
// not work, so better not put it into merged doctests.
|
||||
&& !(has_macro_def && everything_else.contains("$crate"));
|
||||
// Up until now, we've been dealing with settings for the whole crate.
|
||||
// Now, infer settings for this particular test.
|
||||
//
|
||||
// Avoid tests with incompatible attributes.
|
||||
let opt_out = lang_str.is_some_and(|lang_str| {
|
||||
lang_str.compile_fail || lang_str.test_harness || lang_str.standalone_crate
|
||||
});
|
||||
let can_be_merged = if can_merge_doctests == MergeDoctests::Auto {
|
||||
// We try to look at the contents of the test to detect whether it should be merged.
|
||||
// This is not a complete list of possible failures, but it catches many cases.
|
||||
let will_probably_fail = has_global_allocator
|
||||
|| !crate_attrs.is_empty()
|
||||
// If this is a merged doctest and a defined macro uses `$crate`, then the path will
|
||||
// not work, so better not put it into merged doctests.
|
||||
|| (has_macro_def && everything_else.contains("$crate"));
|
||||
!opt_out && !will_probably_fail
|
||||
} else {
|
||||
can_merge_doctests != MergeDoctests::Never && !opt_out
|
||||
};
|
||||
DocTestBuilder {
|
||||
supports_color,
|
||||
has_main_fn,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
use std::fs::read_to_string;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_session::config::Input;
|
||||
use rustc_span::{DUMMY_SP, FileName};
|
||||
use tempfile::tempdir;
|
||||
|
|
@ -78,7 +79,7 @@ impl DocTestVisitor for MdCollector {
|
|||
}
|
||||
|
||||
/// Runs any tests/code examples in the markdown file `options.input`.
|
||||
pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
|
||||
pub(crate) fn test(input: &Input, options: Options, dcx: DiagCtxtHandle<'_>) -> Result<(), String> {
|
||||
let input_str = match input {
|
||||
Input::File(path) => {
|
||||
read_to_string(path).map_err(|err| format!("{}: {err}", path.display()))?
|
||||
|
|
@ -118,6 +119,7 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
|
|||
let CreateRunnableDocTests { opts, rustdoc_options, standalone_tests, mergeable_tests, .. } =
|
||||
collector;
|
||||
crate::doctest::run_tests(
|
||||
dcx,
|
||||
opts,
|
||||
&rustdoc_options,
|
||||
&Arc::new(Mutex::new(Vec::new())),
|
||||
|
|
|
|||
|
|
@ -76,4 +76,8 @@ impl Impl {
|
|||
};
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn is_negative_trait_impl(&self) -> bool {
|
||||
self.inner_impl().is_negative_trait_impl()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -646,6 +646,27 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp
|
|||
})
|
||||
}
|
||||
|
||||
/// Struct used to handle insertion of "negative impl" marker in the generated DOM.
|
||||
///
|
||||
/// This marker appears once in all trait impl lists to divide negative impls from positive impls.
|
||||
struct NegativeMarker {
|
||||
inserted: bool,
|
||||
}
|
||||
|
||||
impl NegativeMarker {
|
||||
fn new() -> Self {
|
||||
Self { inserted: false }
|
||||
}
|
||||
|
||||
fn insert_if_needed(&mut self, w: &mut fmt::Formatter<'_>, implementor: &Impl) -> fmt::Result {
|
||||
if !self.inserted && !implementor.is_negative_trait_impl() {
|
||||
w.write_str("<div class=\"negative-marker\"></div>")?;
|
||||
self.inserted = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display {
|
||||
fmt::from_fn(|w| {
|
||||
let tcx = cx.tcx();
|
||||
|
|
@ -1072,7 +1093,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt:
|
|||
"<div id=\"implementors-list\">",
|
||||
)
|
||||
)?;
|
||||
let mut negative_marker = NegativeMarker::new();
|
||||
for implementor in concrete {
|
||||
negative_marker.insert_if_needed(w, implementor)?;
|
||||
write!(w, "{}", render_implementor(cx, implementor, it, &implementor_dups, &[]))?;
|
||||
}
|
||||
w.write_str("</div>")?;
|
||||
|
|
@ -1088,7 +1111,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt:
|
|||
"<div id=\"synthetic-implementors-list\">",
|
||||
)
|
||||
)?;
|
||||
let mut negative_marker = NegativeMarker::new();
|
||||
for implementor in synthetic {
|
||||
negative_marker.insert_if_needed(w, implementor)?;
|
||||
write!(
|
||||
w,
|
||||
"{}",
|
||||
|
|
@ -2302,11 +2327,18 @@ where
|
|||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct ImplString(String);
|
||||
struct ImplString {
|
||||
rendered: String,
|
||||
is_negative: bool,
|
||||
}
|
||||
|
||||
impl ImplString {
|
||||
fn new(i: &Impl, cx: &Context<'_>) -> ImplString {
|
||||
ImplString(format!("{}", print_impl(i.inner_impl(), false, cx)))
|
||||
let impl_ = i.inner_impl();
|
||||
ImplString {
|
||||
is_negative: impl_.is_negative_trait_impl(),
|
||||
rendered: format!("{}", print_impl(impl_, false, cx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2318,7 +2350,12 @@ impl PartialOrd for ImplString {
|
|||
|
||||
impl Ord for ImplString {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
compare_names(&self.0, &other.0)
|
||||
// We sort negative impls first.
|
||||
match (self.is_negative, other.is_negative) {
|
||||
(false, true) => Ordering::Greater,
|
||||
(true, false) => Ordering::Less,
|
||||
_ => compare_names(&self.rendered, &other.rendered),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
//! or contains "invocation-specific".
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write as _};
|
||||
|
|
@ -47,6 +48,7 @@ use crate::formats::item_type::ItemType;
|
|||
use crate::html::format::{print_impl, print_path};
|
||||
use crate::html::layout;
|
||||
use crate::html::render::ordered_json::{EscapedJson, OrderedJson};
|
||||
use crate::html::render::print_item::compare_names;
|
||||
use crate::html::render::search_index::{SerializedSearchIndex, build_index};
|
||||
use crate::html::render::sorted_template::{self, FileFormat, SortedTemplate};
|
||||
use crate::html::render::{AssocItemLink, ImplRenderingParameters, StylePath};
|
||||
|
|
@ -667,7 +669,7 @@ impl TraitAliasPart {
|
|||
fn blank() -> SortedTemplate<<Self as CciPart>::FileFormat> {
|
||||
SortedTemplate::from_before_after(
|
||||
r"(function() {
|
||||
var implementors = Object.fromEntries([",
|
||||
const implementors = Object.fromEntries([",
|
||||
r"]);
|
||||
if (window.register_implementors) {
|
||||
window.register_implementors(implementors);
|
||||
|
|
@ -720,10 +722,12 @@ impl TraitAliasPart {
|
|||
{
|
||||
None
|
||||
} else {
|
||||
let impl_ = imp.inner_impl();
|
||||
Some(Implementor {
|
||||
text: print_impl(imp.inner_impl(), false, cx).to_string(),
|
||||
text: print_impl(impl_, false, cx).to_string(),
|
||||
synthetic: imp.inner_impl().kind.is_auto(),
|
||||
types: collect_paths_for_type(&imp.inner_impl().for_, cache),
|
||||
is_negative: impl_.is_negative_trait_impl(),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
@ -742,8 +746,22 @@ impl TraitAliasPart {
|
|||
}
|
||||
path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1]));
|
||||
|
||||
let part = OrderedJson::array_sorted(
|
||||
implementors.map(|implementor| OrderedJson::serialize(implementor).unwrap()),
|
||||
let mut implementors = implementors.collect::<Vec<_>>();
|
||||
implementors.sort_unstable_by(|a, b| {
|
||||
// We sort negative impls first.
|
||||
match (a.is_negative, b.is_negative) {
|
||||
(false, true) => Ordering::Greater,
|
||||
(true, false) => Ordering::Less,
|
||||
_ => compare_names(&a.text, &b.text),
|
||||
}
|
||||
});
|
||||
|
||||
let part = OrderedJson::array_unsorted(
|
||||
implementors
|
||||
.iter()
|
||||
.map(OrderedJson::serialize)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.unwrap(),
|
||||
);
|
||||
path_parts.push(path, OrderedJson::array_unsorted([crate_name_json, &part]));
|
||||
}
|
||||
|
|
@ -755,6 +773,7 @@ struct Implementor {
|
|||
text: String,
|
||||
synthetic: bool,
|
||||
types: Vec<String>,
|
||||
is_negative: bool,
|
||||
}
|
||||
|
||||
impl Serialize for Implementor {
|
||||
|
|
@ -764,6 +783,7 @@ impl Serialize for Implementor {
|
|||
{
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
seq.serialize_element(&self.text)?;
|
||||
seq.serialize_element(if self.is_negative { &1 } else { &0 })?;
|
||||
if self.synthetic {
|
||||
seq.serialize_element(&1)?;
|
||||
seq.serialize_element(&self.types)?;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ fn trait_alias_template() {
|
|||
assert_eq!(
|
||||
but_last_line(&template.to_string()),
|
||||
r#"(function() {
|
||||
var implementors = Object.fromEntries([]);
|
||||
const implementors = Object.fromEntries([]);
|
||||
if (window.register_implementors) {
|
||||
window.register_implementors(implementors);
|
||||
} else {
|
||||
|
|
@ -80,7 +80,7 @@ fn trait_alias_template() {
|
|||
assert_eq!(
|
||||
but_last_line(&template.to_string()),
|
||||
r#"(function() {
|
||||
var implementors = Object.fromEntries([["a"]]);
|
||||
const implementors = Object.fromEntries([["a"]]);
|
||||
if (window.register_implementors) {
|
||||
window.register_implementors(implementors);
|
||||
} else {
|
||||
|
|
@ -92,7 +92,7 @@ fn trait_alias_template() {
|
|||
assert_eq!(
|
||||
but_last_line(&template.to_string()),
|
||||
r#"(function() {
|
||||
var implementors = Object.fromEntries([["a"],["b"]]);
|
||||
const implementors = Object.fromEntries([["a"],["b"]]);
|
||||
if (window.register_implementors) {
|
||||
window.register_implementors(implementors);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ nav.sub {
|
|||
display: none;
|
||||
}
|
||||
|
||||
#synthetic-implementors-list:not(.loaded), #implementors-list:not(.loaded) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Begin: styles for themes
|
||||
Keep the default light and dark themes synchronized with the ones
|
||||
in rustdoc.css */
|
||||
|
|
|
|||
|
|
@ -1158,6 +1158,12 @@ div.where {
|
|||
margin-left: calc(var(--docblock-indent) + var(--impl-items-indent));
|
||||
}
|
||||
|
||||
#synthetic-implementors-list:not(.loaded), #implementors-list:not(.loaded) {
|
||||
/* To prevent layout shift when loading the page with extra implementors being loaded
|
||||
from JS, we hide the list until it's complete. */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-info code {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
|
@ -2976,6 +2982,9 @@ in src-script.js and main.js
|
|||
{
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
.negative-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.variants > .docblock,
|
||||
.implementors-toggle > .docblock,
|
||||
|
|
|
|||
|
|
@ -800,21 +800,34 @@ function preLoadCss(cssUrl) {
|
|||
|
||||
// <https://github.com/search?q=repo%3Arust-lang%2Frust+[RUSTDOCIMPL]+trait.impl&type=code>
|
||||
window.register_implementors = imp => {
|
||||
const implementors = document.getElementById("implementors-list");
|
||||
const synthetic_implementors = document.getElementById("synthetic-implementors-list");
|
||||
/** Takes an ID as input and returns a list of two elements. The first element is the DOM
|
||||
* element with the given ID and the second is the "negative marker", meaning the location
|
||||
* between the negative and non-negative impls.
|
||||
*
|
||||
* @param {string} id: ID of the DOM element.
|
||||
*
|
||||
* @return {[HTMLElement|null, HTMLElement|null]}
|
||||
*/
|
||||
function implementorsElems(id) {
|
||||
const elem = document.getElementById(id);
|
||||
return [elem, elem ? elem.querySelector(".negative-marker") : null];
|
||||
}
|
||||
const implementors = implementorsElems("implementors-list");
|
||||
const syntheticImplementors = implementorsElems("synthetic-implementors-list");
|
||||
const inlined_types = new Set();
|
||||
|
||||
const TEXT_IDX = 0;
|
||||
const SYNTHETIC_IDX = 1;
|
||||
const TYPES_IDX = 2;
|
||||
const IS_NEG_IDX = 1;
|
||||
const SYNTHETIC_IDX = 2;
|
||||
const TYPES_IDX = 3;
|
||||
|
||||
if (synthetic_implementors) {
|
||||
if (syntheticImplementors[0]) {
|
||||
// This `inlined_types` variable is used to avoid having the same implementation
|
||||
// showing up twice. For example "String" in the "Sync" doc page.
|
||||
//
|
||||
// By the way, this is only used by and useful for traits implemented automatically
|
||||
// (like "Send" and "Sync").
|
||||
onEachLazy(synthetic_implementors.getElementsByClassName("impl"), el => {
|
||||
onEachLazy(syntheticImplementors[0].getElementsByClassName("impl"), el => {
|
||||
const aliases = el.getAttribute("data-aliases");
|
||||
if (!aliases) {
|
||||
return;
|
||||
|
|
@ -827,7 +840,7 @@ function preLoadCss(cssUrl) {
|
|||
}
|
||||
|
||||
// @ts-expect-error
|
||||
let currentNbImpls = implementors.getElementsByClassName("impl").length;
|
||||
let currentNbImpls = implementors[0].getElementsByClassName("impl").length;
|
||||
// @ts-expect-error
|
||||
const traitName = document.querySelector(".main-heading h1 > .trait").textContent;
|
||||
const baseIdName = "impl-" + traitName + "-";
|
||||
|
|
@ -849,7 +862,7 @@ function preLoadCss(cssUrl) {
|
|||
|
||||
struct_loop:
|
||||
for (const struct of structs) {
|
||||
const list = struct[SYNTHETIC_IDX] ? synthetic_implementors : implementors;
|
||||
const list = struct[SYNTHETIC_IDX] ? syntheticImplementors : implementors;
|
||||
|
||||
// The types list is only used for synthetic impls.
|
||||
// If this changes, `main.js` and `write_shared.rs` both need changed.
|
||||
|
|
@ -884,11 +897,25 @@ function preLoadCss(cssUrl) {
|
|||
addClass(display, "impl");
|
||||
display.appendChild(anchor);
|
||||
display.appendChild(code);
|
||||
// @ts-expect-error
|
||||
list.appendChild(display);
|
||||
|
||||
// If this is a negative implementor, we put it into the right location (just
|
||||
// before the negative impl marker).
|
||||
if (struct[IS_NEG_IDX]) {
|
||||
// @ts-expect-error
|
||||
list[1].before(display);
|
||||
} else {
|
||||
// @ts-expect-error
|
||||
list[0].appendChild(display);
|
||||
}
|
||||
currentNbImpls += 1;
|
||||
}
|
||||
}
|
||||
if (implementors[0]) {
|
||||
implementors[0].classList.add("loaded");
|
||||
}
|
||||
if (syntheticImplementors[0]) {
|
||||
syntheticImplementors[0].classList.add("loaded");
|
||||
}
|
||||
};
|
||||
if (window.pending_implementors) {
|
||||
window.register_implementors(window.pending_implementors);
|
||||
|
|
|
|||
2
src/librustdoc/html/static/js/rustdoc.d.ts
vendored
2
src/librustdoc/html/static/js/rustdoc.d.ts
vendored
|
|
@ -520,7 +520,7 @@ declare namespace rustdoc {
|
|||
* Provided by generated `trait.impl` files.
|
||||
*/
|
||||
type Implementors = {
|
||||
[key: string]: Array<[string, number, Array<string>]>
|
||||
[key: string]: Array<[string, 0|1, number, Array<string>]>
|
||||
}
|
||||
|
||||
type TypeImpls = {
|
||||
|
|
|
|||
|
|
@ -544,6 +544,14 @@ fn opts() -> Vec<RustcOptGroup> {
|
|||
"[toolchain-shared-resources,invocation-specific,dep-info]",
|
||||
),
|
||||
opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
|
||||
opt(
|
||||
Unstable,
|
||||
Opt,
|
||||
"",
|
||||
"merge-doctests",
|
||||
"Force all doctests to be compiled as a single binary, instead of one binary per test. If merging fails, rustdoc will emit a hard error.",
|
||||
"yes|no|auto",
|
||||
),
|
||||
opt(
|
||||
Unstable,
|
||||
Multi,
|
||||
|
|
@ -822,7 +830,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
|
|||
options.should_test || output_format == config::OutputFormat::Doctest,
|
||||
config::markdown_input(&input),
|
||||
) {
|
||||
(true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)),
|
||||
(true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options, dcx)),
|
||||
(true, None) => return doctest::run(dcx, input, options),
|
||||
(false, Some(md_input)) => {
|
||||
let md_input = md_input.to_owned();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use camino::{Utf8Path, Utf8PathBuf};
|
|||
use semver::Version;
|
||||
|
||||
use crate::edition::Edition;
|
||||
use crate::executor::ColorConfig;
|
||||
use crate::fatal;
|
||||
use crate::util::{Utf8PathBufExt, add_dylib_path, string_enum};
|
||||
|
||||
|
|
@ -597,11 +596,6 @@ pub struct Config {
|
|||
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.
|
||||
pub verbose: bool,
|
||||
|
||||
/// Whether to use colors in test output.
|
||||
///
|
||||
/// Note: the exact control mechanism is delegated to [`colored`].
|
||||
pub color: ColorConfig,
|
||||
|
||||
/// Where to find the remote test client process, if we're using it.
|
||||
///
|
||||
/// Note: this is *only* used for target platform executables created by `run-make` test
|
||||
|
|
@ -623,9 +617,6 @@ pub struct Config {
|
|||
/// created in `$test_suite_build_root/rustfix_missing_coverage.txt`
|
||||
pub rustfix_coverage: bool,
|
||||
|
||||
/// Whether to run `tidy` (html-tidy) when a rustdoc test fails.
|
||||
pub has_html_tidy: bool,
|
||||
|
||||
/// Whether to run `enzyme` autodiff tests.
|
||||
pub has_enzyme: bool,
|
||||
|
||||
|
|
|
|||
|
|
@ -341,15 +341,6 @@ pub(crate) struct CollectedTestDesc {
|
|||
pub(crate) should_fail: ShouldFail,
|
||||
}
|
||||
|
||||
/// Whether console output should be colored or not.
|
||||
#[derive(Copy, Clone, Default, Debug)]
|
||||
pub enum ColorConfig {
|
||||
#[default]
|
||||
AutoColor,
|
||||
AlwaysColor,
|
||||
NeverColor,
|
||||
}
|
||||
|
||||
/// Tests with `//@ should-fail` are tests of compiletest itself, and should
|
||||
/// be reported as successful if and only if they would have _failed_.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ use core::panic;
|
|||
use std::collections::HashSet;
|
||||
use std::fmt::Write;
|
||||
use std::io::{self, ErrorKind};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::sync::{Arc, OnceLock};
|
||||
use std::time::SystemTime;
|
||||
use std::{env, fs, vec};
|
||||
|
|
@ -43,7 +42,7 @@ use crate::common::{
|
|||
};
|
||||
use crate::directives::{AuxProps, DirectivesCache, FileDirectives};
|
||||
use crate::edition::parse_edition;
|
||||
use crate::executor::{CollectedTest, ColorConfig};
|
||||
use crate::executor::CollectedTest;
|
||||
|
||||
/// Creates the `Config` instance for this invocation of compiletest.
|
||||
///
|
||||
|
|
@ -136,8 +135,9 @@ fn parse_config(args: Vec<String>) -> Config {
|
|||
"overwrite stderr/stdout files instead of complaining about a mismatch",
|
||||
)
|
||||
.optflag("", "fail-fast", "stop as soon as possible after any test fails")
|
||||
.optopt("", "color", "coloring: auto, always, never", "WHEN")
|
||||
.optopt("", "target", "the target to build for", "TARGET")
|
||||
// FIXME: Should be removed once `bootstrap` will be updated to not use this option.
|
||||
.optopt("", "color", "coloring: auto, always, never", "WHEN")
|
||||
.optopt("", "host", "the host to build for", "HOST")
|
||||
.optopt("", "cdb", "path to CDB to use for CDB debuginfo tests", "PATH")
|
||||
.optopt("", "gdb", "path to GDB to use for GDB debuginfo tests", "PATH")
|
||||
|
|
@ -274,12 +274,6 @@ fn parse_config(args: Vec<String>) -> Config {
|
|||
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
|
||||
let lldb_version =
|
||||
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
|
||||
let color = match matches.opt_str("color").as_deref() {
|
||||
Some("auto") | None => ColorConfig::AutoColor,
|
||||
Some("always") => ColorConfig::AlwaysColor,
|
||||
Some("never") => ColorConfig::NeverColor,
|
||||
Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x),
|
||||
};
|
||||
// FIXME: this is very questionable, we really should be obtaining LLVM version info from
|
||||
// `bootstrap`, and not trying to be figuring out that in `compiletest` by running the
|
||||
// `FileCheck` binary.
|
||||
|
|
@ -304,16 +298,6 @@ fn parse_config(args: Vec<String>) -> Config {
|
|||
let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions");
|
||||
let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions");
|
||||
let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode");
|
||||
let has_html_tidy = if mode == TestMode::Rustdoc {
|
||||
Command::new("tidy")
|
||||
.arg("--version")
|
||||
.stdout(Stdio::null())
|
||||
.status()
|
||||
.map_or(false, |status| status.success())
|
||||
} else {
|
||||
// Avoid spawning an external command when we know html-tidy won't be used.
|
||||
false
|
||||
};
|
||||
let has_enzyme = matches.opt_present("has-enzyme");
|
||||
let filters = if mode == TestMode::RunMake {
|
||||
matches
|
||||
|
|
@ -455,11 +439,9 @@ fn parse_config(args: Vec<String>) -> Config {
|
|||
adb_device_status,
|
||||
verbose: matches.opt_present("verbose"),
|
||||
only_modified: matches.opt_present("only-modified"),
|
||||
color,
|
||||
remote_test_client: matches.opt_str("remote-test-client").map(Utf8PathBuf::from),
|
||||
compare_mode,
|
||||
rustfix_coverage: matches.opt_present("rustfix-coverage"),
|
||||
has_html_tidy,
|
||||
has_enzyme,
|
||||
channel: matches.opt_str("channel").unwrap(),
|
||||
git_hash: matches.opt_present("git-hash"),
|
||||
|
|
@ -1144,10 +1126,6 @@ fn check_for_overlapping_test_paths(found_path_stems: &HashSet<Utf8PathBuf>) {
|
|||
}
|
||||
|
||||
fn early_config_check(config: &Config) {
|
||||
if !config.has_html_tidy && config.mode == TestMode::Rustdoc {
|
||||
warning!("`tidy` (html-tidy.org) is not installed; diffs will not be generated");
|
||||
}
|
||||
|
||||
if !config.profiler_runtime && config.mode == TestMode::CoverageRun {
|
||||
let actioned = if config.bless { "blessed" } else { "checked" };
|
||||
warning!("profiler runtime is not available, so `.coverage` files won't be {actioned}");
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ffi::OsString;
|
||||
use std::fs::{self, File, create_dir_all};
|
||||
use std::fs::{self, create_dir_all};
|
||||
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||
use std::io::prelude::*;
|
||||
use std::io::{self, BufReader};
|
||||
use std::process::{Child, Command, ExitStatus, Output, Stdio};
|
||||
use std::{env, fmt, iter, str};
|
||||
use std::{env, fmt, io, iter, str};
|
||||
|
||||
use build_helper::fs::remove_and_create_dir_all;
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
|
|
@ -23,9 +22,9 @@ use crate::directives::TestProps;
|
|||
use crate::errors::{Error, ErrorKind, load_errors};
|
||||
use crate::output_capture::ConsoleOut;
|
||||
use crate::read2::{Truncated, read2_abbreviated};
|
||||
use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff};
|
||||
use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff};
|
||||
use crate::util::{Utf8PathBufExt, add_dylib_path, static_regex};
|
||||
use crate::{ColorConfig, help, json, stamp_file_path, warning};
|
||||
use crate::{json, stamp_file_path};
|
||||
|
||||
// Helper modules that implement test running logic for each test suite.
|
||||
// tidy-alphabetical-start
|
||||
|
|
@ -2165,161 +2164,6 @@ impl<'test> TestCx<'test> {
|
|||
if cfg!(target_os = "freebsd") { "ISO-8859-1" } else { "UTF-8" }
|
||||
}
|
||||
|
||||
fn compare_to_default_rustdoc(&self, out_dir: &Utf8Path) {
|
||||
if !self.config.has_html_tidy {
|
||||
return;
|
||||
}
|
||||
writeln!(self.stdout, "info: generating a diff against nightly rustdoc");
|
||||
|
||||
let suffix =
|
||||
self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
|
||||
let compare_dir = output_base_dir(self.config, self.testpaths, Some(&suffix));
|
||||
remove_and_create_dir_all(&compare_dir).unwrap_or_else(|e| {
|
||||
panic!("failed to remove and recreate output directory `{compare_dir}`: {e}")
|
||||
});
|
||||
|
||||
// We need to create a new struct for the lifetimes on `config` to work.
|
||||
let new_rustdoc = TestCx {
|
||||
config: &Config {
|
||||
// FIXME: use beta or a user-specified rustdoc instead of
|
||||
// hardcoding the default toolchain
|
||||
rustdoc_path: Some("rustdoc".into()),
|
||||
// Needed for building auxiliary docs below
|
||||
rustc_path: "rustc".into(),
|
||||
..self.config.clone()
|
||||
},
|
||||
..*self
|
||||
};
|
||||
|
||||
let output_file = TargetLocation::ThisDirectory(new_rustdoc.aux_output_dir_name());
|
||||
let mut rustc = new_rustdoc.make_compile_args(
|
||||
&new_rustdoc.testpaths.file,
|
||||
output_file,
|
||||
Emit::None,
|
||||
AllowUnused::Yes,
|
||||
LinkToAux::Yes,
|
||||
Vec::new(),
|
||||
);
|
||||
let aux_dir = new_rustdoc.aux_output_dir();
|
||||
new_rustdoc.build_all_auxiliary(&aux_dir, &mut rustc);
|
||||
|
||||
let proc_res = new_rustdoc.document(&compare_dir, DocKind::Html);
|
||||
if !proc_res.status.success() {
|
||||
writeln!(self.stderr, "failed to run nightly rustdoc");
|
||||
return;
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
let tidy_args = [
|
||||
"--new-blocklevel-tags", "rustdoc-search,rustdoc-toolbar,rustdoc-topbar",
|
||||
"--indent", "yes",
|
||||
"--indent-spaces", "2",
|
||||
"--wrap", "0",
|
||||
"--show-warnings", "no",
|
||||
"--markup", "yes",
|
||||
"--quiet", "yes",
|
||||
"-modify",
|
||||
];
|
||||
let tidy_dir = |dir| {
|
||||
for entry in walkdir::WalkDir::new(dir) {
|
||||
let entry = entry.expect("failed to read file");
|
||||
if entry.file_type().is_file()
|
||||
&& entry.path().extension().and_then(|p| p.to_str()) == Some("html")
|
||||
{
|
||||
let status =
|
||||
Command::new("tidy").args(&tidy_args).arg(entry.path()).status().unwrap();
|
||||
// `tidy` returns 1 if it modified the file.
|
||||
assert!(status.success() || status.code() == Some(1));
|
||||
}
|
||||
}
|
||||
};
|
||||
tidy_dir(out_dir);
|
||||
tidy_dir(&compare_dir);
|
||||
|
||||
let pager = {
|
||||
let output = Command::new("git").args(&["config", "--get", "core.pager"]).output().ok();
|
||||
output.and_then(|out| {
|
||||
if out.status.success() {
|
||||
Some(String::from_utf8(out.stdout).expect("invalid UTF8 in git pager"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
let diff_filename = format!("build/tmp/rustdoc-compare-{}.diff", std::process::id());
|
||||
|
||||
if !write_filtered_diff(
|
||||
self,
|
||||
&diff_filename,
|
||||
out_dir,
|
||||
&compare_dir,
|
||||
self.config.verbose,
|
||||
|file_type, extension| {
|
||||
file_type.is_file() && (extension == Some("html") || extension == Some("js"))
|
||||
},
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
match self.config.color {
|
||||
ColorConfig::AlwaysColor => colored::control::set_override(true),
|
||||
ColorConfig::NeverColor => colored::control::set_override(false),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(pager) = pager {
|
||||
let pager = pager.trim();
|
||||
if self.config.verbose {
|
||||
writeln!(self.stderr, "using pager {}", pager);
|
||||
}
|
||||
let output = Command::new(pager)
|
||||
// disable paging; we want this to be non-interactive
|
||||
.env("PAGER", "")
|
||||
.stdin(File::open(&diff_filename).unwrap())
|
||||
// Capture output and print it explicitly so it will in turn be
|
||||
// captured by output-capture.
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(output.status.success());
|
||||
writeln!(self.stdout, "{}", String::from_utf8_lossy(&output.stdout));
|
||||
writeln!(self.stderr, "{}", String::from_utf8_lossy(&output.stderr));
|
||||
} else {
|
||||
warning!("no pager configured, falling back to unified diff");
|
||||
help!(
|
||||
"try configuring a git pager (e.g. `delta`) with \
|
||||
`git config --global core.pager delta`"
|
||||
);
|
||||
let mut out = io::stdout();
|
||||
let mut diff = BufReader::new(File::open(&diff_filename).unwrap());
|
||||
let mut line = Vec::new();
|
||||
loop {
|
||||
line.truncate(0);
|
||||
match diff.read_until(b'\n', &mut line) {
|
||||
Ok(0) => break,
|
||||
Ok(_) => {}
|
||||
Err(e) => writeln!(self.stderr, "ERROR: {:?}", e),
|
||||
}
|
||||
match String::from_utf8(line.clone()) {
|
||||
Ok(line) => {
|
||||
if line.starts_with('+') {
|
||||
write!(&mut out, "{}", line.green()).unwrap();
|
||||
} else if line.starts_with('-') {
|
||||
write!(&mut out, "{}", line.red()).unwrap();
|
||||
} else if line.starts_with('@') {
|
||||
write!(&mut out, "{}", line.blue()).unwrap();
|
||||
} else {
|
||||
out.write_all(line.as_bytes()).unwrap();
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
write!(&mut out, "{}", String::from_utf8_lossy(&line).reversed()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn get_lines(&self, path: &Utf8Path, mut other_files: Option<&mut Vec<String>>) -> Vec<usize> {
|
||||
let content = fs::read_to_string(path.as_std_path()).unwrap();
|
||||
let mut ignore = false;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,4 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::fs::{File, FileType};
|
||||
|
||||
use camino::Utf8Path;
|
||||
|
||||
use crate::runtest::TestCx;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DiffLine {
|
||||
|
|
@ -109,55 +104,3 @@ pub(crate) fn write_diff(expected: &str, actual: &str, context_size: usize) -> S
|
|||
}
|
||||
output
|
||||
}
|
||||
|
||||
/// Filters based on filetype and extension whether to diff a file.
|
||||
///
|
||||
/// Returns whether any data was actually written.
|
||||
pub(crate) fn write_filtered_diff<Filter>(
|
||||
cx: &TestCx<'_>,
|
||||
diff_filename: &str,
|
||||
out_dir: &Utf8Path,
|
||||
compare_dir: &Utf8Path,
|
||||
verbose: bool,
|
||||
filter: Filter,
|
||||
) -> bool
|
||||
where
|
||||
Filter: Fn(FileType, Option<&str>) -> bool,
|
||||
{
|
||||
use std::io::{Read, Write};
|
||||
let mut diff_output = File::create(diff_filename).unwrap();
|
||||
let mut wrote_data = false;
|
||||
for entry in walkdir::WalkDir::new(out_dir.as_std_path()) {
|
||||
let entry = entry.expect("failed to read file");
|
||||
let extension = entry.path().extension().and_then(|p| p.to_str());
|
||||
if filter(entry.file_type(), extension) {
|
||||
let expected_path = compare_dir
|
||||
.as_std_path()
|
||||
.join(entry.path().strip_prefix(&out_dir.as_std_path()).unwrap());
|
||||
let expected = if let Ok(s) = std::fs::read(&expected_path) { s } else { continue };
|
||||
let actual_path = entry.path();
|
||||
let actual = std::fs::read(&actual_path).unwrap();
|
||||
let diff = unified_diff::diff(
|
||||
&expected,
|
||||
&expected_path.to_str().unwrap(),
|
||||
&actual,
|
||||
&actual_path.to_str().unwrap(),
|
||||
3,
|
||||
);
|
||||
wrote_data |= !diff.is_empty();
|
||||
diff_output.write_all(&diff).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
if !wrote_data {
|
||||
writeln!(cx.stdout, "note: diff is identical to nightly rustdoc");
|
||||
assert!(diff_output.metadata().unwrap().len() == 0);
|
||||
return false;
|
||||
} else if verbose {
|
||||
writeln!(cx.stderr, "printing diff:");
|
||||
let mut buf = Vec::new();
|
||||
diff_output.read_to_end(&mut buf).unwrap();
|
||||
std::io::stderr().lock().write_all(&mut buf).unwrap();
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@ impl TestCx<'_> {
|
|||
}
|
||||
let res = self.run_command_to_procres(&mut cmd);
|
||||
if !res.status.success() {
|
||||
self.fatal_proc_rec_general("htmldocck failed!", None, &res, || {
|
||||
self.compare_to_default_rustdoc(&out_dir);
|
||||
});
|
||||
self.fatal_proc_rec("htmldocck failed!", &res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,11 +108,9 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
|
|||
adb_test_dir: Default::default(),
|
||||
adb_device_status: Default::default(),
|
||||
verbose: Default::default(),
|
||||
color: Default::default(),
|
||||
remote_test_client: Default::default(),
|
||||
compare_mode: Default::default(),
|
||||
rustfix_coverage: Default::default(),
|
||||
has_html_tidy: Default::default(),
|
||||
has_enzyme: Default::default(),
|
||||
channel: Default::default(),
|
||||
git_hash: Default::default(),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//@error-in-other-file: aborted execution
|
||||
// Backtraces vary wildly between platforms, we have to normalize away almost the entire thing
|
||||
//@normalize-stderr-test: "'main'|'<unnamed>'" -> "$$NAME"
|
||||
//@normalize-stderr-test: ".*(note|-->|\|).*\n" -> ""
|
||||
//@normalize-stderr-test: ".*(note|-->|:::|\|).*\n" -> ""
|
||||
|
||||
pub struct NoisyDrop {}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,20 +91,16 @@ fn extract_error_codes(root_path: &Path, check: &mut RunningCheck) -> Vec<String
|
|||
let line_index = line_index + 1;
|
||||
let line = line.trim();
|
||||
|
||||
if line.starts_with('E') {
|
||||
let split_line = line.split_once(':');
|
||||
|
||||
// Extract the error code from the line. Emit a fatal error if it is not in the correct
|
||||
// format.
|
||||
let Some(split_line) = split_line else {
|
||||
if line.starts_with(|c: char| c.is_ascii_digit()) {
|
||||
let mut chars = line.chars();
|
||||
let err_code = chars.by_ref().take(4).collect::<String>();
|
||||
if chars.next() != Some(',') {
|
||||
check.error(format!(
|
||||
"{path}:{line_index}: Expected a line with the format `Eabcd: abcd, \
|
||||
but got \"{line}\" without a `:` delimiter",
|
||||
"{path}:{line_index}: Expected a line with the format `abcd,` \
|
||||
but got \"{line}\" without a `,` delimiter",
|
||||
));
|
||||
continue;
|
||||
};
|
||||
|
||||
let err_code = split_line.0.to_owned();
|
||||
}
|
||||
|
||||
// If this is a duplicate of another error code, emit a fatal error.
|
||||
if error_codes.contains(&err_code) {
|
||||
|
|
@ -114,35 +110,13 @@ fn extract_error_codes(root_path: &Path, check: &mut RunningCheck) -> Vec<String
|
|||
continue;
|
||||
}
|
||||
|
||||
let mut chars = err_code.chars();
|
||||
assert_eq!(chars.next(), Some('E'));
|
||||
let error_num_as_str = chars.as_str();
|
||||
|
||||
// Ensure that the line references the correct markdown file.
|
||||
let rest = split_line.1.split_once(',');
|
||||
let Some(rest) = rest else {
|
||||
check.error(format!(
|
||||
"{path}:{line_index}: Expected a line with the format `Eabcd: abcd, \
|
||||
but got \"{line}\" without a `,` delimiter",
|
||||
));
|
||||
continue;
|
||||
};
|
||||
if error_num_as_str != rest.0.trim() {
|
||||
check.error(format!(
|
||||
"{path}:{line_index}: `{}:` should be followed by `{},` but instead found `{}` in \
|
||||
`compiler/rustc_error_codes/src/lib.rs`",
|
||||
err_code,
|
||||
error_num_as_str,
|
||||
split_line.1,
|
||||
));
|
||||
continue;
|
||||
}
|
||||
if !rest.1.trim().is_empty() && !rest.1.trim().starts_with("//") {
|
||||
let rest = chars.as_str().trim();
|
||||
if !rest.is_empty() && !rest.starts_with("//") {
|
||||
check.error(format!("{path}:{line_index}: should only have one error per line"));
|
||||
continue;
|
||||
}
|
||||
|
||||
error_codes.push(err_code);
|
||||
error_codes.push(format!("E{err_code}"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1583,7 +1583,6 @@ ui/macros/issue-6596-1.rs
|
|||
ui/macros/issue-6596-2.rs
|
||||
ui/macros/issue-68058.rs
|
||||
ui/macros/issue-68060.rs
|
||||
ui/macros/issue-69396-const-no-type-in-macro.rs
|
||||
ui/macros/issue-69838-mods-relative-to-included-path.rs
|
||||
ui/macros/issue-70446.rs
|
||||
ui/macros/issue-75982-foreign-macro-weird-mod.rs
|
||||
|
|
@ -2100,7 +2099,6 @@ ui/parser/issues/issue-88770.rs
|
|||
ui/parser/issues/issue-88818.rs
|
||||
ui/parser/issues/issue-89388.rs
|
||||
ui/parser/issues/issue-89396.rs
|
||||
ui/parser/issues/issue-89574.rs
|
||||
ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs
|
||||
ui/parser/issues/issue-90728.rs
|
||||
ui/parser/issues/issue-90993.rs
|
||||
|
|
@ -2880,7 +2878,6 @@ ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs
|
|||
ui/typeck/auxiliary/issue-29181.rs
|
||||
ui/typeck/auxiliary/issue-36708.rs
|
||||
ui/typeck/auxiliary/issue-81943-lib.rs
|
||||
ui/typeck/issue-100164.rs
|
||||
ui/typeck/issue-100246.rs
|
||||
ui/typeck/issue-100285.rs
|
||||
ui/typeck/issue-103899.rs
|
||||
|
|
@ -2937,7 +2934,6 @@ ui/typeck/issue-74933.rs
|
|||
ui/typeck/issue-75883.rs
|
||||
ui/typeck/issue-75889.rs
|
||||
ui/typeck/issue-7813.rs
|
||||
ui/typeck/issue-79040.rs
|
||||
ui/typeck/issue-80207-unsized-return.rs
|
||||
ui/typeck/issue-80779.rs
|
||||
ui/typeck/issue-81293.rs
|
||||
|
|
|
|||
|
|
@ -154,6 +154,10 @@ Options:
|
|||
Comma separated list of types of output for rustdoc to
|
||||
emit
|
||||
--no-run Compile doctests without running them
|
||||
--merge-doctests yes|no|auto
|
||||
Force all doctests to be compiled as a single binary,
|
||||
instead of one binary per test. If merging fails,
|
||||
rustdoc will emit a hard error.
|
||||
--remap-path-prefix FROM=TO
|
||||
Remap source names in compiler messages
|
||||
--show-type-layout
|
||||
|
|
|
|||
|
|
@ -1,19 +1,46 @@
|
|||
// The goal of this test is to check that the external trait implementors, generated with JS,
|
||||
// have the same display than the "local" ones.
|
||||
go-to: "file://" + |DOC_PATH| + "/implementors/trait.Whatever.html"
|
||||
assert: "#implementors-list"
|
||||
// There are supposed to be two implementors listed.
|
||||
assert-count: ("#implementors-list .impl", 2)
|
||||
wait-for-css: ("#implementors-list", {"display": "block"})
|
||||
// There are supposed to be four implementors listed.
|
||||
assert-count: ("#implementors-list .impl", 4)
|
||||
// There are supposed to be two non-negative implementors.
|
||||
assert-count: ("#implementors-list .negative-marker ~ *", 2)
|
||||
// Now we check that both implementors have an anchor, an ID and a similar DOM.
|
||||
assert: ("#implementors-list .impl:nth-child(1) > a.anchor")
|
||||
assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever-for-Struct"})
|
||||
assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever-for-Struct"})
|
||||
assert: "#implementors-list .impl:nth-child(1) > .code-header"
|
||||
define-function: (
|
||||
"check-dom",
|
||||
[id],
|
||||
block {
|
||||
assert-attribute: (|id| + " > a.anchor", {"href": |id|})
|
||||
assert: |id| + " > .code-header"
|
||||
},
|
||||
)
|
||||
|
||||
assert: ("#implementors-list .impl:nth-child(2) > a.anchor")
|
||||
assert-attribute: ("#implementors-list .impl:nth-child(2)", {"id": "impl-Whatever-1"})
|
||||
assert-attribute: ("#implementors-list .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"})
|
||||
assert: "#implementors-list .impl:nth-child(2) > .code-header"
|
||||
call-function: ("check-dom", {"id": "#impl-Whatever-for-Struct2"})
|
||||
call-function: ("check-dom", {"id": "#impl-Whatever-2"})
|
||||
call-function: ("check-dom", {"id": "#impl-Whatever-for-Struct"})
|
||||
call-function: ("check-dom", {"id": "#impl-Whatever-3"})
|
||||
|
||||
// Ensure that negative impl are sorted first.
|
||||
assert-property: (
|
||||
"#implementors-list > *:nth-child(1) > h3",
|
||||
{"textContent": "impl !Whatever for Struct2"},
|
||||
)
|
||||
assert-property: (
|
||||
"#implementors-list > *:nth-child(2) > h3",
|
||||
{"textContent": "impl !Whatever for StructToImplOnReexport"},
|
||||
)
|
||||
// Third one is the negative marker.
|
||||
assert-attribute: ("#implementors-list > *:nth-child(3)", {"class": "negative-marker"})
|
||||
// This one is a `<detail>` so the selector is a bit different.
|
||||
assert-property: (
|
||||
"#implementors-list > *:nth-child(4) section > h3",
|
||||
{"textContent": "impl Whatever for Struct"},
|
||||
)
|
||||
assert-property: (
|
||||
"#implementors-list > *:nth-child(5) > h3",
|
||||
{"textContent": "impl Whatever for Foo"},
|
||||
)
|
||||
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HasEmptyTraits.html"
|
||||
compare-elements-position-near-false: (
|
||||
|
|
@ -39,3 +66,8 @@ assert-count: ("#implementors-list .impl", 1)
|
|||
go-to: "file://" + |DOC_PATH| + "/http/trait.HttpTrait.html"
|
||||
assert-count: ("#implementors-list .impl", 1)
|
||||
assert-attribute: ("#implementors-list .impl a.trait", {"href": "../http/trait.HttpTrait.html"})
|
||||
|
||||
// Now we check that if JS is disabled, the implementors list will be visible.
|
||||
javascript: false
|
||||
reload:
|
||||
assert-css: ("#implementors-list", {"display": "block"})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#![feature(negative_impls)]
|
||||
|
||||
pub trait Whatever {
|
||||
type Foo;
|
||||
|
||||
|
|
@ -5,11 +7,14 @@ pub trait Whatever {
|
|||
}
|
||||
|
||||
pub struct Struct;
|
||||
pub struct Struct2;
|
||||
|
||||
impl Whatever for Struct {
|
||||
type Foo = u8;
|
||||
}
|
||||
|
||||
impl !Whatever for Struct2 {}
|
||||
|
||||
impl http::HttpTrait for Struct {}
|
||||
|
||||
mod traits {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// ignore-tidy-linelength
|
||||
|
||||
#![feature(doc_cfg)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
pub mod another_folder;
|
||||
pub mod another_mod;
|
||||
|
|
@ -60,6 +61,8 @@ impl implementors::Whatever for Foo {
|
|||
type Foo = u32;
|
||||
}
|
||||
|
||||
impl !implementors::Whatever for StructToImplOnReexport {}
|
||||
|
||||
#[doc(inline)]
|
||||
pub use implementors::TraitToReexport;
|
||||
|
||||
|
|
|
|||
25
tests/rustdoc-ui/doctest/force-merge-default-not-override.rs
Normal file
25
tests/rustdoc-ui/doctest/force-merge-default-not-override.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//@ check-pass
|
||||
//@ edition: 2024
|
||||
//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options
|
||||
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
|
||||
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME"
|
||||
//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME"
|
||||
//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
|
||||
|
||||
// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't
|
||||
// emitted as JSON. Instead the .stderr file tests that this doesn't contains a
|
||||
// "merged compilation took ..." message.
|
||||
|
||||
/// ```standalone_crate
|
||||
/// let x = 12;
|
||||
/// ```
|
||||
///
|
||||
/// These two doctests should be not be merged, even though this passes `--merge-doctests=yes`.
|
||||
///
|
||||
/// ```standalone_crate
|
||||
/// fn main() {
|
||||
/// println!("owo");
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Foo;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
running 2 tests
|
||||
test $DIR/force-merge-default-not-override.rs - Foo (line 14) ... ok
|
||||
test $DIR/force-merge-default-not-override.rs - Foo (line 20) ... ok
|
||||
|
||||
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
|
||||
|
||||
18
tests/rustdoc-ui/doctest/force-merge-fail.rs
Normal file
18
tests/rustdoc-ui/doctest/force-merge-fail.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//@ edition: 2018
|
||||
//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options
|
||||
//@ normalize-stderr: ".*doctest_bundle_2018.rs:\d+:\d+" -> "doctest_bundle_2018.rs:$$LINE:$$COL"
|
||||
|
||||
//~? ERROR failed to merge doctests
|
||||
|
||||
/// These two doctests will fail to force-merge, and should give a hard error as a result.
|
||||
///
|
||||
/// ```
|
||||
/// #![deny(clashing_extern_declarations)]
|
||||
/// unsafe extern "C" { fn unmangled_name() -> u8; }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![deny(clashing_extern_declarations)]
|
||||
/// unsafe extern "C" { fn unmangled_name(); }
|
||||
/// ```
|
||||
pub struct Foo;
|
||||
6
tests/rustdoc-ui/doctest/force-merge-fail.stderr
Normal file
6
tests/rustdoc-ui/doctest/force-merge-fail.stderr
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
doctest_bundle_2018.rs:$LINE:$COL: error: `unmangled_name` redeclared with a different signature: this signature doesn't match the previous declaration
|
||||
error: aborting due to 1 previous error
|
||||
error: failed to merge doctests
|
||||
|
|
||||
= note: requested explicitly on the command line with `--merge-doctests=yes`
|
||||
|
||||
25
tests/rustdoc-ui/doctest/force-merge.rs
Normal file
25
tests/rustdoc-ui/doctest/force-merge.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//@ check-pass
|
||||
//@ edition: 2018
|
||||
//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options
|
||||
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
|
||||
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME"
|
||||
//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME"
|
||||
//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
|
||||
|
||||
// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't
|
||||
// emitted as JSON. Instead the .stderr file tests that this contains a
|
||||
// "merged compilation took ..." message.
|
||||
|
||||
/// ```
|
||||
/// let x = 12;
|
||||
/// ```
|
||||
///
|
||||
/// These two doctests should be force-merged, even though this uses edition 2018.
|
||||
///
|
||||
/// ```
|
||||
/// fn main() {
|
||||
/// println!("owo");
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Foo;
|
||||
8
tests/rustdoc-ui/doctest/force-merge.stdout
Normal file
8
tests/rustdoc-ui/doctest/force-merge.stdout
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
running 2 tests
|
||||
test $DIR/force-merge.rs - Foo (line 14) ... ok
|
||||
test $DIR/force-merge.rs - Foo (line 20) ... ok
|
||||
|
||||
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
|
||||
|
||||
all doctests ran in $TIME; merged doctests compilation took $TIME
|
||||
24
tests/rustdoc-ui/doctest/force-no-merge.rs
Normal file
24
tests/rustdoc-ui/doctest/force-no-merge.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//@ edition: 2024
|
||||
//@ check-pass
|
||||
//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=no -Z unstable-options
|
||||
//@ normalize-stderr: ".*doctest_bundle_2018.rs:\d+:\d+" -> "doctest_bundle_2018.rs:$$LINE:$$COL"
|
||||
|
||||
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
|
||||
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME"
|
||||
//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME"
|
||||
//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
|
||||
|
||||
/// These two doctests should not force-merge, even though this crate has edition 2024 and the
|
||||
/// individual doctests are not annotated.
|
||||
///
|
||||
/// ```
|
||||
/// #![deny(clashing_extern_declarations)]
|
||||
/// unsafe extern "C" { fn unmangled_name() -> u8; }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![deny(clashing_extern_declarations)]
|
||||
/// unsafe extern "C" { fn unmangled_name(); }
|
||||
/// ```
|
||||
pub struct Foo;
|
||||
7
tests/rustdoc-ui/doctest/force-no-merge.stdout
Normal file
7
tests/rustdoc-ui/doctest/force-no-merge.stdout
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
running 2 tests
|
||||
test $DIR/force-no-merge.rs - Foo (line 15) ... ok
|
||||
test $DIR/force-no-merge.rs - Foo (line 20) ... ok
|
||||
|
||||
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
|
||||
|
||||
28
tests/rustdoc-ui/doctest/merge-doctests-auto.rs
Normal file
28
tests/rustdoc-ui/doctest/merge-doctests-auto.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//! `--merge-doctests=auto` should override the edition.
|
||||
|
||||
//@ check-pass
|
||||
//@ edition: 2018
|
||||
//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=auto -Z unstable-options
|
||||
|
||||
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
|
||||
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME"
|
||||
//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME"
|
||||
//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
|
||||
|
||||
// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't
|
||||
// emitted as JSON. Instead the .stderr file tests that this contains a
|
||||
// "merged compilation took ..." message.
|
||||
|
||||
/// ```
|
||||
/// let x = 12;
|
||||
/// ```
|
||||
///
|
||||
/// These two doctests should be auto-merged, even though this uses edition 2018.
|
||||
///
|
||||
/// ```
|
||||
/// fn main() {
|
||||
/// println!("owo");
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Foo;
|
||||
8
tests/rustdoc-ui/doctest/merge-doctests-auto.stdout
Normal file
8
tests/rustdoc-ui/doctest/merge-doctests-auto.stdout
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
running 2 tests
|
||||
test $DIR/merge-doctests-auto.rs - Foo (line 17) ... ok
|
||||
test $DIR/merge-doctests-auto.rs - Foo (line 23) ... ok
|
||||
|
||||
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
|
||||
|
||||
all doctests ran in $TIME; merged doctests compilation took $TIME
|
||||
2
tests/rustdoc-ui/doctest/merge-doctests-invalid.rs
Normal file
2
tests/rustdoc-ui/doctest/merge-doctests-invalid.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
//@ compile-flags: --merge-doctests=bad-opt -Zunstable-options
|
||||
//~? ERROR must be a boolean
|
||||
2
tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr
Normal file
2
tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
error: argument to --merge-doctests must be a boolean (true/false) or 'auto'
|
||||
|
||||
2
tests/rustdoc-ui/doctest/merge-doctests-unstable.rs
Normal file
2
tests/rustdoc-ui/doctest/merge-doctests-unstable.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
//@ compile-flags: --merge-doctests=no
|
||||
//~? RAW `-Z unstable-options` flag must also be passed
|
||||
2
tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr
Normal file
2
tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
error: the `-Z unstable-options` flag must also be passed to enable the flag `merge-doctests`
|
||||
|
||||
|
|
@ -18,6 +18,9 @@ help: the following other types implement trait `VisitorResult`
|
|||
= note: `ControlFlow<T>`
|
||||
note: required by a bound in `rustc_ast::visit::Visitor::Result`
|
||||
--> /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL
|
||||
::: /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
= note: this error originates in the macro `common_visitor_and_walkers` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -20,8 +20,11 @@ LL | impl<T> VisitorResult for ControlFlow<T> {
|
|||
note: required by a bound in `rustc_ast::visit::Visitor::Result`
|
||||
--> $COMPILER_DIR_REAL/rustc_ast/src/visit.rs:LL:COL
|
||||
|
|
||||
LL | type Result: VisitorResult = ();
|
||||
| ^^^^^^^^^^^^^ required by this bound in `Visitor::Result`
|
||||
...
|
||||
LL | common_visitor_and_walkers!(Visitor<'a>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Visitor::Result`
|
||||
| ---------------------------------------- in this macro invocation
|
||||
= note: this error originates in the macro `common_visitor_and_walkers` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ LL | struct NotIntoDiagArg;
|
|||
= help: normalized in stderr
|
||||
note: required by a bound in `Diag::<'a, G>::arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
|
|
||||
= note: in this macro invocation
|
||||
= note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied
|
||||
|
|
@ -34,6 +37,9 @@ LL | struct NotIntoDiagArg;
|
|||
= help: normalized in stderr
|
||||
note: required by a bound in `Diag::<'a, G>::arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
|
|
||||
= note: in this macro invocation
|
||||
= note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
|
|||
|
|
@ -665,6 +665,9 @@ LL | struct Hello {}
|
|||
= help: normalized in stderr
|
||||
note: required by a bound in `Diag::<'a, G>::arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
|
|
||||
= note: in this macro invocation
|
||||
= note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 85 previous errors
|
||||
|
|
|
|||
|
|
@ -305,13 +305,19 @@ LL | let _ = FOO & (*"Sized".to_string().into_boxed_str());
|
|||
help: the following other types implement trait `BitAnd<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
|
||||
|
|
||||
= note: `&i32` implements `BitAnd<i32>`
|
||||
= note: `i32` implements `BitAnd`
|
||||
::: $SRC_DIR/core/src/ops/bit.rs:LL:COL
|
||||
|
|
||||
= note: `&i32` implements `BitAnd`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&i32` implements `BitAnd<i32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `BitAnd<&i32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `BitAnd`
|
||||
= note: `&i32` implements `BitAnd`
|
||||
= note: this error originates in the macro `bitand_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
|
|
|
|||
|
|
@ -8,13 +8,19 @@ LL | x * y
|
|||
help: the following other types implement trait `Mul<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&i32` implements `Mul<i32>`
|
||||
= note: `i32` implements `Mul`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&i32` implements `Mul`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&i32` implements `Mul<i32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Mul<&i32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Mul`
|
||||
= note: `&i32` implements `Mul`
|
||||
= note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -84,6 +84,9 @@ LL | check(&mut () as *mut ());
|
|||
|
|
||||
help: the trait `ConstParamTy_` is implemented for `()`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_bad.rs:4:18
|
||||
|
|
||||
|
|
@ -101,6 +104,9 @@ LL | check(&() as *const ());
|
|||
|
|
||||
help: the trait `ConstParamTy_` is implemented for `()`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: required by a bound in `check`
|
||||
--> $DIR/const_param_ty_bad.rs:4:18
|
||||
|
|
||||
|
|
|
|||
|
|
@ -14,13 +14,19 @@ LL | = [0; (i8::MAX + 1u8) as usize];
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&i8` implements `Add<i8>`
|
||||
= note: `i8` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&i8` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&i8` implements `Add<i8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `i8` implements `Add<&i8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `i8` implements `Add`
|
||||
= note: `&i8` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
|
|||
|
|
@ -14,13 +14,19 @@ LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&i8` implements `Add<i8>`
|
||||
= note: `i8` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&i8` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&i8` implements `Add<i8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `i8` implements `Add<&i8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `i8` implements `Add`
|
||||
= note: `&i8` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0604]: only `u8` can be cast as `char`, not `i8`
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@ LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize);
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `post_monomorphization_error::ValidateConstImm::<2, 0, 1>::VALID` failed here
|
||||
|
||||
note: erroneous constant encountered
|
||||
--> $DIR/auxiliary/post_monomorphization_error.rs:19:5
|
||||
--> $DIR/auxiliary/post_monomorphization_error.rs:13:17
|
||||
|
|
||||
LL | let _ = $crate::ValidateConstImm::<$imm, 0, { (1 << 1) - 1 }>::VALID;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | static_assert_imm1!(IMM1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ------------------------- in this macro invocation
|
||||
|
|
||||
= note: this note originates in the macro `static_assert_imm1` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,14 @@ LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); };
|
|||
|
|
||||
note: inside `core::num::<impl u64>::from_str_radix`
|
||||
--> $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: inside `core::num::<impl u64>::from_ascii_radix`
|
||||
--> $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
= note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0080]: evaluation panicked: from_ascii_radix: radix must lie in the range `[2, 36]`
|
||||
|
|
@ -18,8 +24,14 @@ LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); };
|
|||
|
|
||||
note: inside `core::num::<impl u64>::from_str_radix`
|
||||
--> $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: inside `core::num::<impl u64>::from_ascii_radix`
|
||||
--> $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
= note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0369]: cannot add `{integer}` to `&str`
|
||||
--> $DIR/issue-79040.rs:2:25
|
||||
--> $DIR/dont-suggest-type-error.rs:2:25
|
||||
|
|
||||
LL | const FOO = "hello" + 1;
|
||||
| ------- ^ - {integer}
|
||||
|
|
@ -7,7 +7,7 @@ LL | const FOO = "hello" + 1;
|
|||
| &str
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-79040.rs:2:14
|
||||
--> $DIR/dont-suggest-type-error.rs:2:14
|
||||
|
|
||||
LL | const FOO = "hello" + 1;
|
||||
| ^
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-89574.rs:2:25
|
||||
--> $DIR/empty-array.rs:2:25
|
||||
|
|
||||
LL | const EMPTY_ARRAY = [];
|
||||
| ^^ cannot infer type
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-89574.rs:2:22
|
||||
--> $DIR/empty-array.rs:2:22
|
||||
|
|
||||
LL | const EMPTY_ARRAY = [];
|
||||
| ^
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0428]: the name `A` is defined multiple times
|
||||
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:13
|
||||
--> $DIR/in-macro.rs:4:13
|
||||
|
|
||||
LL | const A = "A".$fn();
|
||||
| ^^^^^^^^^^^^^^^^^^^^ `A` redefined here
|
||||
|
|
@ -14,7 +14,7 @@ LL | | }
|
|||
= note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:20
|
||||
--> $DIR/in-macro.rs:4:20
|
||||
|
|
||||
LL | const A = "A".$fn();
|
||||
| ^ help: provide a type for the constant: `: usize`
|
||||
|
|
@ -28,7 +28,7 @@ LL | | }
|
|||
= note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0121]: missing type for item
|
||||
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:20
|
||||
--> $DIR/in-macro.rs:4:20
|
||||
|
|
||||
LL | const A = "A".$fn();
|
||||
| ^ not allowed in type signatures
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
error: missing type for `const` item
|
||||
--> $DIR/issue-100164.rs:3:10
|
||||
--> $DIR/with-colon.rs:3:10
|
||||
|
|
||||
LL | const _A: = 123;
|
||||
| ^ help: provide a type for the constant: `i32`
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/issue-100164.rs:7:14
|
||||
--> $DIR/with-colon.rs:7:14
|
||||
|
|
||||
LL | const _B: = 123;
|
||||
| ^ help: provide a type for the constant: `i32`
|
||||
|
|
@ -5,9 +5,16 @@ LL | assert!(!ptr.wrapping_sub(512).is_null());
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MAYBE_NULL` failed inside this call
|
||||
|
|
||||
note: inside `std::ptr::const_ptr::<impl *const i32>::is_null`
|
||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: inside `std::ptr::const_ptr::<impl *const T>::is_null::compiletime`
|
||||
--> $SRC_DIR/core/src/panic.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ LL | assert!(a == b);
|
|||
| ^^^^^^ evaluation of `_` failed inside this call
|
||||
|
|
||||
note: inside `<TypeId as PartialEq>::eq`
|
||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/any.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: inside `<TypeId as PartialEq>::eq::compiletime`
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ LL | assert!(a == b);
|
|||
| ^^^^^^ evaluation of `_` failed inside this call
|
||||
|
|
||||
note: inside `<TypeId as PartialEq>::eq`
|
||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/any.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: inside `<TypeId as PartialEq>::eq::compiletime`
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ LL | assert!(a == b);
|
|||
| ^^^^^^ evaluation of `_` failed inside this call
|
||||
|
|
||||
note: inside `<TypeId as PartialEq>::eq`
|
||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/any.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: inside `<TypeId as PartialEq>::eq::compiletime`
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ LL | assert!(b == b);
|
|||
| ^^^^^^ evaluation of `_` failed inside this call
|
||||
|
|
||||
note: inside `<TypeId as PartialEq>::eq`
|
||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/any.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: inside `<TypeId as PartialEq>::eq::compiletime`
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ LL | id == id
|
|||
| ^^^^^^^^ evaluation of `X` failed inside this call
|
||||
|
|
||||
note: inside `<TypeId as PartialEq>::eq`
|
||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/any.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: inside `<TypeId as PartialEq>::eq::compiletime`
|
||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||
= note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
error: constant evaluation is taking a long time
|
||||
--> $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
|
||||
|
|
||||
--> $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
::: $SRC_DIR/core/src/num/mod.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
|
|
||||
= note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
|
||||
If your compilation actually takes a long time, you can safely allow the lint.
|
||||
|
|
|
|||
10
tests/ui/entry-point/imported_main_conflict_lib.rs
Normal file
10
tests/ui/entry-point/imported_main_conflict_lib.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Tests that ambiguously glob importing main doesn't fail to compile in non-executable crates
|
||||
// Regression test for #149412
|
||||
//@ check-pass
|
||||
#![crate_type = "lib"]
|
||||
|
||||
mod m1 { pub(crate) fn main() {} }
|
||||
mod m2 { pub(crate) fn main() {} }
|
||||
|
||||
use m1::*;
|
||||
use m2::*;
|
||||
|
|
@ -12,16 +12,6 @@ LL | | drop((x.0, x.1, x.2));
|
|||
| | --- use occurs due to use in closure
|
||||
LL | | });
|
||||
| |_________- value moved here, in previous iteration of loop
|
||||
|
|
||||
help: consider moving the expression out of the loop so it is only moved once
|
||||
|
|
||||
LL ~ let mut value = std::thread::spawn(use || {
|
||||
LL +
|
||||
LL + drop((x.0, x.1, x.2));
|
||||
LL + });
|
||||
LL ~ for _ in 0..10 {
|
||||
LL ~ let handler = value;
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope
|
|||
LL | let x = MyStruct {};
|
||||
| ^^^^^^^^ not found in this scope
|
||||
|
|
||||
::: $DIR/auxiliary/use_by_macro.rs:15:1
|
||||
::: $DIR/auxiliary/use_by_macro.rs:7:24
|
||||
|
|
||||
LL | x!(my_struct);
|
||||
| ------------- you might have meant to refer to this struct
|
||||
LL | pub struct MyStruct;
|
||||
| -------- you might have meant to refer to this struct
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -33,13 +33,19 @@ LL | n + sum_to(n - 1)
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&u32` implements `Add<u32>`
|
||||
= note: `u32` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&u32` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&u32` implements `Add<u32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `u32` implements `Add<&u32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `u32` implements `Add`
|
||||
= note: `&u32` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
|
|
|||
|
|
@ -8,10 +8,13 @@ LL | glob_vs_expanded::mac!();
|
|||
= note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
|
||||
= note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution
|
||||
note: `mac` could refer to the macro defined here
|
||||
--> $DIR/auxiliary/glob-vs-expanded.rs:11:1
|
||||
--> $DIR/auxiliary/glob-vs-expanded.rs:9:13
|
||||
|
|
||||
LL | () => { pub macro mac() {} }
|
||||
| ^^^^^^^^^^^^^
|
||||
LL | }
|
||||
LL | define_mac!();
|
||||
| ^^^^^^^^^^^^^
|
||||
| ------------- in this macro invocation
|
||||
note: `mac` could also refer to the macro defined here
|
||||
--> $DIR/auxiliary/glob-vs-expanded.rs:5:9
|
||||
|
|
||||
|
|
@ -33,10 +36,13 @@ LL | glob_vs_expanded::mac!();
|
|||
= note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
|
||||
= note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution
|
||||
note: `mac` could refer to the macro defined here
|
||||
--> $DIR/auxiliary/glob-vs-expanded.rs:11:1
|
||||
--> $DIR/auxiliary/glob-vs-expanded.rs:9:13
|
||||
|
|
||||
LL | () => { pub macro mac() {} }
|
||||
| ^^^^^^^^^^^^^
|
||||
LL | }
|
||||
LL | define_mac!();
|
||||
| ^^^^^^^^^^^^^
|
||||
| ------------- in this macro invocation
|
||||
note: `mac` could also refer to the macro defined here
|
||||
--> $DIR/auxiliary/glob-vs-expanded.rs:5:9
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
error: recursion limit reached while expanding `$crate::format_args!`
|
||||
--> $DIR/issue-41731-infinite-macro-print.rs:14:5
|
||||
--> $DIR/issue-41731-infinite-macro-print.rs:8:13
|
||||
|
|
||||
LL | print!(stack!($overflow))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | stack!("overflow");
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`issue_41731_infinite_macro_print`)
|
||||
= note: this error originates in the macro `print` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
@ -23,10 +26,13 @@ LL | stack!("overflow");
|
|||
= note: to `{ $crate :: io :: _print($crate :: format_args! (stack! ("overflow"))); }`
|
||||
|
||||
error: format argument must be a string literal
|
||||
--> $DIR/issue-41731-infinite-macro-print.rs:14:5
|
||||
--> $DIR/issue-41731-infinite-macro-print.rs:8:13
|
||||
|
|
||||
LL | print!(stack!($overflow))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | stack!("overflow");
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `print` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: you might be missing a string literal to format with
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
error: recursion limit reached while expanding `$crate::format_args_nl!`
|
||||
--> $DIR/issue-41731-infinite-macro-println.rs:14:5
|
||||
--> $DIR/issue-41731-infinite-macro-println.rs:8:13
|
||||
|
|
||||
LL | println!(stack!($overflow))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | stack!("overflow");
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`issue_41731_infinite_macro_println`)
|
||||
= note: this error originates in the macro `println` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
@ -23,10 +26,13 @@ LL | stack!("overflow");
|
|||
= note: to `{ $crate :: io :: _print($crate :: format_args_nl! (stack! ("overflow"))); }`
|
||||
|
||||
error: format argument must be a string literal
|
||||
--> $DIR/issue-41731-infinite-macro-println.rs:14:5
|
||||
--> $DIR/issue-41731-infinite-macro-println.rs:8:13
|
||||
|
|
||||
LL | println!(stack!($overflow))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | stack!("overflow");
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| ------------------ in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `println` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: you might be missing a string literal to format with
|
||||
|
|
|
|||
|
|
@ -35,10 +35,14 @@ LL | println!("{}", scores.sum::<i32>());
|
|||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain-fixable.rs:14:10
|
||||
|
|
||||
|
|
@ -72,10 +76,14 @@ LL | .sum::<i32>(),
|
|||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain-fixable.rs:23:14
|
||||
|
|
||||
|
|
@ -109,10 +117,14 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
|
|||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain-fixable.rs:27:38
|
||||
|
|
||||
|
|
|
|||
|
|
@ -9,10 +9,14 @@ LL | let x = Some(()).iter().map(|()| 1).sum::<f32>();
|
|||
= help: the trait `Sum<{integer}>` is not implemented for `f32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Sum<&f32>`
|
||||
|
|
||||
= note: `f32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Sum<&f32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29
|
||||
|
|
||||
|
|
|
|||
|
|
@ -35,10 +35,14 @@ LL | println!("{}", scores.sum::<i32>());
|
|||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:12:10
|
||||
|
|
||||
|
|
@ -71,10 +75,14 @@ LL | .sum::<i32>(),
|
|||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:25:14
|
||||
|
|
||||
|
|
@ -114,10 +122,14 @@ LL | .sum::<i32>(),
|
|||
= help: the trait `Sum<f64>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:33:14
|
||||
|
|
||||
|
|
@ -148,10 +160,14 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
|
|||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:38:38
|
||||
|
|
||||
|
|
@ -180,10 +196,14 @@ LL | println!("{}", vec![(), ()].iter().sum::<i32>());
|
|||
= help: the trait `Sum<&()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:39:33
|
||||
|
|
||||
|
|
|
|||
|
|
@ -26,13 +26,19 @@ LL | 2 as usize - Some(1);
|
|||
help: the following other types implement trait `Sub<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&usize` implements `Sub<usize>`
|
||||
= note: `usize` implements `Sub`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&usize` implements `Sub`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&usize` implements `Sub<usize>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `usize` implements `Sub<&usize>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `usize` implements `Sub`
|
||||
= note: `&usize` implements `Sub`
|
||||
= note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot multiply `{integer}` by `()`
|
||||
|
|
|
|||
|
|
@ -8,13 +8,19 @@ LL | 1.0f64 - 1
|
|||
help: the following other types implement trait `Sub<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub<f64>`
|
||||
= note: `f64` implements `Sub`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Sub<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Sub`
|
||||
= note: `&f64` implements `Sub`
|
||||
= note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
|
|||
37
tests/ui/moves/arc-consumed-in-looped-closure.rs
Normal file
37
tests/ui/moves/arc-consumed-in-looped-closure.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use std::thread;
|
||||
use std::sync::{Arc, Mutex, Condvar};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
type Job = Box<dyn FnOnce() + Send + 'static>;
|
||||
|
||||
struct ThreadPool {
|
||||
workers: Vec<thread::JoinHandle<()>>,
|
||||
queue: Arc<()>,
|
||||
}
|
||||
|
||||
impl ThreadPool {
|
||||
fn execute<F>(&self, f: F)
|
||||
where
|
||||
F: FnOnce() + Send + 'static,
|
||||
{
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE move occurs because
|
||||
let pool = ThreadPool {
|
||||
workers: vec![],
|
||||
queue: Arc::new(()),
|
||||
};
|
||||
|
||||
for i in 0..20 { //~ NOTE inside of this loop
|
||||
// let results = Arc::clone(&results); // Forgot this.
|
||||
pool.execute(move || { //~ ERROR E0382
|
||||
//~^ NOTE value moved into closure here, in previous iteration of loop
|
||||
//~| HELP consider cloning the value before moving it into the closure
|
||||
let mut r = results.lock().unwrap(); //~ NOTE use occurs due to use in closure
|
||||
r.push(i);
|
||||
});
|
||||
}
|
||||
}
|
||||
27
tests/ui/moves/arc-consumed-in-looped-closure.stderr
Normal file
27
tests/ui/moves/arc-consumed-in-looped-closure.stderr
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
error[E0382]: use of moved value: `results`
|
||||
--> $DIR/arc-consumed-in-looped-closure.rs:30:22
|
||||
|
|
||||
LL | let results = Arc::new(Mutex::new(Vec::new()));
|
||||
| ------- move occurs because `results` has type `Arc<std::sync::Mutex<Vec<i32>>>`, which does not implement the `Copy` trait
|
||||
...
|
||||
LL | for i in 0..20 {
|
||||
| -------------- inside of this loop
|
||||
LL | // let results = Arc::clone(&results); // Forgot this.
|
||||
LL | pool.execute(move || {
|
||||
| ^^^^^^^ value moved into closure here, in previous iteration of loop
|
||||
...
|
||||
LL | let mut r = results.lock().unwrap();
|
||||
| ------- use occurs due to use in closure
|
||||
|
|
||||
help: consider cloning the value before moving it into the closure
|
||||
|
|
||||
LL ~ let value = results.clone();
|
||||
LL ~ pool.execute(move || {
|
||||
LL |
|
||||
LL |
|
||||
LL ~ let mut r = value.lock().unwrap();
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
|
|
@ -7,8 +7,6 @@ fn foo() {
|
|||
//~^ NOTE this reinitialization might get skipped
|
||||
//~| NOTE move occurs because `foo` has type `String`
|
||||
//~| NOTE inside of this loop
|
||||
//~| HELP consider moving the expression out of the loop
|
||||
//~| NOTE in this expansion of desugaring of `for` loop
|
||||
//~| NOTE
|
||||
//~| NOTE
|
||||
baz.push(foo);
|
||||
|
|
@ -35,8 +33,6 @@ fn main() {
|
|||
//~| NOTE
|
||||
for bar in &bars {
|
||||
//~^ NOTE inside of this loop
|
||||
//~| HELP consider moving the expression out of the loop
|
||||
//~| NOTE in this expansion of desugaring of `for` loop
|
||||
//~| NOTE
|
||||
if foo == *bar {
|
||||
baz.push(foo);
|
||||
|
|
@ -44,7 +40,7 @@ fn main() {
|
|||
//~| HELP consider cloning the value
|
||||
continue;
|
||||
//~^ NOTE verify that your loop breaking logic is correct
|
||||
//~| NOTE this `continue` advances the loop at line 36
|
||||
//~| NOTE this `continue` advances the loop at line 34
|
||||
}
|
||||
}
|
||||
qux.push(foo);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0382]: use of moved value: `foo`
|
||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:21:14
|
||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:19:14
|
||||
|
|
||||
LL | for foo in foos { for bar in &bars { if foo == *bar {
|
||||
| --- ---------------- inside of this loop
|
||||
|
|
@ -14,29 +14,20 @@ LL | qux.push(foo);
|
|||
| ^^^ value used here after move
|
||||
|
|
||||
note: verify that your loop breaking logic is correct
|
||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:17:9
|
||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:15:9
|
||||
|
|
||||
LL | for foo in foos { for bar in &bars { if foo == *bar {
|
||||
| --------------- ----------------
|
||||
...
|
||||
LL | continue;
|
||||
| ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 20:8
|
||||
help: consider moving the expression out of the loop so it is only moved once
|
||||
|
|
||||
LL ~ for foo in foos { let mut value = baz.push(foo);
|
||||
LL ~ for bar in &bars { if foo == *bar {
|
||||
LL |
|
||||
...
|
||||
LL |
|
||||
LL ~ value;
|
||||
|
|
||||
| ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 18:8
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | baz.push(foo.clone());
|
||||
| ++++++++
|
||||
|
||||
error[E0382]: use of moved value: `foo`
|
||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:50:18
|
||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18
|
||||
|
|
||||
LL | for foo in foos {
|
||||
| ---
|
||||
|
|
@ -54,7 +45,7 @@ LL | qux.push(foo);
|
|||
| ^^^ value used here after move
|
||||
|
|
||||
note: verify that your loop breaking logic is correct
|
||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:45:17
|
||||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17
|
||||
|
|
||||
LL | for foo in foos {
|
||||
| ---------------
|
||||
|
|
@ -63,16 +54,7 @@ LL | for bar in &bars {
|
|||
| ----------------
|
||||
...
|
||||
LL | continue;
|
||||
| ^^^^^^^^ this `continue` advances the loop at line 36
|
||||
help: consider moving the expression out of the loop so it is only moved once
|
||||
|
|
||||
LL ~ let mut value = baz.push(foo);
|
||||
LL ~ for bar in &bars {
|
||||
LL |
|
||||
...
|
||||
LL | if foo == *bar {
|
||||
LL ~ value;
|
||||
|
|
||||
| ^^^^^^^^ this `continue` advances the loop at line 34
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | baz.push(foo.clone());
|
||||
|
|
|
|||
|
|
@ -8,13 +8,19 @@ LL | 2_usize + (loop {});
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&usize` implements `Add<usize>`
|
||||
= note: `usize` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&usize` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&usize` implements `Add<usize>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `usize` implements `Add<&usize>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `usize` implements `Add`
|
||||
= note: `&usize` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -8,13 +8,19 @@ LL | x + 100.0
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Add<u8>`
|
||||
= note: `u8` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Add<u8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `u8` implements `Add<&u8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `u8` implements `Add`
|
||||
= note: `&u8` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot add `&str` to `f64`
|
||||
|
|
@ -27,13 +33,19 @@ LL | x + "foo"
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add<f64>`
|
||||
= note: `f64` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Add<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Add`
|
||||
= note: `&f64` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot add `{integer}` to `f64`
|
||||
|
|
@ -46,13 +58,19 @@ LL | x + y
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add<f64>`
|
||||
= note: `f64` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Add<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Add`
|
||||
= note: `&f64` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot subtract `{float}` from `u8`
|
||||
|
|
@ -65,13 +83,19 @@ LL | x - 100.0
|
|||
help: the following other types implement trait `Sub<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Sub<u8>`
|
||||
= note: `u8` implements `Sub`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Sub`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Sub<u8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `u8` implements `Sub<&u8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `u8` implements `Sub`
|
||||
= note: `&u8` implements `Sub`
|
||||
= note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot subtract `&str` from `f64`
|
||||
|
|
@ -84,13 +108,19 @@ LL | x - "foo"
|
|||
help: the following other types implement trait `Sub<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub<f64>`
|
||||
= note: `f64` implements `Sub`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Sub<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Sub`
|
||||
= note: `&f64` implements `Sub`
|
||||
= note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot subtract `{integer}` from `f64`
|
||||
|
|
@ -103,13 +133,19 @@ LL | x - y
|
|||
help: the following other types implement trait `Sub<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub<f64>`
|
||||
= note: `f64` implements `Sub`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Sub<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Sub`
|
||||
= note: `&f64` implements `Sub`
|
||||
= note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot multiply `u8` by `{float}`
|
||||
|
|
@ -122,13 +158,19 @@ LL | x * 100.0
|
|||
help: the following other types implement trait `Mul<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Mul<u8>`
|
||||
= note: `u8` implements `Mul`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Mul`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&u8` implements `Mul<u8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `u8` implements `Mul<&u8>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `u8` implements `Mul`
|
||||
= note: `&u8` implements `Mul`
|
||||
= note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot multiply `f64` by `&str`
|
||||
|
|
@ -141,13 +183,19 @@ LL | x * "foo"
|
|||
help: the following other types implement trait `Mul<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul<f64>`
|
||||
= note: `f64` implements `Mul`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Mul<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Mul`
|
||||
= note: `&f64` implements `Mul`
|
||||
= note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot multiply `f64` by `{integer}`
|
||||
|
|
@ -160,13 +208,19 @@ LL | x * y
|
|||
help: the following other types implement trait `Mul<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul<f64>`
|
||||
= note: `f64` implements `Mul`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Mul<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Mul`
|
||||
= note: `&f64` implements `Mul`
|
||||
= note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot divide `u8` by `{float}`
|
||||
|
|
@ -193,13 +247,19 @@ LL | x / "foo"
|
|||
help: the following other types implement trait `Div<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div<f64>`
|
||||
= note: `f64` implements `Div`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Div<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Div`
|
||||
= note: `&f64` implements `Div`
|
||||
= note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: cannot divide `f64` by `{integer}`
|
||||
|
|
@ -212,13 +272,19 @@ LL | x / y
|
|||
help: the following other types implement trait `Div<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div<f64>`
|
||||
= note: `f64` implements `Div`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Div<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Div`
|
||||
= note: `&f64` implements `Div`
|
||||
= note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
|
|
|||
|
|
@ -8,13 +8,19 @@ LL | x + 100
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Add<f32>`
|
||||
= note: `f32` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Add<f32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Add<&f32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Add`
|
||||
= note: `&f32` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
@ -31,13 +37,19 @@ LL | x + 100
|
|||
help: the following other types implement trait `Add<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add<f64>`
|
||||
= note: `f64` implements `Add`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Add<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Add<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Add`
|
||||
= note: `&f64` implements `Add`
|
||||
= note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
@ -54,13 +66,19 @@ LL | x - 100
|
|||
help: the following other types implement trait `Sub<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Sub<f32>`
|
||||
= note: `f32` implements `Sub`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Sub`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Sub<f32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Sub<&f32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Sub`
|
||||
= note: `&f32` implements `Sub`
|
||||
= note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
@ -77,13 +95,19 @@ LL | x - 100
|
|||
help: the following other types implement trait `Sub<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub<f64>`
|
||||
= note: `f64` implements `Sub`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Sub<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Sub<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Sub`
|
||||
= note: `&f64` implements `Sub`
|
||||
= note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
@ -100,13 +124,19 @@ LL | x * 100
|
|||
help: the following other types implement trait `Mul<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Mul<f32>`
|
||||
= note: `f32` implements `Mul`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Mul`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Mul<f32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Mul<&f32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Mul`
|
||||
= note: `&f32` implements `Mul`
|
||||
= note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
@ -123,13 +153,19 @@ LL | x * 100
|
|||
help: the following other types implement trait `Mul<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul<f64>`
|
||||
= note: `f64` implements `Mul`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Mul<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Mul<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Mul`
|
||||
= note: `&f64` implements `Mul`
|
||||
= note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
@ -146,13 +182,19 @@ LL | x / 100
|
|||
help: the following other types implement trait `Div<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Div<f32>`
|
||||
= note: `f32` implements `Div`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Div`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f32` implements `Div<f32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Div<&f32>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f32` implements `Div`
|
||||
= note: `&f32` implements `Div`
|
||||
= note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
@ -169,13 +211,19 @@ LL | x / 100
|
|||
help: the following other types implement trait `Div<Rhs>`
|
||||
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div<f64>`
|
||||
= note: `f64` implements `Div`
|
||||
::: $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div`
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `&f64` implements `Div<f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Div<&f64>`
|
||||
::: $SRC_DIR/core/src/internal_macros.rs:LL:COL
|
||||
|
|
||||
= note: `f64` implements `Div`
|
||||
= note: `&f64` implements `Div`
|
||||
= note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider using a floating-point literal by writing it with `.0`
|
||||
|
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ help: the following other types implement trait `SliceIndex<T>`
|
|||
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
||||
|
|
||||
= note: `RangeTo<usize>` implements `SliceIndex<ByteStr>`
|
||||
::: $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
--> $SRC_DIR/core/src/str/traits.rs:LL:COL
|
||||
|
|
||||
= note: `RangeTo<usize>` implements `SliceIndex<str>`
|
||||
|
|
|
|||
|
|
@ -9,10 +9,14 @@ LL | vec![(), ()].iter().sum::<i32>();
|
|||
= help: the trait `Sum<&()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Sum<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Sum`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Sum<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/sum.rs:4:18
|
||||
|
|
||||
|
|
@ -35,10 +39,14 @@ LL | vec![(), ()].iter().product::<i32>();
|
|||
= help: the trait `Product<&()>` is not implemented for `i32`
|
||||
help: the following other types implement trait `Product<A>`
|
||||
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Product<&i32>`
|
||||
|
|
||||
= note: `i32` implements `Product`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: `i32` implements `Product<&i32>`
|
||||
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
||||
|
|
||||
= note: in this macro invocation
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/sum.rs:7:18
|
||||
|
|
||||
|
|
|
|||
|
|
@ -112,10 +112,13 @@ LL | test!();
|
|||
= note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0432]: unresolved import `$crate`
|
||||
--> $DIR/mixed-site-span.rs:69:5
|
||||
--> $DIR/mixed-site-span.rs:67:9
|
||||
|
|
||||
LL | invoke_with_ident!{$crate call proc_macro_item}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root
|
||||
LL | }}
|
||||
LL | test!();
|
||||
| ^^^^^^^ no `proc_macro_item` in the root
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
|
@ -262,10 +265,13 @@ LL + token_site_span::TokenItem as _
|
|||
|
|
||||
|
||||
error[E0432]: unresolved import `$crate`
|
||||
--> $DIR/mixed-site-span.rs:110:5
|
||||
--> $DIR/mixed-site-span.rs:106:9
|
||||
|
|
||||
LL | invoke_with_ident!{$crate mixed TokenItem}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root
|
||||
...
|
||||
LL | test!();
|
||||
| ^^^^^^^ no `TokenItem` in the root
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider importing this struct instead
|
||||
|
|
@ -417,10 +423,13 @@ LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ };
|
|||
|
|
||||
|
||||
error[E0432]: unresolved import `$crate`
|
||||
--> $DIR/mixed-site-span.rs:150:5
|
||||
--> $DIR/mixed-site-span.rs:145:9
|
||||
|
|
||||
LL | invoke_with_ident!{$crate mixed ItemUse}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
|
||||
...
|
||||
LL | test!();
|
||||
| ^^^^^^^ no `ItemUse` in the root
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider importing this struct instead
|
||||
|
|
@ -447,10 +456,13 @@ LL + ItemUse as _
|
|||
|
|
||||
|
||||
error[E0432]: unresolved import `$crate`
|
||||
--> $DIR/mixed-site-span.rs:150:5
|
||||
--> $DIR/mixed-site-span.rs:148:9
|
||||
|
|
||||
LL | invoke_with_ident!{$crate call ItemUse}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root
|
||||
LL | }}
|
||||
LL | test!();
|
||||
| ^^^^^^^ no `ItemUse` in the root
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider importing this struct instead
|
||||
|
|
|
|||
16
tests/ui/span/macro-span-caller-replacement.rs
Normal file
16
tests/ui/span/macro-span-caller-replacement.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
macro_rules! macro_with_format { () => {
|
||||
fn check_5(arg : usize) -> String {
|
||||
let s : &str;
|
||||
if arg < 5 {
|
||||
s = format!("{arg}"); //~ ERROR mismatched types
|
||||
} else {
|
||||
s = String::new(); //~ ERROR mismatched types
|
||||
}
|
||||
String::from(s)
|
||||
}
|
||||
}}
|
||||
|
||||
fn main() {
|
||||
macro_with_format!();
|
||||
println!( "{}", check_5(6) );
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue