From 123693953f6fb4063f95bd59b288aea8375c3c34 Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 11 Jun 2023 10:13:02 -0500 Subject: [PATCH] Don't override `debuginfo-level = 1` to mean `line-tables-only` This has real differences in the effective debuginfo: in particular, it omits the module-level information and breaks perf. Allow passing `line-tables-only` directly in config.toml instead. --- src/bootstrap/builder.rs | 7 +--- src/bootstrap/config.rs | 86 +++++++++++++++++++++++++++++++++------- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index ea1b34812e5ca..51d94c48f7ffb 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1649,12 +1649,7 @@ impl<'a> Builder<'a> { self.config.rust_debuginfo_level_tools } }; - if debuginfo_level == 1 { - // Use less debuginfo than the default to save on disk space. - cargo.env(profile_var("DEBUG"), "line-tables-only"); - } else { - cargo.env(profile_var("DEBUG"), debuginfo_level.to_string()); - }; + cargo.env(profile_var("DEBUG"), debuginfo_level.to_string()); if self.cc[&target].args().iter().any(|arg| arg == "-gz") { rustflags.arg("-Clink-arg=-gz"); } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index c59df7eecf680..b521ad75d63a1 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -10,7 +10,7 @@ use std::cell::{Cell, RefCell}; use std::cmp; use std::collections::{HashMap, HashSet}; use std::env; -use std::fmt; +use std::fmt::{self, Display}; use std::fs; use std::io::IsTerminal; use std::path::{Path, PathBuf}; @@ -50,6 +50,57 @@ pub enum DryRun { UserSelected, } +#[derive(Copy, Clone, Default)] +pub enum DebuginfoLevel { + #[default] + None, + LineTablesOnly, + Limited, + Full, +} + +// NOTE: can't derive(Deserialize) because the intermediate trip through toml::Value only +// deserializes i64, and derive() only generates visit_u64 +impl<'de> Deserialize<'de> for DebuginfoLevel { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + use serde::de::Error; + + Ok(match Deserialize::deserialize(deserializer)? { + StringOrInt::String("none") | StringOrInt::Int(0) => DebuginfoLevel::None, + StringOrInt::String("line-tables-only") => DebuginfoLevel::LineTablesOnly, + StringOrInt::String("limited") | StringOrInt::Int(1) => DebuginfoLevel::Limited, + StringOrInt::String("full") | StringOrInt::Int(2) => DebuginfoLevel::Full, + StringOrInt::Int(n) => { + let other = serde::de::Unexpected::Signed(n); + return Err(D::Error::invalid_value(other, &"expected 0, 1, or 2")); + } + StringOrInt::String(s) => { + let other = serde::de::Unexpected::Str(s); + return Err(D::Error::invalid_value( + other, + &"expected none, line-tables-only, limited, or full", + )); + } + }) + } +} + +/// Suitable for passing to `-C debuginfo` +impl Display for DebuginfoLevel { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use DebuginfoLevel::*; + f.write_str(match self { + None => "0", + LineTablesOnly => "line-tables-only", + Limited => "1", + Full => "2", + }) + } +} + /// Global configuration for the entire build and/or bootstrap. /// /// This structure is parsed from `config.toml`, and some of the fields are inferred from `git` or build-time parameters. @@ -159,10 +210,10 @@ pub struct Config { pub rust_overflow_checks: bool, pub rust_overflow_checks_std: bool, pub rust_debug_logging: bool, - pub rust_debuginfo_level_rustc: u32, - pub rust_debuginfo_level_std: u32, - pub rust_debuginfo_level_tools: u32, - pub rust_debuginfo_level_tests: u32, + pub rust_debuginfo_level_rustc: DebuginfoLevel, + pub rust_debuginfo_level_std: DebuginfoLevel, + pub rust_debuginfo_level_tools: DebuginfoLevel, + pub rust_debuginfo_level_tests: DebuginfoLevel, pub rust_split_debuginfo: SplitDebuginfo, pub rust_rpath: bool, pub rustc_parallel: bool, @@ -810,6 +861,13 @@ impl Default for StringOrBool { } } +#[derive(Deserialize)] +#[serde(untagged)] +enum StringOrInt<'a> { + String(&'a str), + Int(i64), +} + define_config! { /// TOML representation of how the Rust build is configured. struct Rust { @@ -822,11 +880,11 @@ define_config! { overflow_checks: Option = "overflow-checks", overflow_checks_std: Option = "overflow-checks-std", debug_logging: Option = "debug-logging", - debuginfo_level: Option = "debuginfo-level", - debuginfo_level_rustc: Option = "debuginfo-level-rustc", - debuginfo_level_std: Option = "debuginfo-level-std", - debuginfo_level_tools: Option = "debuginfo-level-tools", - debuginfo_level_tests: Option = "debuginfo-level-tests", + debuginfo_level: Option = "debuginfo-level", + debuginfo_level_rustc: Option = "debuginfo-level-rustc", + debuginfo_level_std: Option = "debuginfo-level-std", + debuginfo_level_tools: Option = "debuginfo-level-tools", + debuginfo_level_tests: Option = "debuginfo-level-tests", split_debuginfo: Option = "split-debuginfo", run_dsymutil: Option = "run-dsymutil", backtrace: Option = "backtrace", @@ -1478,17 +1536,17 @@ impl Config { config.rust_debug_logging = debug_logging.unwrap_or(config.rust_debug_assertions); - let with_defaults = |debuginfo_level_specific: Option| { + let with_defaults = |debuginfo_level_specific: Option<_>| { debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) { - 1 + DebuginfoLevel::Limited } else { - 0 + DebuginfoLevel::None }) }; config.rust_debuginfo_level_rustc = with_defaults(debuginfo_level_rustc); config.rust_debuginfo_level_std = with_defaults(debuginfo_level_std); config.rust_debuginfo_level_tools = with_defaults(debuginfo_level_tools); - config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(0); + config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None); let download_rustc = config.download_rustc_commit.is_some(); // See https://github.com/rust-lang/compiler-team/issues/326