Skip to content

Commit

Permalink
debug-fmt-detail option
Browse files Browse the repository at this point in the history
Allows disabling `fmt::Debug` derive and debug formatting.
  • Loading branch information
kornelski committed Apr 15, 2024
1 parent 0d8b334 commit bceb534
Show file tree
Hide file tree
Showing 17 changed files with 230 additions and 41 deletions.
6 changes: 5 additions & 1 deletion compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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,
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
Expand Up @@ -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};
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.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),
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 == 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 {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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 @@ -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.
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down
26 changes: 22 additions & 4 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<PathBuf>),
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2968,6 +2985,7 @@ pub(crate) mod dep_tracking {
OutputType,
RealFileName,
LocationDetail,
DebugFmtDetail,
BranchProtection,
OomStrategy,
LanguageIdentifier,
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_session/src/config/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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.
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 @@ -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`";
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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],
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -1227,6 +1228,7 @@ symbols! {
new_binary,
new_const,
new_debug,
new_debug_noop,
new_display,
new_lower_exp,
new_lower_hex,
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 @@ -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)
}
Expand Down
3 changes: 3 additions & 0 deletions tests/ui/check-cfg/well-known-values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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",
Expand Down
Loading

0 comments on commit bceb534

Please sign in to comment.