Auto merge of #106442 - matthiaskrgr:rollup-wivf7gh, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #106200 (Suggest `impl Fn*` and `impl Future` in `-> _` return suggestions)
 - #106274 (Add JSON output to -Zdump-mono-stats)
 - #106292 (Add codegen test for `Box::new(uninit)` of big arrays)
 - #106327 (Add tidy check for dbg)
 - #106361 (Note maximum integer literal for `IntLiteralTooLarge`)
 - #106396 (Allow passing a specific date to `bump-stage0`)
 - #106436 (Enable doctests for rustc_query_impl)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-01-04 09:41:43 +00:00
commit 5c18bc6137
37 changed files with 477 additions and 131 deletions

View File

@ -4243,6 +4243,8 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"serde",
"serde_json",
"smallvec",
"tracing",
]

View File

@ -34,7 +34,7 @@ pub enum LitError {
InvalidIntSuffix,
InvalidFloatSuffix,
NonDecimalFloat(u32),
IntTooLarge,
IntTooLarge(u32),
}
impl LitKind {
@ -333,6 +333,6 @@ fn integer_lit(symbol: Symbol, suffix: Option<Symbol>) -> Result<LitKind, LitErr
// but these kinds of errors are already reported by the lexer.
let from_lexer =
base < 10 && s.chars().any(|c| c.to_digit(10).map_or(false, |d| d >= base));
if from_lexer { LitError::LexerError } else { LitError::IntTooLarge }
if from_lexer { LitError::LexerError } else { LitError::IntTooLarge(base) }
})
}

View File

@ -85,6 +85,7 @@ session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float lite
.help = valid suffixes are `f32` and `f64`
session_int_literal_too_large = integer literal is too large
.note = value exceeds limit of `{$limit}`
session_invalid_int_literal_width = invalid width `{$width}` for integer literal
.help = valid widths are 8, 16, 32, 64 and 128

View File

@ -17,6 +17,7 @@
use crate::astconv::AstConv;
use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::errors;
use hir::def::DefKind;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
@ -24,8 +25,8 @@ use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{GenericParamKind, Node};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::ObligationCause;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::util::{Discr, IntTypeExt};
@ -1195,12 +1196,11 @@ fn infer_return_ty_for_fn_sig<'tcx>(
ty::ReErased => tcx.lifetimes.re_static,
_ => r,
});
let fn_sig = ty::Binder::dummy(fn_sig);
let mut visitor = HirPlaceholderCollector::default();
visitor.visit_ty(ty);
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
let ret_ty = fn_sig.skip_binder().output();
let ret_ty = fn_sig.output();
if ret_ty.is_suggestable(tcx, false) {
diag.span_suggestion(
ty.span,
@ -1223,26 +1223,26 @@ fn infer_return_ty_for_fn_sig<'tcx>(
Applicability::MachineApplicable,
);
}
} else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, hir_id, def_id) {
diag.span_suggestion(
ty.span,
"replace with an appropriate return type",
sugg,
Applicability::MachineApplicable,
);
} else if ret_ty.is_closure() {
// We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds
// to prevent the user from getting a papercut while trying to use the unique closure
// syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
}
// Also note how `Fn` traits work just in case!
if ret_ty.is_closure() {
diag.note(
"for more information on `Fn` traits and closure types, see \
https://doc.rust-lang.org/book/ch13-01-closures.html",
);
} else if let Some(i_ty) = suggest_impl_iterator(tcx, ret_ty, ty.span, hir_id, def_id) {
diag.span_suggestion(
ty.span,
"replace with an appropriate return type",
format!("impl Iterator<Item = {}>", i_ty),
Applicability::MachineApplicable,
);
}
diag.emit();
fn_sig
ty::Binder::dummy(fn_sig)
}
None => <dyn AstConv<'_>>::ty_of_fn(
icx,
@ -1256,47 +1256,94 @@ fn infer_return_ty_for_fn_sig<'tcx>(
}
}
fn suggest_impl_iterator<'tcx>(
fn suggest_impl_trait<'tcx>(
tcx: TyCtxt<'tcx>,
ret_ty: Ty<'tcx>,
span: Span,
hir_id: hir::HirId,
def_id: LocalDefId,
) -> Option<Ty<'tcx>> {
let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) else { return None; };
let Some(iterator_item) = tcx.get_diagnostic_item(sym::IteratorItem) else { return None; };
if !tcx
.infer_ctxt()
.build()
.type_implements_trait(iter_trait, [ret_ty], tcx.param_env(def_id))
.must_apply_modulo_regions()
{
return None;
}
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
// Find the type of `Iterator::Item`.
let origin = TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
let ty_var = infcx.next_ty_var(origin);
let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Projection(
ty::ProjectionPredicate {
projection_ty: tcx.mk_alias_ty(iterator_item, tcx.mk_substs([ret_ty.into()].iter())),
term: ty_var.into(),
},
)));
// Add `<ret_ty as Iterator>::Item = _` obligation.
ocx.register_obligation(crate::traits::Obligation::misc(
tcx,
span,
hir_id,
tcx.param_env(def_id),
projection,
));
if ocx.select_where_possible().is_empty()
&& let item_ty = infcx.resolve_vars_if_possible(ty_var)
&& item_ty.is_suggestable(tcx, false)
{
return Some(item_ty);
) -> Option<String> {
let format_as_assoc: fn(_, _, _, _, _) -> _ =
|tcx: TyCtxt<'tcx>,
_: ty::SubstsRef<'tcx>,
trait_def_id: DefId,
assoc_item_def_id: DefId,
item_ty: Ty<'tcx>| {
let trait_name = tcx.item_name(trait_def_id);
let assoc_name = tcx.item_name(assoc_item_def_id);
Some(format!("impl {trait_name}<{assoc_name} = {item_ty}>"))
};
let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
|tcx: TyCtxt<'tcx>,
substs: ty::SubstsRef<'tcx>,
trait_def_id: DefId,
_: DefId,
item_ty: Ty<'tcx>| {
let trait_name = tcx.item_name(trait_def_id);
let args_tuple = substs.type_at(1);
let ty::Tuple(types) = *args_tuple.kind() else { return None; };
if !types.is_suggestable(tcx, false) {
return None;
}
let maybe_ret =
if item_ty.is_unit() { String::new() } else { format!(" -> {item_ty}") };
Some(format!(
"impl {trait_name}({}){maybe_ret}",
types.iter().map(|ty| ty.to_string()).collect::<Vec<_>>().join(", ")
))
};
for (trait_def_id, assoc_item_def_id, formatter) in [
(
tcx.get_diagnostic_item(sym::Iterator),
tcx.get_diagnostic_item(sym::IteratorItem),
format_as_assoc,
),
(
tcx.lang_items().future_trait(),
tcx.get_diagnostic_item(sym::FutureOutput),
format_as_assoc,
),
(tcx.lang_items().fn_trait(), tcx.lang_items().fn_once_output(), format_as_parenthesized),
(
tcx.lang_items().fn_mut_trait(),
tcx.lang_items().fn_once_output(),
format_as_parenthesized,
),
(
tcx.lang_items().fn_once_trait(),
tcx.lang_items().fn_once_output(),
format_as_parenthesized,
),
] {
let Some(trait_def_id) = trait_def_id else { continue; };
let Some(assoc_item_def_id) = assoc_item_def_id else { continue; };
if tcx.def_kind(assoc_item_def_id) != DefKind::AssocTy {
continue;
}
let param_env = tcx.param_env(def_id);
let infcx = tcx.infer_ctxt().build();
let substs = ty::InternalSubsts::for_item(tcx, trait_def_id, |param, _| {
if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(span, param) }
});
if !infcx.type_implements_trait(trait_def_id, substs, param_env).must_apply_modulo_regions()
{
continue;
}
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
let item_ty = ocx.normalize(
&ObligationCause::misc(span, hir_id),
param_env,
tcx.mk_projection(assoc_item_def_id, substs),
);
// FIXME(compiler-errors): We may benefit from resolving regions here.
if ocx.select_where_possible().is_empty()
&& let item_ty = infcx.resolve_vars_if_possible(item_ty)
&& item_ty.is_suggestable(tcx, false)
&& let Some(sugg) = formatter(tcx, infcx.resolve_vars_if_possible(substs), trait_def_id, assoc_item_def_id, item_ty)
{
return Some(sugg);
}
}
None
}

View File

@ -3,17 +3,16 @@ use crate::interface::parse_cfgspecs;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_session::config::InstrumentCoverage;
use rustc_session::config::Strip;
use rustc_session::config::rustc_optgroups;
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
use rustc_session::config::{
rustc_optgroups, ErrorOutputType, ExternLocation, LocationDetail, Options, Passes,
};
use rustc_session::config::{
BranchProtection, Externs, OomStrategy, OutputType, OutputTypes, PAuthKey, PacRet,
ProcMacroExecutionStrategy, SymbolManglingVersion, WasiExecModel,
};
use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
use rustc_session::config::{DumpMonoStatsFormat, MirSpanview};
use rustc_session::config::{ErrorOutputType, ExternLocation, LocationDetail, Options, Strip};
use rustc_session::config::{InstrumentCoverage, Passes};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
@ -647,6 +646,9 @@ fn test_unstable_options_tracking_hash() {
untracked!(dump_mir_dir, String::from("abc"));
untracked!(dump_mir_exclude_pass_number, true);
untracked!(dump_mir_graphviz, true);
untracked!(dump_mir_spanview, Some(MirSpanview::Statement));
untracked!(dump_mono_stats, SwitchWithOptPath::Enabled(Some("mono-items-dir/".into())));
untracked!(dump_mono_stats_format, DumpMonoStatsFormat::Json);
untracked!(dylib_lto, true);
untracked!(emit_stack_sizes, true);
untracked!(future_incompat_test, true);

View File

@ -6,6 +6,8 @@ edition = "2021"
[lib]
[dependencies]
serde = "1"
serde_json = "1"
smallvec = { version = "1.8.1", features = [ "union", "may_dangle" ] }
tracing = "0.1"
rustc_data_structures = { path = "../rustc_data_structures" }

View File

@ -102,14 +102,14 @@ use std::path::{Path, PathBuf};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync;
use rustc_hir::def_id::DefIdSet;
use rustc_hir::def_id::{DefIdSet, LOCAL_CRATE};
use rustc_middle::mir;
use rustc_middle::mir::mono::MonoItem;
use rustc_middle::mir::mono::{CodegenUnit, Linkage};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::SwitchWithOptPath;
use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
use rustc_span::symbol::Symbol;
use crate::collector::InliningMap;
@ -417,7 +417,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
// Output monomorphization stats per def_id
if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats {
if let Err(err) =
dump_mono_items_stats(tcx, &codegen_units, path, tcx.sess.opts.crate_name.as_deref())
dump_mono_items_stats(tcx, &codegen_units, path, tcx.crate_name(LOCAL_CRATE))
{
tcx.sess.emit_fatal(CouldntDumpMonoStats { error: err.to_string() });
}
@ -483,7 +483,7 @@ fn dump_mono_items_stats<'tcx>(
tcx: TyCtxt<'tcx>,
codegen_units: &[CodegenUnit<'tcx>],
output_directory: &Option<PathBuf>,
crate_name: Option<&str>,
crate_name: Symbol,
) -> Result<(), Box<dyn std::error::Error>> {
let output_directory = if let Some(ref directory) = output_directory {
fs::create_dir_all(directory)?;
@ -492,9 +492,11 @@ fn dump_mono_items_stats<'tcx>(
Path::new(".")
};
let filename = format!("{}.mono_items.md", crate_name.unwrap_or("unknown-crate"));
let format = tcx.sess.opts.unstable_opts.dump_mono_stats_format;
let ext = format.extension();
let filename = format!("{crate_name}.mono_items.{ext}");
let output_path = output_directory.join(&filename);
let file = File::create(output_path)?;
let file = File::create(&output_path)?;
let mut file = BufWriter::new(file);
// Gather instantiated mono items grouped by def_id
@ -508,30 +510,44 @@ fn dump_mono_items_stats<'tcx>(
}
}
#[derive(serde::Serialize)]
struct MonoItem {
name: String,
instantiation_count: usize,
size_estimate: usize,
total_estimate: usize,
}
// Output stats sorted by total instantiated size, from heaviest to lightest
let mut stats: Vec<_> = items_per_def_id
.into_iter()
.map(|(def_id, items)| {
let name = with_no_trimmed_paths!(tcx.def_path_str(def_id));
let instantiation_count = items.len();
let size_estimate = items[0].size_estimate(tcx);
let total_estimate = instantiation_count * size_estimate;
(def_id, instantiation_count, size_estimate, total_estimate)
MonoItem { name, instantiation_count, size_estimate, total_estimate }
})
.collect();
stats.sort_unstable_by_key(|(_, _, _, total_estimate)| cmp::Reverse(*total_estimate));
stats.sort_unstable_by_key(|item| cmp::Reverse(item.total_estimate));
if !stats.is_empty() {
writeln!(
file,
"| Item | Instantiation count | Estimated Cost Per Instantiation | Total Estimated Cost |"
)?;
writeln!(file, "| --- | ---: | ---: | ---: |")?;
for (def_id, instantiation_count, size_estimate, total_estimate) in stats {
let item = with_no_trimmed_paths!(tcx.def_path_str(def_id));
writeln!(
file,
"| {item} | {instantiation_count} | {size_estimate} | {total_estimate} |"
)?;
match format {
DumpMonoStatsFormat::Json => serde_json::to_writer(file, &stats)?,
DumpMonoStatsFormat::Markdown => {
writeln!(
file,
"| Item | Instantiation count | Estimated Cost Per Instantiation | Total Estimated Cost |"
)?;
writeln!(file, "| --- | ---: | ---: | ---: |")?;
for MonoItem { name, instantiation_count, size_estimate, total_estimate } in stats {
writeln!(
file,
"| `{name}` | {instantiation_count} | {size_estimate} | {total_estimate} |"
)?;
}
}
}
}

View File

@ -4,7 +4,7 @@ version = "0.0.0"
edition = "2021"
[lib]
doctest = false
[dependencies]
measureme = "10.0.0"

View File

@ -2981,3 +2981,21 @@ pub enum ProcMacroExecutionStrategy {
/// Run the proc-macro code on a different thread.
CrossThread,
}
/// Which format to use for `-Z dump-mono-stats`
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum DumpMonoStatsFormat {
/// Pretty-print a markdown table
Markdown,
/// Emit structured JSON
Json,
}
impl DumpMonoStatsFormat {
pub fn extension(self) -> &'static str {
match self {
Self::Markdown => "md",
Self::Json => "json",
}
}
}

View File

@ -260,9 +260,11 @@ pub(crate) struct InvalidFloatLiteralSuffix {
#[derive(Diagnostic)]
#[diag(session_int_literal_too_large)]
#[note]
pub(crate) struct IntLiteralTooLarge {
#[primary_span]
pub span: Span,
pub limit: String,
}
#[derive(Diagnostic)]
@ -361,8 +363,15 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
_ => unreachable!(),
};
}
LitError::IntTooLarge => {
sess.emit_err(IntLiteralTooLarge { span });
LitError::IntTooLarge(base) => {
let max = u128::MAX;
let limit = match base {
2 => format!("{max:#b}"),
8 => format!("{max:#o}"),
16 => format!("{max:#x}"),
_ => format!("{max}"),
};
sess.emit_err(IntLiteralTooLarge { span, limit });
}
}
}

View File

@ -377,6 +377,7 @@ mod desc {
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
pub const parse_optimization_fuel: &str = "crate=integer";
pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`";
pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
pub const parse_instrument_coverage: &str =
"`all` (default), `except-unused-generics`, `except-unused-functions`, or `off`";
pub const parse_unpretty: &str = "`string` or `string=string`";
@ -820,6 +821,21 @@ mod parse {
true
}
pub(crate) fn parse_dump_mono_stats(slot: &mut DumpMonoStatsFormat, v: Option<&str>) -> bool {
match v {
None => true,
Some("json") => {
*slot = DumpMonoStatsFormat::Json;
true
}
Some("markdown") => {
*slot = DumpMonoStatsFormat::Markdown;
true
}
Some(_) => false,
}
}
pub(crate) fn parse_instrument_coverage(
slot: &mut Option<InstrumentCoverage>,
v: Option<&str>,
@ -1295,7 +1311,9 @@ options! {
an additional `.html` file showing the computed coverage spans."),
dump_mono_stats: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
parse_switch_with_opt_path, [UNTRACKED],
"output statistics about monomorphization collection (format: markdown)"),
"output statistics about monomorphization collection"),
dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED],
"the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"),
dwarf_version: Option<u32> = (None, parse_opt_number, [TRACKED],
"version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
dylib_lto: bool = (false, parse_bool, [UNTRACKED],

View File

@ -193,6 +193,7 @@ symbols! {
FromIterator,
FromResidual,
Future,
FutureOutput,
FxHashMap,
FxHashSet,
GlobalAlloc,

View File

@ -37,6 +37,7 @@ use crate::task::{Context, Poll};
pub trait Future {
/// The type of value produced on completion.
#[stable(feature = "futures_api", since = "1.36.0")]
#[rustc_diagnostic_item = "FutureOutput"]
type Output;
/// Attempt to resolve the future to a final value, registering

View File

@ -3,6 +3,7 @@
//! This module contains a set of macros which are exported from the standard
//! library. Each macro is available for use when linking against the standard
//! library.
// ignore-tidy-dbg
#[doc = include_str!("../../core/src/macros/panic.md")]
#[macro_export]

View File

@ -105,6 +105,7 @@ impl Step for BumpStage0 {
fn run(self, builder: &Builder<'_>) -> Self::Output {
let mut cmd = builder.tool_cmd(Tool::BumpStage0);
cmd.args(builder.config.cmd.args());
builder.run(&mut cmd);
}
}

View File

@ -0,0 +1,6 @@
# `dump-mono-stats-format`
--------------------
The `-Z dump-mono-stats-format` compiler flag controls what file format to use for `-Z dump-mono-stats`.
The default is markdown; currently JSON is also supported. JSON can be useful for programatically manipulating the results (e.g. to find the item that took the longest to compile).

View File

@ -0,0 +1,14 @@
# `dump-mono-stats`
--------------------
The `-Z dump-mono-stats` compiler flag generates a file with a list of the monomorphized items in the current crate.
It is useful for investigating compile times.
It accepts an optional directory where the file will be located. If no directory is specified, the file will be placed in the current directory.
See also `-Z dump-mono-stats-format` and `-Z print-mono-items`. Unlike `print-mono-items`,
`dump-mono-stats` aggregates monomorphized items by definition and includes a size estimate of how
large the item is when codegened.
See <https://rustc-dev-guide.rust-lang.org/backend/monomorph.html> for an overview of monomorphized items.

View File

@ -2,7 +2,7 @@
// Once we're done with llvm 14 and earlier, this test can be deleted.
#![crate_type="lib"]
#![crate_type = "lib"]
use std::mem::MaybeUninit;
@ -17,8 +17,16 @@ pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
Box::new(MaybeUninit::uninit())
}
// FIXME: add a test for a bigger box. Currently broken, see
// https://github.com/rust-lang/rust/issues/58201.
// https://github.com/rust-lang/rust/issues/58201
#[no_mangle]
pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
// CHECK-LABEL: @box_uninitialized2
// CHECK-NOT: store
// CHECK-NOT: alloca
// CHECK-NOT: memcpy
// CHECK-NOT: memset
Box::new(MaybeUninit::uninit())
}
// Hide the LLVM 15+ `allocalign` attribute in the declaration of __rust_alloc
// from the CHECK-NOT above. We don't check the attributes here because we can't rely

View File

@ -1,6 +1,6 @@
// compile-flags: -O
// min-llvm-version: 15.0
#![crate_type="lib"]
#![crate_type = "lib"]
use std::mem::MaybeUninit;
@ -15,8 +15,16 @@ pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
Box::new(MaybeUninit::uninit())
}
// FIXME: add a test for a bigger box. Currently broken, see
// https://github.com/rust-lang/rust/issues/58201.
// https://github.com/rust-lang/rust/issues/58201
#[no_mangle]
pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
// CHECK-LABEL: @box_uninitialized2
// CHECK-NOT: store
// CHECK-NOT: alloca
// CHECK-NOT: memcpy
// CHECK-NOT: memset
Box::new(MaybeUninit::uninit())
}
// Hide the `allocalign` attribute in the declaration of __rust_alloc
// from the CHECK-NOT above, and also verify the attributes got set reasonably.

View File

@ -0,0 +1,5 @@
include ../../run-make-fulldeps/tools.mk
all:
$(RUSTC) --crate-type lib foo.rs -Z dump-mono-stats=$(TMPDIR) -Zdump-mono-stats-format=json
cat $(TMPDIR)/foo.mono_items.json | $(CGREP) '"name":"bar"'

View File

@ -0,0 +1 @@
pub fn bar() {}

View File

@ -35,7 +35,8 @@
-Z dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no)
-Z dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no)
-Z dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans.
-Z dump-mono-stats=val -- output statistics about monomorphization collection (format: markdown)
-Z dump-mono-stats=val -- output statistics about monomorphization collection
-Z dump-mono-stats-format=val -- the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)
-Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform)
-Z dylib-lto=val -- enables LTO for dylib crate type
-Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)

View File

@ -18,9 +18,9 @@ fn returns_fn_ptr() -> _ {
fn returns_closure() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
//~| NOTE not allowed in type signatures
//~| HELP consider using an `Fn`, `FnMut`, or `FnOnce` trait bound
//~| NOTE for more information on `Fn` traits and closure types, see
// https://doc.rust-lang.org/book/ch13-01-closures.html
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl Fn() -> i32
//~| NOTE for more information on `Fn` traits and closure types
|| 0
}

View File

@ -11,9 +11,11 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
--> $DIR/issue-80179.rs:18:25
|
LL | fn returns_closure() -> _ {
| ^ not allowed in type signatures
| ^
| |
| not allowed in type signatures
| help: replace with an appropriate return type: `impl Fn() -> i32`
|
= help: consider using an `Fn`, `FnMut`, or `FnOnce` trait bound
= note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
error: aborting due to 2 previous errors

View File

@ -0,0 +1,34 @@
fn fn_once() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
//~| NOTE not allowed in type signatures
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl FnOnce()
//~| NOTE for more information on `Fn` traits and closure types
let x = String::new();
|| {
drop(x);
}
}
fn fn_mut() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
//~| NOTE not allowed in type signatures
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl FnMut(char)
//~| NOTE for more information on `Fn` traits and closure types
let x = String::new();
|c| {
x.push(c);
}
}
fn fun() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
//~| NOTE not allowed in type signatures
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl Fn() -> i32
//~| NOTE for more information on `Fn` traits and closure types
|| 1i32
}
fn main() {}

View File

@ -0,0 +1,36 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-return-closure.rs:1:17
|
LL | fn fn_once() -> _ {
| ^
| |
| not allowed in type signatures
| help: replace with an appropriate return type: `impl FnOnce()`
|
= note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-return-closure.rs:13:16
|
LL | fn fn_mut() -> _ {
| ^
| |
| not allowed in type signatures
| help: replace with an appropriate return type: `impl FnMut(char)`
|
= note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-return-closure.rs:25:13
|
LL | fn fun() -> _ {
| ^
| |
| not allowed in type signatures
| help: replace with an appropriate return type: `impl Fn() -> i32`
|
= note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0121`.

View File

@ -0,0 +1,23 @@
// edition: 2021
async fn a() -> i32 {
0
}
fn foo() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
//~| NOTE not allowed in type signatures
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl Future<Output = i32>
a()
}
fn bar() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
//~| NOTE not allowed in type signatures
//~| HELP replace with an appropriate return type
//~| SUGGESTION impl Future<Output = i32>
async { a().await }
}
fn main() {}

View File

@ -0,0 +1,21 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-return-future.rs:7:13
|
LL | fn foo() -> _ {
| ^
| |
| not allowed in type signatures
| help: replace with an appropriate return type: `impl Future<Output = i32>`
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/suggest-return-future.rs:15:13
|
LL | fn bar() -> _ {
| ^
| |
| not allowed in type signatures
| help: replace with an appropriate return type: `impl Future<Output = i32>`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0121`.

View File

@ -49,6 +49,8 @@ error: integer literal is too large
|
LL | 999340282366920938463463374607431768211455999;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `340282366920938463463374607431768211455`
error: aborting due to 8 previous errors

View File

@ -1,3 +1,5 @@
// ignore-tidy-linelength
fn main() {
0o1.0; //~ ERROR: octal float literal is not supported
0o2f32; //~ ERROR: octal float literal is not supported
@ -15,6 +17,12 @@ fn main() {
//~^ ERROR: integer literal is too large
9900000000000000000000000000999999999999999999999999999999;
//~^ ERROR: integer literal is too large
0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110;
//~^ ERROR: integer literal is too large
0o37777777777777777777777777777777777777777770;
//~^ ERROR: integer literal is too large
0xffffffffffffffffffffffffffffffff0;
//~^ ERROR: integer literal is too large
0x; //~ ERROR: no valid digits
0xu32; //~ ERROR: no valid digits
0ou32; //~ ERROR: no valid digits

View File

@ -1,141 +1,169 @@
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:2:5
--> $DIR/lex-bad-numeric-literals.rs:4:5
|
LL | 0o1.0;
| ^^^^^
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:4:5
--> $DIR/lex-bad-numeric-literals.rs:6:5
|
LL | 0o3.0f32;
| ^^^^^
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:5:5
--> $DIR/lex-bad-numeric-literals.rs:7:5
|
LL | 0o4e4;
| ^^^^^
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:6:5
--> $DIR/lex-bad-numeric-literals.rs:8:5
|
LL | 0o5.0e5;
| ^^^^^^^
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:7:5
--> $DIR/lex-bad-numeric-literals.rs:9:5
|
LL | 0o6e6f32;
| ^^^^^
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:8:5
--> $DIR/lex-bad-numeric-literals.rs:10:5
|
LL | 0o7.0e7f64;
| ^^^^^^^
error: hexadecimal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:9:5
--> $DIR/lex-bad-numeric-literals.rs:11:5
|
LL | 0x8.0e+9;
| ^^^^^^^^
error: hexadecimal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:10:5
--> $DIR/lex-bad-numeric-literals.rs:12:5
|
LL | 0x9.0e-9;
| ^^^^^^^^
error[E0768]: no valid digits found for number
--> $DIR/lex-bad-numeric-literals.rs:11:5
--> $DIR/lex-bad-numeric-literals.rs:13:5
|
LL | 0o;
| ^^
error: expected at least one digit in exponent
--> $DIR/lex-bad-numeric-literals.rs:12:5
--> $DIR/lex-bad-numeric-literals.rs:14:5
|
LL | 1e+;
| ^^^
error: hexadecimal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:13:5
--> $DIR/lex-bad-numeric-literals.rs:15:5
|
LL | 0x539.0;
| ^^^^^^^
error[E0768]: no valid digits found for number
--> $DIR/lex-bad-numeric-literals.rs:18:5
--> $DIR/lex-bad-numeric-literals.rs:26:5
|
LL | 0x;
| ^^
error[E0768]: no valid digits found for number
--> $DIR/lex-bad-numeric-literals.rs:19:5
--> $DIR/lex-bad-numeric-literals.rs:27:5
|
LL | 0xu32;
| ^^
error[E0768]: no valid digits found for number
--> $DIR/lex-bad-numeric-literals.rs:20:5
--> $DIR/lex-bad-numeric-literals.rs:28:5
|
LL | 0ou32;
| ^^
error[E0768]: no valid digits found for number
--> $DIR/lex-bad-numeric-literals.rs:21:5
--> $DIR/lex-bad-numeric-literals.rs:29:5
|
LL | 0bu32;
| ^^
error[E0768]: no valid digits found for number
--> $DIR/lex-bad-numeric-literals.rs:22:5
--> $DIR/lex-bad-numeric-literals.rs:30:5
|
LL | 0b;
| ^^
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:24:5
--> $DIR/lex-bad-numeric-literals.rs:32:5
|
LL | 0o123.456;
| ^^^^^^^^^
error: binary float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:26:5
--> $DIR/lex-bad-numeric-literals.rs:34:5
|
LL | 0b111.101;
| ^^^^^^^^^
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:3:5
--> $DIR/lex-bad-numeric-literals.rs:5:5
|
LL | 0o2f32;
| ^^^^^^ not supported
error: integer literal is too large
--> $DIR/lex-bad-numeric-literals.rs:14:5
|
LL | 9900000000000000000000000000999999999999999999999999999999;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: integer literal is too large
--> $DIR/lex-bad-numeric-literals.rs:16:5
|
LL | 9900000000000000000000000000999999999999999999999999999999;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `340282366920938463463374607431768211455`
error: integer literal is too large
--> $DIR/lex-bad-numeric-literals.rs:18:5
|
LL | 9900000000000000000000000000999999999999999999999999999999;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `340282366920938463463374607431768211455`
error: integer literal is too large
--> $DIR/lex-bad-numeric-literals.rs:20:5
|
LL | 0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111`
error: integer literal is too large
--> $DIR/lex-bad-numeric-literals.rs:22:5
|
LL | 0o37777777777777777777777777777777777777777770;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `0o3777777777777777777777777777777777777777777`
error: integer literal is too large
--> $DIR/lex-bad-numeric-literals.rs:24:5
|
LL | 0xffffffffffffffffffffffffffffffff0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `0xffffffffffffffffffffffffffffffff`
error: octal float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:23:5
--> $DIR/lex-bad-numeric-literals.rs:31:5
|
LL | 0o123f64;
| ^^^^^^^^ not supported
error: binary float literal is not supported
--> $DIR/lex-bad-numeric-literals.rs:25:5
--> $DIR/lex-bad-numeric-literals.rs:33:5
|
LL | 0b101f64;
| ^^^^^^^^ not supported
error: aborting due to 23 previous errors
error: aborting due to 26 previous errors
For more information about this error, try `rustc --explain E0768`.

View File

@ -11,6 +11,8 @@ error: integer literal is too large
|
LL | concat_bytes!(888888888888888888888888888888888888888);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `340282366920938463463374607431768211455`
error: aborting due to 2 previous errors

View File

@ -3,6 +3,8 @@ error: integer literal is too large
|
LL | 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `340282366920938463463374607431768211455`
error: aborting due to previous error

View File

@ -3,6 +3,8 @@ error: integer literal is too large
|
LL | let __isize = 340282366920938463463374607431768211456; // 2^128
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `340282366920938463463374607431768211455`
error: aborting due to previous error

View File

@ -3,6 +3,8 @@ error: integer literal is too large
|
LL | let __isize = 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ff;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: value exceeds limit of `0xffffffffffffffffffffffffffffffff`
error: aborting due to previous error

View File

@ -1,4 +1,4 @@
use anyhow::Error;
use anyhow::{Context, Error};
use curl::easy::Easy;
use indexmap::IndexMap;
use std::collections::HashMap;
@ -13,12 +13,13 @@ struct Tool {
comments: Vec<String>,
channel: Channel,
date: Option<String>,
version: [u16; 3],
checksums: IndexMap<String, String>,
}
impl Tool {
fn new() -> Result<Self, Error> {
fn new(date: Option<String>) -> Result<Self, Error> {
let channel = match std::fs::read_to_string("src/ci/channel")?.trim() {
"stable" => Channel::Stable,
"beta" => Channel::Beta,
@ -40,6 +41,7 @@ impl Tool {
Ok(Self {
channel,
version,
date,
config: existing.config,
comments: existing.comments,
checksums: IndexMap::new(),
@ -84,7 +86,7 @@ impl Tool {
Channel::Nightly => "beta".to_string(),
};
let manifest = fetch_manifest(&self.config, &channel)?;
let manifest = fetch_manifest(&self.config, &channel, self.date.as_deref())?;
self.collect_checksums(&manifest, COMPILER_COMPONENTS)?;
Ok(Stage0Toolchain {
date: manifest.date,
@ -110,7 +112,7 @@ impl Tool {
return Ok(None);
}
let manifest = fetch_manifest(&self.config, "nightly")?;
let manifest = fetch_manifest(&self.config, "nightly", self.date.as_deref())?;
self.collect_checksums(&manifest, RUSTFMT_COMPONENTS)?;
Ok(Some(Stage0Toolchain { date: manifest.date, version: "nightly".into() }))
}
@ -141,16 +143,19 @@ impl Tool {
}
fn main() -> Result<(), Error> {
let tool = Tool::new()?;
let tool = Tool::new(std::env::args().nth(1))?;
tool.update_json()?;
Ok(())
}
fn fetch_manifest(config: &Config, channel: &str) -> Result<Manifest, Error> {
Ok(toml::from_slice(&http_get(&format!(
"{}/dist/channel-rust-{}.toml",
config.dist_server, channel
))?)?)
fn fetch_manifest(config: &Config, channel: &str, date: Option<&str>) -> Result<Manifest, Error> {
let url = if let Some(date) = date {
format!("{}/dist/{}/channel-rust-{}.toml", config.dist_server, date, channel)
} else {
format!("{}/dist/channel-rust-{}.toml", config.dist_server, channel)
};
Ok(toml::from_slice(&http_get(&url)?)?)
}
fn http_get(url: &str) -> Result<Vec<u8>, Error> {
@ -164,7 +169,7 @@ fn http_get(url: &str) -> Result<Vec<u8>, Error> {
data.extend_from_slice(new_data);
Ok(new_data.len())
})?;
transfer.perform()?;
transfer.perform().context(format!("failed to fetch {url}"))?;
}
Ok(data)
}

View File

@ -15,6 +15,7 @@
//!
//! A number of these checks can be opted-out of with various directives of the form:
//! `// ignore-tidy-CHECK-NAME`.
// ignore-tidy-dbg
use crate::walk::{filter_dirs, walk};
use regex::{Regex, RegexSet};
@ -278,6 +279,7 @@ pub fn check(path: &Path, bad: &mut bool) {
let mut skip_leading_newlines =
contains_ignore_directive(can_contain, &contents, "leading-newlines");
let mut skip_copyright = contains_ignore_directive(can_contain, &contents, "copyright");
let mut skip_dbg = contains_ignore_directive(can_contain, &contents, "dbg");
let mut leading_new_lines = false;
let mut trailing_new_lines = 0;
let mut lines = 0;
@ -306,6 +308,21 @@ pub fn check(path: &Path, bad: &mut bool) {
let mut err = |msg: &str| {
tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg);
};
if trimmed.contains("dbg!")
&& !trimmed.starts_with("//")
&& !file
.ancestors()
.any(|a| a.ends_with("src/test") || a.ends_with("library/alloc/tests"))
&& filename != "tests.rs"
{
suppressible_tidy_err!(
err,
skip_dbg,
"`dbg!` macro is intended as a debugging tool. It should not be in version control."
)
}
if !under_rustfmt
&& line.chars().count() > max_columns
&& !long_line_is_ok(&extension, is_error_code, max_columns, line)