From bceb5349b20c49d2dc171b54621dbf0e6bb1308f Mon Sep 17 00:00:00 2001 From: Kornel Date: Sun, 14 Apr 2024 13:52:58 +0100 Subject: [PATCH] debug-fmt-detail option Allows disabling `fmt::Debug` derive and debug formatting. --- compiler/rustc_ast_lowering/src/format.rs | 6 +- .../src/deriving/debug.rs | 13 ++++ compiler/rustc_feature/src/builtin_attrs.rs | 1 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_interface/src/tests.rs | 13 ++-- compiler/rustc_session/src/config.rs | 26 +++++-- compiler/rustc_session/src/config/cfg.rs | 17 ++++- compiler/rustc_session/src/options.rs | 14 ++++ compiler/rustc_span/src/symbol.rs | 2 + library/core/src/fmt/rt.rs | 4 ++ tests/ui/check-cfg/well-known-values.rs | 3 + tests/ui/check-cfg/well-known-values.stderr | 67 +++++++++++-------- .../feature-gate-debug-fmt-detail.rs | 5 ++ .../feature-gate-debug-fmt-detail.stderr | 13 ++++ tests/ui/fmt/debug_fmt_detail/full.rs | 15 +++++ tests/ui/fmt/debug_fmt_detail/none.rs | 37 ++++++++++ tests/ui/fmt/debug_fmt_detail/shallow.rs | 33 +++++++++ 17 files changed, 230 insertions(+), 41 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-debug-fmt-detail.rs create mode 100644 tests/ui/feature-gates/feature-gate-debug-fmt-detail.stderr create mode 100644 tests/ui/fmt/debug_fmt_detail/full.rs create mode 100644 tests/ui/fmt/debug_fmt_detail/none.rs create mode 100644 tests/ui/fmt/debug_fmt_detail/shallow.rs diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index d2c3b8b2d5652..498f9cd4c7793 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -5,6 +5,7 @@ use rustc_ast::visit::Visitor; use rustc_ast::*; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; +use rustc_session::config::DebugFmtDetail; use rustc_span::{ sym, symbol::{kw, Ident}, @@ -205,7 +206,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.debug_fmt_detail { + DebugFmtDetail::Full | DebugFmtDetail::Shallow => sym::new_debug, + DebugFmtDetail::None => sym::new_debug_noop, + }, Format(LowerExp) => sym::new_lower_exp, Format(UpperExp) => sym::new_upper_exp, Format(Octal) => sym::new_octal, diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index e442b3520b275..d6aa1da21602f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -4,6 +4,7 @@ use crate::deriving::path_std; use rustc_ast::{self as ast, EnumDef, MetaItem}; use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_session::config::DebugFmtDetail; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use thin_vec::{thin_vec, ThinVec}; @@ -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.debug_fmt_detail; + if fmt_detail == DebugFmtDetail::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), @@ -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 == DebugFmtDetail::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 { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 4f62323231a73..87f3c72176121 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -38,6 +38,7 @@ 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)), + (sym::debug_fmt_detail, sym::debug_fmt_detail, cfg_fn!(debug_fmt_detail)), ]; /// Find a gated cfg determined by the `pred`icate which is given the cfg's name. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e6b19817de385..a3ad72f628747 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -432,6 +432,8 @@ declare_features! ( (unstable, custom_inner_attributes, "1.30.0", Some(54726)), /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. (unstable, custom_test_frameworks, "1.30.0", Some(50297)), + /// Disabling fmt::Debug + (unstable, debug_fmt_detail, "CURRENT_RUSTC_VERSION", Some(123940)), /// Allows declarative macros 2.0 (`macro`). (unstable, decl_macro, "1.17.0", Some(39412)), /// Allows default type parameters to influence type inference. diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d2fb65b5d4f8e..2bc10d307e00d 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -4,12 +4,12 @@ use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::{ build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg, - CollapseMacroDebuginfo, 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, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, - WasiExecModel, + CollapseMacroDebuginfo, CoverageOptions, DebugFmtDetail, DebugInfo, DumpMonoStatsFormat, + ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, + Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, + LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, + PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, + SymbolManglingVersion, WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -762,6 +762,7 @@ fn test_unstable_options_tracking_hash() { tracked!(coverage_options, CoverageOptions { branch: true }); tracked!(crate_attr, vec!["abc".to_string()]); tracked!(cross_crate_inline_threshold, InliningThreshold::Always); + tracked!(debug_fmt_detail, DebugFmtDetail::Full); tracked!(debug_info_for_profiling, true); tracked!(debug_macros, true); tracked!(default_hidden_visibility, Some(true)); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 34acb4ea10f82..f7398b3730459 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -360,6 +360,23 @@ impl LocationDetail { } } +/// Values for the `-Z debug-fmt-detail` flag. +#[derive(Copy, Clone, PartialEq, Hash, Debug)] +pub enum DebugFmtDetail { + /// Derive fully-featured implementation + Full, + /// Print only type name, without fields + Shallow, + /// `#[derive(Debug)]` and `{:?}` are no-ops + None, +} + +impl DebugFmtDetail { + pub(crate) fn all() -> [&'static str; 3] { + ["full", "none", "shallow"] + } +} + #[derive(Clone, PartialEq, Hash, Debug)] pub enum SwitchWithOptPath { Enabled(Option), @@ -2863,10 +2880,10 @@ pub enum WasiExecModel { pub(crate) mod dep_tracking { use super::{ BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions, - CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn, - InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, - LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, - Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, + CrateType, DebugFmtDetail, DebugInfo, DebugInfoCompression, ErrorOutputType, + FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, + LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, + OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use crate::lint; @@ -2968,6 +2985,7 @@ pub(crate) mod dep_tracking { OutputType, RealFileName, LocationDetail, + DebugFmtDetail, BranchProtection, OomStrategy, LanguageIdentifier, diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 34dcd0cf598ff..11d32562f2fd6 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -25,7 +25,7 @@ use rustc_target::abi::Align; use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet}; use rustc_target::spec::{Target, TargetTriple, TARGETS}; -use crate::config::CrateType; +use crate::config::{CrateType, DebugFmtDetail}; use crate::Session; use std::hash::Hash; @@ -115,6 +115,18 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg { ins_none!(sym::debug_assertions); } + match sess.opts.unstable_opts.debug_fmt_detail { + DebugFmtDetail::Full => { + ins_str!(sym::debug_fmt_detail, "full"); + } + DebugFmtDetail::Shallow => { + ins_str!(sym::debug_fmt_detail, "shallow"); + } + DebugFmtDetail::None => { + ins_str!(sym::debug_fmt_detail, "none"); + } + } + if sess.overflow_checks() { ins_none!(sym::overflow_checks); } @@ -262,6 +274,9 @@ impl CheckCfg { ins!(sym::debug_assertions, no_values); + ins!(sym::debug_fmt_detail, empty_values) + .extend(DebugFmtDetail::all().into_iter().map(Symbol::intern)); + // These four are never set by rustc, but we set them anyway: they // should not trigger a lint because `cargo clippy`, `cargo doc`, // `cargo test` and `cargo miri run` (respectively) can set them. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 963c9558c170c..137a9e98f9ee4 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -406,6 +406,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_debug_fmt_detail: &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`"; @@ -585,6 +586,16 @@ mod parse { } } + pub(crate) fn parse_debug_fmt_detail(opt: &mut DebugFmtDetail, v: Option<&str>) -> bool { + *opt = match v { + Some("full") => DebugFmtDetail::Full, + Some("shallow") => DebugFmtDetail::Shallow, + Some("none") => DebugFmtDetail::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; @@ -1606,6 +1617,9 @@ options! { "inject the given attribute in the crate"), cross_crate_inline_threshold: InliningThreshold = (InliningThreshold::Sometimes(100), parse_inlining_threshold, [TRACKED], "threshold to allow cross crate inlining of functions"), + debug_fmt_detail: DebugFmtDetail = (DebugFmtDetail::Full, parse_debug_fmt_detail, [TRACKED], + "how detailed `#[derive(Debug)]` should be. `full` prints types recursively, \ + `shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"), debug_info_for_profiling: bool = (false, parse_bool, [TRACKED], "emit discriminators and other data necessary for AutoFDO"), debug_macros: bool = (false, parse_bool, [TRACKED], diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index bfd0f77c237b2..a6022305d1918 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -658,6 +658,7 @@ symbols! { debug_assert_macro, debug_assert_ne_macro, debug_assertions, + debug_fmt_detail, debug_struct, debug_struct_fields_finish, debug_tuple, @@ -1227,6 +1228,7 @@ symbols! { new_binary, new_const, new_debug, + new_debug_noop, new_display, new_lower_exp, new_lower_hex, diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 5e4dac8f49b6c..c09ede9ce320a 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -117,6 +117,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) } diff --git a/tests/ui/check-cfg/well-known-values.rs b/tests/ui/check-cfg/well-known-values.rs index 2758a793538ee..de16865700655 100644 --- a/tests/ui/check-cfg/well-known-values.rs +++ b/tests/ui/check-cfg/well-known-values.rs @@ -15,6 +15,7 @@ #![feature(cfg_target_has_atomic_equal_alignment)] #![feature(cfg_target_thread_local)] #![feature(cfg_ub_checks)] +#![feature(debug_fmt_detail)] // This part makes sure that none of the well known names are // unexpected. @@ -28,6 +29,8 @@ //~^ WARN unexpected `cfg` condition value debug_assertions = "_UNEXPECTED_VALUE", //~^ WARN unexpected `cfg` condition value + debug_fmt_detail = "_UNEXPECTED_VALUE", + //~^ WARN unexpected `cfg` condition value doc = "_UNEXPECTED_VALUE", //~^ WARN unexpected `cfg` condition value doctest = "_UNEXPECTED_VALUE", diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 729794150f62b..2bc417ceaa03c 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:27:5 + --> $DIR/well-known-values.rs:28:5 | LL | clippy = "_UNEXPECTED_VALUE", | ^^^^^^---------------------- @@ -11,7 +11,7 @@ LL | clippy = "_UNEXPECTED_VALUE", = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:29:5 + --> $DIR/well-known-values.rs:30:5 | LL | debug_assertions = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^---------------------- @@ -22,7 +22,16 @@ LL | debug_assertions = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:31:5 + --> $DIR/well-known-values.rs:32:5 + | +LL | debug_fmt_detail = "_UNEXPECTED_VALUE", + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected values for `debug_fmt_detail` are: `full`, `none`, `shallow` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` + --> $DIR/well-known-values.rs:34:5 | LL | doc = "_UNEXPECTED_VALUE", | ^^^---------------------- @@ -33,7 +42,7 @@ LL | doc = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:33:5 + --> $DIR/well-known-values.rs:36:5 | LL | doctest = "_UNEXPECTED_VALUE", | ^^^^^^^---------------------- @@ -44,7 +53,7 @@ LL | doctest = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:35:5 + --> $DIR/well-known-values.rs:38:5 | LL | miri = "_UNEXPECTED_VALUE", | ^^^^---------------------- @@ -55,7 +64,7 @@ LL | miri = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:37:5 + --> $DIR/well-known-values.rs:40:5 | LL | overflow_checks = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^---------------------- @@ -66,7 +75,7 @@ LL | overflow_checks = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:39:5 + --> $DIR/well-known-values.rs:42:5 | LL | panic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -75,7 +84,7 @@ LL | panic = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:41:5 + --> $DIR/well-known-values.rs:44:5 | LL | proc_macro = "_UNEXPECTED_VALUE", | ^^^^^^^^^^---------------------- @@ -86,7 +95,7 @@ LL | proc_macro = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:43:5 + --> $DIR/well-known-values.rs:46:5 | LL | relocation_model = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -95,7 +104,7 @@ LL | relocation_model = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:45:5 + --> $DIR/well-known-values.rs:48:5 | LL | sanitize = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +113,7 @@ LL | sanitize = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:47:5 + --> $DIR/well-known-values.rs:50:5 | LL | target_abi = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +122,7 @@ LL | target_abi = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:49:5 + --> $DIR/well-known-values.rs:52:5 | LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +131,7 @@ LL | target_arch = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:51:5 + --> $DIR/well-known-values.rs:54:5 | LL | target_endian = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -131,7 +140,7 @@ LL | target_endian = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:53:5 + --> $DIR/well-known-values.rs:56:5 | LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -140,7 +149,7 @@ LL | target_env = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:55:5 + --> $DIR/well-known-values.rs:58:5 | LL | target_family = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +158,7 @@ LL | target_family = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:57:5 + --> $DIR/well-known-values.rs:60:5 | LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,7 +167,7 @@ LL | target_feature = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:59:5 + --> $DIR/well-known-values.rs:62:5 | LL | target_has_atomic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,7 +176,7 @@ LL | target_has_atomic = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:61:5 + --> $DIR/well-known-values.rs:64:5 | LL | target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -176,7 +185,7 @@ LL | target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:63:5 + --> $DIR/well-known-values.rs:66:5 | LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +194,7 @@ LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:65:5 + --> $DIR/well-known-values.rs:68:5 | LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -194,7 +203,7 @@ LL | target_os = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:67:5 + --> $DIR/well-known-values.rs:70:5 | LL | target_pointer_width = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -203,7 +212,7 @@ LL | target_pointer_width = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:69:5 + --> $DIR/well-known-values.rs:72:5 | LL | target_thread_local = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^---------------------- @@ -214,7 +223,7 @@ LL | target_thread_local = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:71:5 + --> $DIR/well-known-values.rs:74:5 | LL | target_vendor = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +232,7 @@ LL | target_vendor = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:73:5 + --> $DIR/well-known-values.rs:76:5 | LL | test = "_UNEXPECTED_VALUE", | ^^^^---------------------- @@ -234,7 +243,7 @@ LL | test = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:75:5 + --> $DIR/well-known-values.rs:78:5 | LL | ub_checks = "_UNEXPECTED_VALUE", | ^^^^^^^^^---------------------- @@ -245,7 +254,7 @@ LL | ub_checks = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:77:5 + --> $DIR/well-known-values.rs:80:5 | LL | unix = "_UNEXPECTED_VALUE", | ^^^^---------------------- @@ -256,7 +265,7 @@ LL | unix = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:79:5 + --> $DIR/well-known-values.rs:82:5 | LL | windows = "_UNEXPECTED_VALUE", | ^^^^^^^---------------------- @@ -267,7 +276,7 @@ LL | windows = "_UNEXPECTED_VALUE", = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `linuz` - --> $DIR/well-known-values.rs:85:7 + --> $DIR/well-known-values.rs:88:7 | LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | ^^^^^^^^^^^^------- @@ -277,5 +286,5 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm` = note: see for more information about checking conditional configuration -warning: 28 warnings emitted +warning: 29 warnings emitted diff --git a/tests/ui/feature-gates/feature-gate-debug-fmt-detail.rs b/tests/ui/feature-gates/feature-gate-debug-fmt-detail.rs new file mode 100644 index 0000000000000..961eb99df7750 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-debug-fmt-detail.rs @@ -0,0 +1,5 @@ +#[cfg(debug_fmt_detail = "full")] +//~^ ERROR is experimental +fn main() { + +} diff --git a/tests/ui/feature-gates/feature-gate-debug-fmt-detail.stderr b/tests/ui/feature-gates/feature-gate-debug-fmt-detail.stderr new file mode 100644 index 0000000000000..6f07ac4408b5c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-debug-fmt-detail.stderr @@ -0,0 +1,13 @@ +error[E0658]: `cfg(debug_fmt_detail)` is experimental and subject to change + --> $DIR/feature-gate-debug-fmt-detail.rs:1:7 + | +LL | #[cfg(debug_fmt_detail = "full")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #123940 for more information + = help: add `#![feature(debug_fmt_detail)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/fmt/debug_fmt_detail/full.rs b/tests/ui/fmt/debug_fmt_detail/full.rs new file mode 100644 index 0000000000000..2e8e3aaa8699d --- /dev/null +++ b/tests/ui/fmt/debug_fmt_detail/full.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -Zdebug-fmt-detail=full +//@ run-pass +#![feature(debug_fmt_detail)] +#![allow(dead_code)] +#![allow(unused)] + +#[derive(Debug)] +struct Foo { + bar: u32, +} + +fn main() { + let s = format!("Still works: {:?} '{:?}'", cfg!(debug_fmt_detail = "full"), Foo { bar: 1 }); + assert_eq!("Still works: true 'Foo { bar: 1 }'", s); +} diff --git a/tests/ui/fmt/debug_fmt_detail/none.rs b/tests/ui/fmt/debug_fmt_detail/none.rs new file mode 100644 index 0000000000000..80d13f78e128b --- /dev/null +++ b/tests/ui/fmt/debug_fmt_detail/none.rs @@ -0,0 +1,37 @@ +//@ compile-flags: -Zdebug-fmt-detail=none +//@ run-pass +#![feature(debug_fmt_detail)] +#![allow(dead_code)] +#![allow(unused)] + +#[derive(Debug)] +struct Foo { + bar: u32, +} + +#[derive(Debug)] +enum Baz { + Quz, +} + +#[cfg(debug_fmt_detail = "full")] +compile_error!("nope"); + +#[cfg(debug_fmt_detail = "none")] +struct Custom; + +impl std::fmt::Debug for Custom { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("custom_fmt") + } +} + +fn main() { + let c = Custom; + let s = format!("Debug is '{:?}', '{:#?}', and '{c:?}'", Foo { bar: 1 }, Baz::Quz); + assert_eq!("Debug is '', '', and ''", s); + + let f = 3.0; + let s = format_args!("{:?}x{:#?}y{f:?}", 1234, "can't debug this").to_string(); + assert_eq!("xy", s); +} diff --git a/tests/ui/fmt/debug_fmt_detail/shallow.rs b/tests/ui/fmt/debug_fmt_detail/shallow.rs new file mode 100644 index 0000000000000..027449109aa69 --- /dev/null +++ b/tests/ui/fmt/debug_fmt_detail/shallow.rs @@ -0,0 +1,33 @@ +//@ compile-flags: -Zdebug-fmt-detail=shallow +//@ run-pass +#![feature(debug_fmt_detail)] +#![allow(dead_code)] +#![allow(unused)] + +#[derive(Debug)] +struct Foo { + bar: u32, + bomb: Bomb, +} + +#[derive(Debug)] +enum Baz { + Quz, +} + +struct Bomb; + +impl std::fmt::Debug for Bomb { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + panic!() + } +} + +fn main() { + let s = format!("Debug is '{:?}' and '{:#?}'", Foo { bar: 1, bomb: Bomb }, Baz::Quz); + assert_eq!("Debug is 'Foo' and 'Quz'", s); + + let f = 3.0; + let s = format_args!("{:?}{:#?}{f:?}", 1234, cfg!(debug_fmt_detail = "shallow")).to_string(); + assert_eq!("1234true3.0", s); +}