Skip to content

Commit 37998ab

Browse files
committed
Auto merge of #112530 - matthiaskrgr:rollup-qee1kc1, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - #112487 (Update documentation for `tools` defaults) - #112513 (Dont compute `opt_suggest_box_span` span for TAIT) - #112528 (bootstrap: Don't override `debuginfo-level = 1` to mean `line-tables-only`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 81c02da + c1f2da5 commit 37998ab

File tree

9 files changed

+139
-130
lines changed

9 files changed

+139
-130
lines changed

compiler/rustc_hir_typeck/src/_match.rs

+8
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
510510
..
511511
} = self.type_var_origin(expected)? else { return None; };
512512

513+
let Some(rpit_local_def_id) = rpit_def_id.as_local() else { return None; };
514+
if !matches!(
515+
self.tcx.hir().expect_item(rpit_local_def_id).expect_opaque_ty().origin,
516+
hir::OpaqueTyOrigin::FnReturn(..)
517+
) {
518+
return None;
519+
}
520+
513521
let sig = self.body_fn_sig()?;
514522

515523
let substs = sig.output().walk().find_map(|arg| {

compiler/rustc_hir_typeck/src/coercion.rs

+4-109
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@
3636
//! ```
3737
3838
use crate::FnCtxt;
39-
use rustc_errors::{
40-
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
41-
};
39+
use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
4240
use rustc_hir as hir;
4341
use rustc_hir::def_id::DefId;
4442
use rustc_hir::intravisit::{self, Visitor};
@@ -58,7 +56,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
5856
use rustc_middle::ty::{self, Ty, TypeAndMut};
5957
use rustc_session::parse::feature_err;
6058
use rustc_span::symbol::sym;
61-
use rustc_span::{self, BytePos, DesugaringKind, Span};
59+
use rustc_span::{self, DesugaringKind};
6260
use rustc_target::spec::abi::Abi;
6361
use rustc_trait_selection::infer::InferCtxtExt as _;
6462
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
@@ -1702,9 +1700,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
17021700
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
17031701
let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err);
17041702

1705-
let mut pointing_at_return_type = false;
1706-
let mut fn_output = None;
1707-
17081703
let parent_id = fcx.tcx.hir().parent_id(id);
17091704
let parent = fcx.tcx.hir().get(parent_id);
17101705
if let Some(expr) = expression
@@ -1717,7 +1712,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
17171712
// label pointing out the cause for the type coercion will be wrong
17181713
// as prior return coercions would not be relevant (#57664).
17191714
let fn_decl = if let (Some(expr), Some(blk_id)) = (expression, blk_id) {
1720-
pointing_at_return_type =
1715+
let pointing_at_return_type =
17211716
fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id);
17221717
if let (Some(cond_expr), true, false) = (
17231718
fcx.tcx.hir().get_if_cause(expr.hir_id),
@@ -1749,7 +1744,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
17491744

17501745
if let Some((fn_id, fn_decl, can_suggest)) = fn_decl {
17511746
if blk_id.is_none() {
1752-
pointing_at_return_type |= fcx.suggest_missing_return_type(
1747+
fcx.suggest_missing_return_type(
17531748
&mut err,
17541749
&fn_decl,
17551750
expected,
@@ -1758,9 +1753,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
17581753
fn_id,
17591754
);
17601755
}
1761-
if !pointing_at_return_type {
1762-
fn_output = Some(&fn_decl.output); // `impl Trait` return type
1763-
}
17641756
}
17651757

17661758
let parent_id = fcx.tcx.hir().get_parent_item(id);
@@ -1795,106 +1787,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
17951787
);
17961788
}
17971789

1798-
if let (Some(sp), Some(fn_output)) = (ret_coercion_span, fn_output) {
1799-
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output);
1800-
}
1801-
18021790
err
18031791
}
18041792

1805-
fn add_impl_trait_explanation<'a>(
1806-
&self,
1807-
err: &mut Diagnostic,
1808-
cause: &ObligationCause<'tcx>,
1809-
fcx: &FnCtxt<'a, 'tcx>,
1810-
expected: Ty<'tcx>,
1811-
sp: Span,
1812-
fn_output: &hir::FnRetTy<'_>,
1813-
) {
1814-
let return_sp = fn_output.span();
1815-
err.span_label(return_sp, "expected because this return type...");
1816-
err.span_label(
1817-
sp,
1818-
format!("...is found to be `{}` here", fcx.resolve_vars_with_obligations(expected)),
1819-
);
1820-
let impl_trait_msg = "for information on `impl Trait`, see \
1821-
<https://doc.rust-lang.org/book/ch10-02-traits.html\
1822-
#returning-types-that-implement-traits>";
1823-
let trait_obj_msg = "for information on trait objects, see \
1824-
<https://doc.rust-lang.org/book/ch17-02-trait-objects.html\
1825-
#using-trait-objects-that-allow-for-values-of-different-types>";
1826-
err.note("to return `impl Trait`, all returned values must be of the same type");
1827-
err.note(impl_trait_msg);
1828-
let snippet = fcx
1829-
.tcx
1830-
.sess
1831-
.source_map()
1832-
.span_to_snippet(return_sp)
1833-
.unwrap_or_else(|_| "dyn Trait".to_string());
1834-
let mut snippet_iter = snippet.split_whitespace();
1835-
let has_impl = snippet_iter.next().is_some_and(|s| s == "impl");
1836-
// Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe.
1837-
let mut is_object_safe = false;
1838-
if let hir::FnRetTy::Return(ty) = fn_output
1839-
// Get the return type.
1840-
&& let hir::TyKind::OpaqueDef(..) = ty.kind
1841-
{
1842-
let ty = fcx.astconv().ast_ty_to_ty( ty);
1843-
// Get the `impl Trait`'s `DefId`.
1844-
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind()
1845-
// Get the `impl Trait`'s `Item` so that we can get its trait bounds and
1846-
// get the `Trait`'s `DefId`.
1847-
&& let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) =
1848-
fcx.tcx.hir().expect_item(def_id.expect_local()).kind
1849-
{
1850-
// Are of this `impl Trait`'s traits object safe?
1851-
is_object_safe = bounds.iter().all(|bound| {
1852-
bound
1853-
.trait_ref()
1854-
.and_then(|t| t.trait_def_id())
1855-
.is_some_and(|def_id| {
1856-
fcx.tcx.check_is_object_safe(def_id)
1857-
})
1858-
})
1859-
}
1860-
};
1861-
if has_impl {
1862-
if is_object_safe {
1863-
err.multipart_suggestion(
1864-
"you could change the return type to be a boxed trait object",
1865-
vec![
1866-
(return_sp.with_hi(return_sp.lo() + BytePos(4)), "Box<dyn".to_string()),
1867-
(return_sp.shrink_to_hi(), ">".to_string()),
1868-
],
1869-
Applicability::MachineApplicable,
1870-
);
1871-
let sugg = [sp, cause.span]
1872-
.into_iter()
1873-
.flat_map(|sp| {
1874-
[
1875-
(sp.shrink_to_lo(), "Box::new(".to_string()),
1876-
(sp.shrink_to_hi(), ")".to_string()),
1877-
]
1878-
.into_iter()
1879-
})
1880-
.collect::<Vec<_>>();
1881-
err.multipart_suggestion(
1882-
"if you change the return type to expect trait objects, box the returned \
1883-
expressions",
1884-
sugg,
1885-
Applicability::MaybeIncorrect,
1886-
);
1887-
} else {
1888-
err.help(format!(
1889-
"if the trait `{}` were object safe, you could return a boxed trait object",
1890-
&snippet[5..]
1891-
));
1892-
}
1893-
err.note(trait_obj_msg);
1894-
}
1895-
err.help("you could instead create a new `enum` with a variant for each returned type");
1896-
}
1897-
18981793
/// Checks whether the return type is unsized via an obligation, which makes
18991794
/// sure we consider `dyn Trait: Sized` where clauses, which are trivially
19001795
/// false but technically valid for typeck.

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
847847
) {
848848
err.subdiagnostic(subdiag);
849849
}
850-
if let Some(ret_sp) = opt_suggest_box_span {
850+
// don't suggest wrapping either blocks in `if .. {} else {}`
851+
let is_empty_arm = |id| {
852+
let hir::Node::Block(blk) = self.tcx.hir().get(id)
853+
else {
854+
return false;
855+
};
856+
if blk.expr.is_some() || !blk.stmts.is_empty() {
857+
return false;
858+
}
859+
let Some((_, hir::Node::Expr(expr))) = self.tcx.hir().parent_iter(id).nth(1)
860+
else {
861+
return false;
862+
};
863+
matches!(expr.kind, hir::ExprKind::If(..))
864+
};
865+
if let Some(ret_sp) = opt_suggest_box_span
866+
&& !is_empty_arm(then_id)
867+
&& !is_empty_arm(else_id)
868+
{
851869
self.suggest_boxing_for_return_impl_trait(
852870
err,
853871
ret_sp,

src/bootstrap/builder.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1649,12 +1649,7 @@ impl<'a> Builder<'a> {
16491649
self.config.rust_debuginfo_level_tools
16501650
}
16511651
};
1652-
if debuginfo_level == 1 {
1653-
// Use less debuginfo than the default to save on disk space.
1654-
cargo.env(profile_var("DEBUG"), "line-tables-only");
1655-
} else {
1656-
cargo.env(profile_var("DEBUG"), debuginfo_level.to_string());
1657-
};
1652+
cargo.env(profile_var("DEBUG"), debuginfo_level.to_string());
16581653
if self.cc[&target].args().iter().any(|arg| arg == "-gz") {
16591654
rustflags.arg("-Clink-arg=-gz");
16601655
}

src/bootstrap/config.rs

+72-14
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::cell::{Cell, RefCell};
1010
use std::cmp;
1111
use std::collections::{HashMap, HashSet};
1212
use std::env;
13-
use std::fmt;
13+
use std::fmt::{self, Display};
1414
use std::fs;
1515
use std::io::IsTerminal;
1616
use std::path::{Path, PathBuf};
@@ -50,6 +50,57 @@ pub enum DryRun {
5050
UserSelected,
5151
}
5252

53+
#[derive(Copy, Clone, Default)]
54+
pub enum DebuginfoLevel {
55+
#[default]
56+
None,
57+
LineTablesOnly,
58+
Limited,
59+
Full,
60+
}
61+
62+
// NOTE: can't derive(Deserialize) because the intermediate trip through toml::Value only
63+
// deserializes i64, and derive() only generates visit_u64
64+
impl<'de> Deserialize<'de> for DebuginfoLevel {
65+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
66+
where
67+
D: Deserializer<'de>,
68+
{
69+
use serde::de::Error;
70+
71+
Ok(match Deserialize::deserialize(deserializer)? {
72+
StringOrInt::String("none") | StringOrInt::Int(0) => DebuginfoLevel::None,
73+
StringOrInt::String("line-tables-only") => DebuginfoLevel::LineTablesOnly,
74+
StringOrInt::String("limited") | StringOrInt::Int(1) => DebuginfoLevel::Limited,
75+
StringOrInt::String("full") | StringOrInt::Int(2) => DebuginfoLevel::Full,
76+
StringOrInt::Int(n) => {
77+
let other = serde::de::Unexpected::Signed(n);
78+
return Err(D::Error::invalid_value(other, &"expected 0, 1, or 2"));
79+
}
80+
StringOrInt::String(s) => {
81+
let other = serde::de::Unexpected::Str(s);
82+
return Err(D::Error::invalid_value(
83+
other,
84+
&"expected none, line-tables-only, limited, or full",
85+
));
86+
}
87+
})
88+
}
89+
}
90+
91+
/// Suitable for passing to `-C debuginfo`
92+
impl Display for DebuginfoLevel {
93+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94+
use DebuginfoLevel::*;
95+
f.write_str(match self {
96+
None => "0",
97+
LineTablesOnly => "line-tables-only",
98+
Limited => "1",
99+
Full => "2",
100+
})
101+
}
102+
}
103+
53104
/// Global configuration for the entire build and/or bootstrap.
54105
///
55106
/// 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 {
159210
pub rust_overflow_checks: bool,
160211
pub rust_overflow_checks_std: bool,
161212
pub rust_debug_logging: bool,
162-
pub rust_debuginfo_level_rustc: u32,
163-
pub rust_debuginfo_level_std: u32,
164-
pub rust_debuginfo_level_tools: u32,
165-
pub rust_debuginfo_level_tests: u32,
213+
pub rust_debuginfo_level_rustc: DebuginfoLevel,
214+
pub rust_debuginfo_level_std: DebuginfoLevel,
215+
pub rust_debuginfo_level_tools: DebuginfoLevel,
216+
pub rust_debuginfo_level_tests: DebuginfoLevel,
166217
pub rust_split_debuginfo: SplitDebuginfo,
167218
pub rust_rpath: bool,
168219
pub rustc_parallel: bool,
@@ -810,6 +861,13 @@ impl Default for StringOrBool {
810861
}
811862
}
812863

864+
#[derive(Deserialize)]
865+
#[serde(untagged)]
866+
enum StringOrInt<'a> {
867+
String(&'a str),
868+
Int(i64),
869+
}
870+
813871
define_config! {
814872
/// TOML representation of how the Rust build is configured.
815873
struct Rust {
@@ -822,11 +880,11 @@ define_config! {
822880
overflow_checks: Option<bool> = "overflow-checks",
823881
overflow_checks_std: Option<bool> = "overflow-checks-std",
824882
debug_logging: Option<bool> = "debug-logging",
825-
debuginfo_level: Option<u32> = "debuginfo-level",
826-
debuginfo_level_rustc: Option<u32> = "debuginfo-level-rustc",
827-
debuginfo_level_std: Option<u32> = "debuginfo-level-std",
828-
debuginfo_level_tools: Option<u32> = "debuginfo-level-tools",
829-
debuginfo_level_tests: Option<u32> = "debuginfo-level-tests",
883+
debuginfo_level: Option<DebuginfoLevel> = "debuginfo-level",
884+
debuginfo_level_rustc: Option<DebuginfoLevel> = "debuginfo-level-rustc",
885+
debuginfo_level_std: Option<DebuginfoLevel> = "debuginfo-level-std",
886+
debuginfo_level_tools: Option<DebuginfoLevel> = "debuginfo-level-tools",
887+
debuginfo_level_tests: Option<DebuginfoLevel> = "debuginfo-level-tests",
830888
split_debuginfo: Option<String> = "split-debuginfo",
831889
run_dsymutil: Option<bool> = "run-dsymutil",
832890
backtrace: Option<bool> = "backtrace",
@@ -1478,17 +1536,17 @@ impl Config {
14781536

14791537
config.rust_debug_logging = debug_logging.unwrap_or(config.rust_debug_assertions);
14801538

1481-
let with_defaults = |debuginfo_level_specific: Option<u32>| {
1539+
let with_defaults = |debuginfo_level_specific: Option<_>| {
14821540
debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) {
1483-
1
1541+
DebuginfoLevel::Limited
14841542
} else {
1485-
0
1543+
DebuginfoLevel::None
14861544
})
14871545
};
14881546
config.rust_debuginfo_level_rustc = with_defaults(debuginfo_level_rustc);
14891547
config.rust_debuginfo_level_std = with_defaults(debuginfo_level_std);
14901548
config.rust_debuginfo_level_tools = with_defaults(debuginfo_level_tools);
1491-
config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(0);
1549+
config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None);
14921550

14931551
let download_rustc = config.download_rustc_commit.is_some();
14941552
// See https://github.com/rust-lang/compiler-team/issues/326

src/bootstrap/defaults/config.tools.toml

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ debug-logging = true
99
incremental = true
1010
# Download rustc from CI instead of building it from source.
1111
# This cuts compile times by almost 60x, but means you can't modify the compiler.
12+
# Using these defaults will download the stage2 compiler (see `download-rustc`
13+
# setting) and the stage2 toolchain should therefore be used for these defaults.
1214
download-rustc = "if-unchanged"
1315

1416
[build]

src/bootstrap/setup.rs

+8
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ pub fn setup(config: &Config, profile: Profile) {
176176
);
177177
}
178178

179+
if profile == Profile::Tools {
180+
eprintln!();
181+
eprintln!(
182+
"note: the `tools` profile sets up the `stage2` toolchain (use \
183+
`rustup toolchain link 'name' host/build/stage2` to use rustc)"
184+
)
185+
}
186+
179187
let path = &config.config.clone().unwrap_or(PathBuf::from("config.toml"));
180188
setup_config_toml(path, profile, config);
181189
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn test() -> impl std::fmt::Debug {
2+
if true {
3+
"boo2"
4+
} else {
5+
//~^ ERROR `if` and `else` have incompatible types
6+
}
7+
}
8+
9+
fn main() {}

0 commit comments

Comments
 (0)