Skip to content

Commit af3c6e7

Browse files
committed
Auto merge of #73996 - da-x:short-unique-paths, r=petrochenkov
diagnostics: shorten paths of unique symbols This is a step towards implementing a fix for #50310, and continuation of the discussion in [Pre-RFC: Nicer Types In Diagnostics - compiler - Rust Internals](https://internals.rust-lang.org/t/pre-rfc-nicer-types-in-diagnostics/11139). Impressed upon me from previous discussion in #21934 that an RFC for this is not needed, and I should just come up with code. The recent improvements to `use` suggestions that I've contributed have given rise to this implementation. Contrary to previous suggestions, it's rather simple logic, and I believe it only reduces the amount of cognitive load that a developer would need when reading type errors. ----- If a symbol name can only be imported from one place, and as long as it was not glob-imported anywhere in the current crate, we can trim its printed path to the last component. This has wide implications on error messages with types, for example, shortening `std::vec::Vec` to just `Vec`, as long as there is no other `Vec` importable from anywhere.
2 parents 0d0f6b1 + e7d7615 commit af3c6e7

File tree

1,316 files changed

+4822
-4499
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,316 files changed

+4822
-4499
lines changed

compiler/rustc_codegen_llvm/src/type_of.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::type_::Type;
44
use rustc_codegen_ssa::traits::*;
55
use rustc_middle::bug;
66
use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout};
7+
use rustc_middle::ty::print::with_no_trimmed_paths;
78
use rustc_middle::ty::{self, Ty, TypeFoldable};
89
use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
910
use rustc_target::abi::{Int, Pointer, F32, F64};
@@ -57,7 +58,7 @@ fn uncached_llvm_type<'a, 'tcx>(
5758
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str
5859
if !cx.sess().fewer_names() =>
5960
{
60-
let mut name = layout.ty.to_string();
61+
let mut name = with_no_trimmed_paths(|| layout.ty.to_string());
6162
if let (&ty::Adt(def, _), &Variants::Single { index }) =
6263
(&layout.ty.kind, &layout.variants)
6364
{

compiler/rustc_codegen_ssa/src/mir/block.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_middle::mir;
1616
use rustc_middle::mir::interpret::{AllocId, ConstValue, Pointer, Scalar};
1717
use rustc_middle::mir::AssertKind;
1818
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
19+
use rustc_middle::ty::print::with_no_trimmed_paths;
1920
use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
2021
use rustc_span::source_map::Span;
2122
use rustc_span::{sym, Symbol};
@@ -479,14 +480,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
479480
UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false).unwrap(),
480481
};
481482
if do_panic {
482-
let msg_str = if layout.abi.is_uninhabited() {
483-
// Use this error even for the other intrinsics as it is more precise.
484-
format!("attempted to instantiate uninhabited type `{}`", ty)
485-
} else if intrinsic == ZeroValid {
486-
format!("attempted to zero-initialize type `{}`, which is invalid", ty)
487-
} else {
488-
format!("attempted to leave type `{}` uninitialized, which is invalid", ty)
489-
};
483+
let msg_str = with_no_trimmed_paths(|| {
484+
if layout.abi.is_uninhabited() {
485+
// Use this error even for the other intrinsics as it is more precise.
486+
format!("attempted to instantiate uninhabited type `{}`", ty)
487+
} else if intrinsic == ZeroValid {
488+
format!("attempted to zero-initialize type `{}`, which is invalid", ty)
489+
} else {
490+
format!("attempted to leave type `{}` uninitialized, which is invalid", ty)
491+
}
492+
});
490493
let msg = bx.const_str(Symbol::intern(&msg_str));
491494
let location = self.get_caller_location(bx, span).immediate();
492495

compiler/rustc_driver/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustc_save_analysis as save;
3232
use rustc_save_analysis::DumpHandler;
3333
use rustc_serialize::json::{self, ToJson};
3434
use rustc_session::config::nightly_options;
35-
use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest};
35+
use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths};
3636
use rustc_session::getopts;
3737
use rustc_session::lint::{Lint, LintId};
3838
use rustc_session::{config, DiagnosticOutput, Session};
@@ -126,6 +126,7 @@ impl Callbacks for TimePassesCallbacks {
126126
// time because it will mess up the --prints output. See #64339.
127127
self.time_passes = config.opts.prints.is_empty()
128128
&& (config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time);
129+
config.opts.trimmed_def_paths = TrimmedDefPaths::GoodPath;
129130
}
130131
}
131132

compiler/rustc_errors/src/lib.rs

+48-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
66
#![feature(crate_visibility_modifier)]
7+
#![feature(backtrace)]
78
#![feature(nll)]
89

910
#[macro_use]
@@ -296,9 +297,11 @@ struct HandlerInner {
296297
/// This is not necessarily the count that's reported to the user once
297298
/// compilation ends.
298299
err_count: usize,
300+
warn_count: usize,
299301
deduplicated_err_count: usize,
300302
emitter: Box<dyn Emitter + sync::Send>,
301303
delayed_span_bugs: Vec<Diagnostic>,
304+
delayed_good_path_bugs: Vec<Diagnostic>,
302305

303306
/// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
304307
/// emitting the same diagnostic with extended help (`--teach`) twice, which
@@ -361,13 +364,15 @@ impl Drop for HandlerInner {
361364

362365
if !self.has_errors() {
363366
let bugs = std::mem::replace(&mut self.delayed_span_bugs, Vec::new());
364-
let has_bugs = !bugs.is_empty();
365-
for bug in bugs {
366-
self.emit_diagnostic(&bug);
367-
}
368-
if has_bugs {
369-
panic!("no errors encountered even though `delay_span_bug` issued");
370-
}
367+
self.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued");
368+
}
369+
370+
if !self.has_any_message() {
371+
let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new());
372+
self.flush_delayed(
373+
bugs,
374+
"no warnings or errors encountered even though `delayed_good_path_bugs` issued",
375+
);
371376
}
372377
}
373378
}
@@ -422,10 +427,12 @@ impl Handler {
422427
inner: Lock::new(HandlerInner {
423428
flags,
424429
err_count: 0,
430+
warn_count: 0,
425431
deduplicated_err_count: 0,
426432
deduplicated_warn_count: 0,
427433
emitter,
428434
delayed_span_bugs: Vec::new(),
435+
delayed_good_path_bugs: Vec::new(),
429436
taught_diagnostics: Default::default(),
430437
emitted_diagnostic_codes: Default::default(),
431438
emitted_diagnostics: Default::default(),
@@ -448,11 +455,13 @@ impl Handler {
448455
pub fn reset_err_count(&self) {
449456
let mut inner = self.inner.borrow_mut();
450457
inner.err_count = 0;
458+
inner.warn_count = 0;
451459
inner.deduplicated_err_count = 0;
452460
inner.deduplicated_warn_count = 0;
453461

454462
// actually free the underlying memory (which `clear` would not do)
455463
inner.delayed_span_bugs = Default::default();
464+
inner.delayed_good_path_bugs = Default::default();
456465
inner.taught_diagnostics = Default::default();
457466
inner.emitted_diagnostic_codes = Default::default();
458467
inner.emitted_diagnostics = Default::default();
@@ -629,6 +638,10 @@ impl Handler {
629638
self.inner.borrow_mut().delay_span_bug(span, msg)
630639
}
631640

641+
pub fn delay_good_path_bug(&self, msg: &str) {
642+
self.inner.borrow_mut().delay_good_path_bug(msg)
643+
}
644+
632645
pub fn span_bug_no_panic(&self, span: impl Into<MultiSpan>, msg: &str) {
633646
self.emit_diag_at_span(Diagnostic::new(Bug, msg), span);
634647
}
@@ -768,6 +781,8 @@ impl HandlerInner {
768781
}
769782
if diagnostic.is_error() {
770783
self.bump_err_count();
784+
} else {
785+
self.bump_warn_count();
771786
}
772787
}
773788

@@ -859,6 +874,9 @@ impl HandlerInner {
859874
fn has_errors_or_delayed_span_bugs(&self) -> bool {
860875
self.has_errors() || !self.delayed_span_bugs.is_empty()
861876
}
877+
fn has_any_message(&self) -> bool {
878+
self.err_count() > 0 || self.warn_count > 0
879+
}
862880

863881
fn abort_if_errors(&mut self) {
864882
self.emit_stashed_diagnostics();
@@ -892,6 +910,15 @@ impl HandlerInner {
892910
self.delay_as_bug(diagnostic)
893911
}
894912

913+
fn delay_good_path_bug(&mut self, msg: &str) {
914+
let mut diagnostic = Diagnostic::new(Level::Bug, msg);
915+
if self.flags.report_delayed_bugs {
916+
self.emit_diagnostic(&diagnostic);
917+
}
918+
diagnostic.note(&format!("delayed at {}", std::backtrace::Backtrace::force_capture()));
919+
self.delayed_good_path_bugs.push(diagnostic);
920+
}
921+
895922
fn failure(&mut self, msg: &str) {
896923
self.emit_diagnostic(&Diagnostic::new(FailureNote, msg));
897924
}
@@ -925,11 +952,25 @@ impl HandlerInner {
925952
self.delayed_span_bugs.push(diagnostic);
926953
}
927954

955+
fn flush_delayed(&mut self, bugs: Vec<Diagnostic>, explanation: &str) {
956+
let has_bugs = !bugs.is_empty();
957+
for bug in bugs {
958+
self.emit_diagnostic(&bug);
959+
}
960+
if has_bugs {
961+
panic!("{}", explanation);
962+
}
963+
}
964+
928965
fn bump_err_count(&mut self) {
929966
self.err_count += 1;
930967
self.panic_if_treat_err_as_bug();
931968
}
932969

970+
fn bump_warn_count(&mut self) {
971+
self.warn_count += 1;
972+
}
973+
933974
fn panic_if_treat_err_as_bug(&self) {
934975
if self.treat_err_as_bug() {
935976
let s = match (self.err_count(), self.flags.treat_err_as_bug.unwrap_or(0)) {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -611,11 +611,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
611611
let sig = self.tcx.fn_sig(did);
612612
let bound_output = sig.output();
613613
let output = bound_output.skip_binder();
614-
err.span_label(e.span, &format!("this method call resolves to `{:?}`", output));
614+
err.span_label(e.span, &format!("this method call resolves to `{}`", output));
615615
let kind = &output.kind;
616616
if let ty::Projection(proj) = kind {
617617
if let Some(span) = self.tcx.hir().span_if_local(proj.item_def_id) {
618-
err.span_label(span, &format!("`{:?}` defined here", output));
618+
err.span_label(span, &format!("`{}` defined here", output));
619619
}
620620
}
621621
}

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
5858
.tcx()
5959
.sess
6060
.struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature");
61-
err.span_label(sp, &format!("found `{:?}`", found));
62-
err.span_label(trait_sp, &format!("expected `{:?}`", expected));
61+
err.span_label(sp, &format!("found `{}`", found));
62+
err.span_label(trait_sp, &format!("expected `{}`", expected));
6363

6464
// Get the span of all the used type parameters in the method.
6565
let assoc_item = self.tcx().associated_item(trait_def_id);
@@ -92,7 +92,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
9292
err.note_expected_found(&"", expected, &"", found);
9393
} else {
9494
// This fallback shouldn't be necessary, but let's keep it in just in case.
95-
err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found));
95+
err.note(&format!("expected `{}`\n found `{}`", expected, found));
9696
}
9797
err.span_help(
9898
type_param_span,

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ fn test_debugging_options_tracking_hash() {
518518
untracked!(time_llvm_passes, true);
519519
untracked!(time_passes, true);
520520
untracked!(trace_macros, true);
521+
untracked!(trim_diagnostic_paths, false);
521522
untracked!(ui_testing, true);
522523
untracked!(unpretty, Some("expanded".to_string()));
523524
untracked!(unstable_options, true);

compiler/rustc_lint/src/builtin.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use rustc_hir::{ForeignItemKind, GenericParamKind, PatKind};
4040
use rustc_hir::{HirId, HirIdSet, Node};
4141
use rustc_index::vec::Idx;
4242
use rustc_middle::lint::LintDiagnosticBuilder;
43+
use rustc_middle::ty::print::with_no_trimmed_paths;
4344
use rustc_middle::ty::subst::{GenericArgKind, Subst};
4445
use rustc_middle::ty::{self, layout::LayoutError, Ty, TyCtxt};
4546
use rustc_session::lint::FutureIncompatibleInfo;
@@ -2040,7 +2041,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
20402041
// using zeroed or uninitialized memory.
20412042
// We are extremely conservative with what we warn about.
20422043
let conjured_ty = cx.typeck_results().expr_ty(expr);
2043-
if let Some((msg, span)) = ty_find_init_error(cx.tcx, conjured_ty, init) {
2044+
if let Some((msg, span)) =
2045+
with_no_trimmed_paths(|| ty_find_init_error(cx.tcx, conjured_ty, init))
2046+
{
20442047
cx.struct_span_lint(INVALID_VALUE, expr.span, |lint| {
20452048
let mut err = lint.build(&format!(
20462049
"the type `{}` does not permit {}",

compiler/rustc_lint/src/context.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc_middle::lint::LintDiagnosticBuilder;
3131
use rustc_middle::middle::privacy::AccessLevels;
3232
use rustc_middle::middle::stability;
3333
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
34+
use rustc_middle::ty::print::with_no_trimmed_paths;
3435
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
3536
use rustc_session::lint::{add_elided_lifetime_in_path_suggestion, BuiltinLintDiagnostics};
3637
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
@@ -795,10 +796,12 @@ impl<'tcx> LateContext<'tcx> {
795796
}
796797

797798
// This shouldn't ever be needed, but just in case:
798-
Ok(vec![match trait_ref {
799-
Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)),
800-
None => Symbol::intern(&format!("<{}>", self_ty)),
801-
}])
799+
with_no_trimmed_paths(|| {
800+
Ok(vec![match trait_ref {
801+
Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)),
802+
None => Symbol::intern(&format!("<{}>", self_ty)),
803+
}])
804+
})
802805
}
803806

804807
fn path_append_impl(
@@ -812,12 +815,16 @@ impl<'tcx> LateContext<'tcx> {
812815

813816
// This shouldn't ever be needed, but just in case:
814817
path.push(match trait_ref {
815-
Some(trait_ref) => Symbol::intern(&format!(
816-
"<impl {} for {}>",
817-
trait_ref.print_only_trait_path(),
818-
self_ty
819-
)),
820-
None => Symbol::intern(&format!("<impl {}>", self_ty)),
818+
Some(trait_ref) => with_no_trimmed_paths(|| {
819+
Symbol::intern(&format!(
820+
"<impl {} for {}>",
821+
trait_ref.print_only_trait_path(),
822+
self_ty
823+
))
824+
}),
825+
None => {
826+
with_no_trimmed_paths(|| Symbol::intern(&format!("<impl {}>", self_ty)))
827+
}
821828
});
822829

823830
Ok(path)

compiler/rustc_macros/src/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ fn add_query_description_impl(
392392
#tcx: TyCtxt<'tcx>,
393393
#key: #arg,
394394
) -> Cow<'static, str> {
395-
format!(#desc).into()
395+
::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into())
396396
}
397397
};
398398

compiler/rustc_middle/src/middle/stability.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_hir as hir;
1313
use rustc_hir::def::DefKind;
1414
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
1515
use rustc_hir::{self, HirId};
16+
use rustc_middle::ty::print::with_no_trimmed_paths;
1617
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
1718
use rustc_session::lint::{BuiltinLintDiagnostics, Lint, LintBuffer};
1819
use rustc_session::parse::feature_err_issue;
@@ -308,7 +309,7 @@ impl<'tcx> TyCtxt<'tcx> {
308309
// #[rustc_deprecated] however wants to emit down the whole
309310
// hierarchy.
310311
if !skip || depr_entry.attr.is_since_rustc_version {
311-
let path = &self.def_path_str(def_id);
312+
let path = &with_no_trimmed_paths(|| self.def_path_str(def_id));
312313
let kind = self.def_kind(def_id).descr(def_id);
313314
let (message, lint) = deprecation_message(&depr_entry.attr, kind, path);
314315
late_report_deprecation(

compiler/rustc_middle/src/mir/interpret/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ use rustc_data_structures::sync::{HashMapExt, Lock};
108108
use rustc_data_structures::tiny_list::TinyList;
109109
use rustc_hir::def_id::DefId;
110110
use rustc_macros::HashStable;
111+
use rustc_middle::ty::print::with_no_trimmed_paths;
111112
use rustc_serialize::{Decodable, Encodable};
112113
use rustc_target::abi::{Endian, Size};
113114

@@ -145,7 +146,7 @@ pub struct GlobalId<'tcx> {
145146

146147
impl GlobalId<'tcx> {
147148
pub fn display(self, tcx: TyCtxt<'tcx>) -> String {
148-
let instance_name = tcx.def_path_str(self.instance.def.def_id());
149+
let instance_name = with_no_trimmed_paths(|| tcx.def_path_str(self.instance.def.def_id()));
149150
if let Some(promoted) = self.promoted {
150151
format!("{}::{:?}", instance_name, promoted)
151152
} else {

compiler/rustc_middle/src/query/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,11 @@ rustc_queries! {
12551255
storage(ArenaCacheSelector<'tcx>)
12561256
desc { "calculating the visible parent map" }
12571257
}
1258+
query trimmed_def_paths(_: CrateNum)
1259+
-> FxHashMap<DefId, Symbol> {
1260+
storage(ArenaCacheSelector<'tcx>)
1261+
desc { "calculating trimmed def paths" }
1262+
}
12581263
query missing_extern_crate_item(_: CrateNum) -> bool {
12591264
eval_always
12601265
desc { "seeing if we're missing an `extern crate` item for this crate" }

compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ pub struct GlobalCtxt<'tcx> {
944944
maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
945945
/// A map of glob use to a set of names it actually imports. Currently only
946946
/// used in save-analysis.
947-
glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
947+
pub(crate) glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
948948
/// Extern prelude entries. The value is `true` if the entry was introduced
949949
/// via `extern crate` item and not `--extern` option or compiler built-in.
950950
pub extern_prelude: FxHashMap<Symbol, bool>,

compiler/rustc_middle/src/ty/instance.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,11 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
260260
InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
261261
InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
262262
InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num),
263-
InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({:?})", ty),
263+
InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty),
264264
InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
265-
InstanceDef::DropGlue(_, ty) => write!(f, " - shim({:?})", ty),
266-
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({:?})", ty),
265+
InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
266+
InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty),
267+
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty),
267268
}
268269
}
269270
}

0 commit comments

Comments
 (0)