Skip to content

Commit

Permalink
Unrolled build for rust-lang#123940
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#123940 - kornelski:remove-derived-debug, r=Urgau

debug-fmt-detail option

I'd like to propose a new option that makes `#[derive(Debug)]` generate no-op implementations that don't print anything, and makes `{:?}` in format strings a no-op.

There are a couple of motivations for this:

1. A more thorough stripping of debug symbols. Binaries stripped of debug symbols still retain some of them through `Debug` implementations. It's hard to avoid that without compiler's help, because debug formatting can be used in many places, including dependencies, and their loggers, asserts, panics, etc.
   * In my testing it gives about 2% binary size reduction on top of all other binary-minimizing best practices (including `panic_immediate_abort`). There are targets like Web WASM or embedded where users pay attention to binary sizes.
   * Users distributing closed-source binaries may not want to "leak" any symbol names as a matter of principle.
2. Adds ability to test whether code depends on specifics of the `Debug` format implementation in unwise ways (e.g. trying to get data unavailable via public interface, or using it as a serialization format). Because current Rust's debug implementation doesn't change, there's a risk of it becoming a fragile de-facto API that [won't be possible to change in the future](https://www.hyrumslaw.com/). An option that "breaks" it can act as a [grease](https://www.rfc-editor.org/rfc/rfc8701.html).

This implementation is a `-Z fmt-debug=opt` flag that takes:

* `full` — the default, current state.
* `none` — makes derived `Debug` and `{:?}` no-ops. Explicit `impl Debug for T` implementations are left unharmed, but `{:?}` format won't use them, so they may get dead-code eliminated if they aren't invoked directly.
* `shallow` — makes derived `Debug` print only the type's name, without recursing into fields. Fieldless enums print their variant names. `{:?}` works.

The `shallow` option is a compromise between minimizing the `Debug` code, and compatibility. There are popular proc-macro crates that use `Debug::fmt` as a way to convert enum values into their Rust source code.

There's a corresponding `cfg` flag: `#[cfg(fmt_debug = "none")]` that can be used in user code to react to this setting to minimize custom `Debug` implementations or remove unnecessary formatting helper functions.
  • Loading branch information
rust-timer authored Aug 29, 2024
2 parents 784d444 + 88b9edc commit 56eadd5
Show file tree
Hide file tree
Showing 38 changed files with 285 additions and 56 deletions.
8 changes: 6 additions & 2 deletions compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use std::borrow::Cow;
use rustc_ast::visit::Visitor;
use rustc_ast::*;
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir as hir;
use rustc_session::config::FmtDebug;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{sym, Span, Symbol};
use {rustc_ast as ast, rustc_hir as hir};

use super::LoweringContext;

Expand Down Expand Up @@ -243,7 +244,10 @@ fn make_argument<'hir>(
hir::LangItem::FormatArgument,
match ty {
Format(Display) => sym::new_display,
Format(Debug) => sym::new_debug,
Format(Debug) => match ctx.tcx.sess.opts.unstable_opts.fmt_debug {
FmtDebug::Full | FmtDebug::Shallow => sym::new_debug,
FmtDebug::None => sym::new_debug_noop,
},
Format(LowerExp) => sym::new_lower_exp,
Format(UpperExp) => sym::new_upper_exp,
Format(Octal) => sym::new_octal,
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_ast::{self as ast, EnumDef, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_session::config::FmtDebug;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
Expand Down Expand Up @@ -49,6 +50,11 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
// We want to make sure we have the ctxt set so that we can use unstable methods
let span = cx.with_def_site_ctxt(span);

let fmt_detail = cx.sess.opts.unstable_opts.fmt_debug;
if fmt_detail == FmtDebug::None {
return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new())));
}

let (ident, vdata, fields) = match substr.fields {
Struct(vdata, fields) => (substr.type_ident, *vdata, fields),
EnumMatching(_, v, fields) => (v.ident, &v.data, fields),
Expand All @@ -61,6 +67,13 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
let name = cx.expr_str(span, ident.name);
let fmt = substr.nonselflike_args[0].clone();

// Fieldless enums have been special-cased earlier
if fmt_detail == FmtDebug::Shallow {
let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
let expr = cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]);
return BlockOrExpr::new_expr(expr);
}

// Struct and tuples are similar enough that we use the same code for both,
// with some extra pieces for structs due to the field names.
let (is_struct, args_per_field) = match vdata {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const GATED_CFGS: &[GatedCfg] = &[
(sym::relocation_model, sym::cfg_relocation_model, cfg_fn!(cfg_relocation_model)),
(sym::sanitizer_cfi_generalize_pointers, sym::cfg_sanitizer_cfi, cfg_fn!(cfg_sanitizer_cfi)),
(sym::sanitizer_cfi_normalize_integers, sym::cfg_sanitizer_cfi, cfg_fn!(cfg_sanitizer_cfi)),
// this is consistent with naming of the compiler flag it's for
(sym::fmt_debug, sym::fmt_debug, cfg_fn!(fmt_debug)),
];

/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ declare_features! (
(unstable, ffi_const, "1.45.0", Some(58328)),
/// Allows the use of `#[ffi_pure]` on foreign functions.
(unstable, ffi_pure, "1.45.0", Some(58329)),
/// Controlling the behavior of fmt::Debug
(unstable, fmt_debug, "CURRENT_RUSTC_VERSION", Some(129709)),
/// Allows using `#[repr(align(...))]` on function items
(unstable, fn_align, "1.53.0", Some(82232)),
/// Support delegating implementation of functions to other already implemented functions.
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ use rustc_errors::{registry, ColorConfig};
use rustc_session::config::{
build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat,
ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold,
Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail,
LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey,
PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip,
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
ErrorOutputType, ExternEntry, ExternLocation, Externs, FmtDebug, FunctionReturn,
InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained,
LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName,
OutputType, OutputTypes, PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius,
ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
Expand Down Expand Up @@ -780,6 +780,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(fewer_names, Some(true));
tracked!(fixed_x18, true);
tracked!(flatten_format_args, false);
tracked!(fmt_debug, FmtDebug::Shallow);
tracked!(force_unstable_if_unmarked, true);
tracked!(fuel, Some(("abc".to_string(), 99)));
tracked!(function_return, FunctionReturn::ThunkExtern);
Expand Down
24 changes: 22 additions & 2 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ use rustc_feature::UnstableFeatures;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
use rustc_span::source_map::FilePathMapping;
use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
use rustc_span::{
sym, FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol,
};
use rustc_target::spec::{
FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTriple,
};
Expand Down Expand Up @@ -402,6 +404,23 @@ impl LocationDetail {
}
}

/// Values for the `-Z fmt-debug` flag.
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
pub enum FmtDebug {
/// Derive fully-featured implementation
Full,
/// Print only type name, without fields
Shallow,
/// `#[derive(Debug)]` and `{:?}` are no-ops
None,
}

impl FmtDebug {
pub(crate) fn all() -> [Symbol; 3] {
[sym::full, sym::none, sym::shallow]
}
}

#[derive(Clone, PartialEq, Hash, Debug)]
pub enum SwitchWithOptPath {
Enabled(Option<PathBuf>),
Expand Down Expand Up @@ -2994,7 +3013,7 @@ pub(crate) mod dep_tracking {

use super::{
BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks,
Expand Down Expand Up @@ -3088,6 +3107,7 @@ pub(crate) mod dep_tracking {
OutputType,
RealFileName,
LocationDetail,
FmtDebug,
BranchProtection,
OomStrategy,
LanguageIdentifier,
Expand Down
19 changes: 18 additions & 1 deletion compiler/rustc_session/src/config/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::Align;
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, Target, TargetTriple, TARGETS};

use crate::config::CrateType;
use crate::config::{CrateType, FmtDebug};
use crate::Session;

/// The parsed `--cfg` options that define the compilation environment of the
Expand Down Expand Up @@ -142,6 +142,7 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
| (sym::target_has_atomic_equal_alignment, Some(_))
| (sym::target_has_atomic_load_store, Some(_))
| (sym::target_thread_local, None) => disallow(cfg, "--target"),
(sym::fmt_debug, None | Some(_)) => disallow(cfg, "-Z fmt-debug"),
_ => {}
}
}
Expand Down Expand Up @@ -179,6 +180,20 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
ins_none!(sym::debug_assertions);
}

if sess.is_nightly_build() {
match sess.opts.unstable_opts.fmt_debug {
FmtDebug::Full => {
ins_sym!(sym::fmt_debug, sym::full);
}
FmtDebug::Shallow => {
ins_sym!(sym::fmt_debug, sym::shallow);
}
FmtDebug::None => {
ins_sym!(sym::fmt_debug, sym::none);
}
}
}

if sess.overflow_checks() {
ins_none!(sym::overflow_checks);
}
Expand Down Expand Up @@ -326,6 +341,8 @@ impl CheckCfg {

ins!(sym::debug_assertions, no_values);

ins!(sym::fmt_debug, empty_values).extend(FmtDebug::all());

// These four are never set by rustc, but we set them anyway; they
// should not trigger the lint because `cargo clippy`, `cargo doc`,
// `cargo test`, `cargo miri run` and `cargo fmt` (respectively)
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ mod desc {
pub const parse_linker_plugin_lto: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), or the path to the linker plugin";
pub const parse_location_detail: &str = "either `none`, or a comma separated list of location details to track: `file`, `line`, or `column`";
pub const parse_fmt_debug: &str = "either `full`, `shallow`, or `none`";
pub const parse_switch_with_opt_path: &str =
"an optional path to the profiling data output directory";
pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`";
Expand Down Expand Up @@ -589,6 +590,16 @@ mod parse {
}
}

pub(crate) fn parse_fmt_debug(opt: &mut FmtDebug, v: Option<&str>) -> bool {
*opt = match v {
Some("full") => FmtDebug::Full,
Some("shallow") => FmtDebug::Shallow,
Some("none") => FmtDebug::None,
_ => return false,
};
true
}

pub(crate) fn parse_location_detail(ld: &mut LocationDetail, v: Option<&str>) -> bool {
if let Some(v) = v {
ld.line = false;
Expand Down Expand Up @@ -1724,6 +1735,9 @@ options! {
flatten_format_args: bool = (true, parse_bool, [TRACKED],
"flatten nested format_args!() and literals into a simplified format_args!() call \
(default: yes)"),
fmt_debug: FmtDebug = (FmtDebug::Full, parse_fmt_debug, [TRACKED],
"how detailed `#[derive(Debug)]` should be. `full` prints types recursively, \
`shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"),
force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
"force all crates to be `rustc_private` unstable (default: no)"),
fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ symbols! {
cfg_attr_multi,
cfg_doctest,
cfg_eval,
cfg_fmt_debug,
cfg_hide,
cfg_overflow_checks,
cfg_panic,
Expand Down Expand Up @@ -895,6 +896,7 @@ symbols! {
fmaf32,
fmaf64,
fmt,
fmt_debug,
fmul_algebraic,
fmul_fast,
fn_align,
Expand Down Expand Up @@ -938,6 +940,7 @@ symbols! {
fs_create_dir,
fsub_algebraic,
fsub_fast,
full,
fundamental,
fused_iterator,
future,
Expand Down Expand Up @@ -1281,6 +1284,7 @@ symbols! {
new_binary,
new_const,
new_debug,
new_debug_noop,
new_display,
new_lower_exp,
new_lower_hex,
Expand Down Expand Up @@ -1715,6 +1719,7 @@ symbols! {
semitransparent,
sha512_sm_x86,
shadow_call_stack,
shallow,
shl,
shl_assign,
shorter_tail_lifetimes,
Expand Down
4 changes: 4 additions & 0 deletions library/core/src/fmt/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ impl<'a> Argument<'a> {
Self::new(x, Debug::fmt)
}
#[inline(always)]
pub fn new_debug_noop<'b, T: Debug>(x: &'b T) -> Argument<'_> {
Self::new(x, |_, _| Ok(()))
}
#[inline(always)]
pub fn new_octal<'b, T: Octal>(x: &'b T) -> Argument<'_> {
Self::new(x, Octal::fmt)
}
Expand Down
3 changes: 2 additions & 1 deletion src/doc/rustc/src/check-cfg.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,15 @@ the need to specify them manually.
Well known names and values are implicitly added as long as at least one `--check-cfg` argument
is present.
As of `2024-05-06T`, the list of known names is as follows:
As of `2024-08-20T`, the list of known names is as follows:
<!--- See CheckCfg::fill_well_known in compiler/rustc_session/src/config.rs -->
- `clippy`
- `debug_assertions`
- `doc`
- `doctest`
- `fmt_debug`
- `miri`
- `overflow_checks`
- `panic`
Expand Down
15 changes: 15 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/fmt-debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# `fmt-debug`

The tracking issue for this feature is: [#129709](https://github.com/rust-lang/rust/issues/129709).

------------------------

Option `-Z fmt-debug=val` controls verbosity of derived `Debug` implementations
and debug formatting in format strings (`{:?}`).

* `full``#[derive(Debug)]` prints types recursively. This is the default behavior.

* `shallow``#[derive(Debug)]` prints only the type name, or name of a variant of a fieldless enums. Details of the `Debug` implementation are not stable and may change in the future. Behavior of custom `fmt::Debug` implementations is not affected.

* `none``#[derive(Debug)]` does not print anything at all. `{:?}` in formatting strings has no effect.
This option may reduce size of binaries, and remove occurrences of type names in the binary that are not removed by striping symbols. However, it may also cause `panic!` and `assert!` messages to be incomplete.
8 changes: 8 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.fmt_debug_.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: unexpected `--cfg fmt_debug="shallow"` flag
|
= note: config `fmt_debug` is only supposed to be controlled by `-Z fmt-debug`
= note: manually setting a built-in cfg can and does create incoherent behaviors
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default

error: aborting due to 1 previous error

2 changes: 2 additions & 0 deletions tests/ui/cfg/disallowed-cli-cfgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//@ revisions: target_pointer_width_ target_vendor_ target_has_atomic_
//@ revisions: target_has_atomic_equal_alignment_ target_has_atomic_load_store_
//@ revisions: target_thread_local_ relocation_model_
//@ revisions: fmt_debug_

//@ [overflow_checks_]compile-flags: --cfg overflow_checks
//@ [debug_assertions_]compile-flags: --cfg debug_assertions
Expand All @@ -31,5 +32,6 @@
//@ [target_has_atomic_load_store_]compile-flags: --cfg target_has_atomic_load_store="32"
//@ [target_thread_local_]compile-flags: --cfg target_thread_local
//@ [relocation_model_]compile-flags: --cfg relocation_model="a"
//@ [fmt_debug_]compile-flags: --cfg fmt_debug="shallow"

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui/check-cfg/allow-same-level.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `FALSE`
LL | #[cfg(FALSE)]
| ^^^^^
|
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
= help: to expect this configuration use `--check-cfg=cfg(FALSE)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/check-cfg/cargo-build-script.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `has_foo`
LL | #[cfg(has_foo)]
| ^^^^^^^
|
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `has_bar`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `fmt_debug`, `has_bar`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/check-cfg/cargo-feature.none.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ warning: unexpected `cfg` condition name: `tokio_unstable`
LL | #[cfg(tokio_unstable)]
| ^^^^^^^^^^^^^^
|
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
Expand Down
Loading

0 comments on commit 56eadd5

Please sign in to comment.