Skip to content

Commit 3ad7131

Browse files
committed
Introduce with_forced_trimmed_paths
1 parent 32da230 commit 3ad7131

39 files changed

+223
-117
lines changed

compiler/rustc_middle/src/ty/error.rs

+30-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::traits::{ObligationCause, ObligationCauseCode};
22
use crate::ty::diagnostics::suggest_constraining_type_param;
3-
use crate::ty::print::{FmtPrinter, Printer};
3+
use crate::ty::print::{with_forced_trimmed_paths, FmtPrinter, Printer};
44
use crate::ty::{self, BoundRegionKind, Region, Ty, TyCtxt};
55
use hir::def::DefKind;
66
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
@@ -162,17 +162,29 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
162162
),
163163
RegionsPlaceholderMismatch => write!(f, "one type is more general than the other"),
164164
ArgumentSorts(values, _) | Sorts(values) => ty::tls::with(|tcx| {
165-
report_maybe_different(
166-
f,
167-
&values.expected.sort_string(tcx),
168-
&values.found.sort_string(tcx),
169-
)
165+
let (mut expected, mut found) = with_forced_trimmed_paths!((
166+
values.expected.sort_string(tcx),
167+
values.found.sort_string(tcx),
168+
));
169+
if expected == found {
170+
expected = values.expected.sort_string(tcx);
171+
found = values.found.sort_string(tcx);
172+
}
173+
report_maybe_different(f, &expected, &found)
170174
}),
171175
Traits(values) => ty::tls::with(|tcx| {
176+
let (mut expected, mut found) = with_forced_trimmed_paths!((
177+
tcx.def_path_str(values.expected),
178+
tcx.def_path_str(values.found),
179+
));
180+
if expected == found {
181+
expected = tcx.def_path_str(values.expected);
182+
found = tcx.def_path_str(values.found);
183+
}
172184
report_maybe_different(
173185
f,
174-
&format!("trait `{}`", tcx.def_path_str(values.expected)),
175-
&format!("trait `{}`", tcx.def_path_str(values.found)),
186+
&format!("trait `{expected}`"),
187+
&format!("trait `{found}`"),
176188
)
177189
}),
178190
IntMismatch(ref values) => {
@@ -999,14 +1011,16 @@ fn foo(&self) -> Self::T { String::new() }
9991011
let mut short;
10001012
loop {
10011013
// Look for the longest properly trimmed path that still fits in lenght_limit.
1002-
short = FmtPrinter::new_with_limit(
1003-
self,
1004-
hir::def::Namespace::TypeNS,
1005-
rustc_session::Limit(type_limit),
1006-
)
1007-
.pretty_print_type(ty)
1008-
.expect("could not write to `String`")
1009-
.into_buffer();
1014+
short = with_forced_trimmed_paths!(
1015+
FmtPrinter::new_with_limit(
1016+
self,
1017+
hir::def::Namespace::TypeNS,
1018+
rustc_session::Limit(type_limit),
1019+
)
1020+
.pretty_print_type(ty)
1021+
.expect("could not write to `String`")
1022+
.into_buffer()
1023+
);
10101024
if short.len() <= length_limit || type_limit == 0 {
10111025
break;
10121026
}

compiler/rustc_middle/src/ty/print/pretty.rs

+81-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_data_structures::sso::SsoHashSet;
1010
use rustc_hir as hir;
1111
use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
1212
use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_ID, LOCAL_CRATE};
13-
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
13+
use rustc_hir::definitions::{DefKey, DefPathData, DefPathDataName, DisambiguatedDefPathData};
1414
use rustc_hir::LangItem;
1515
use rustc_session::config::TrimmedDefPaths;
1616
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
@@ -63,6 +63,7 @@ thread_local! {
6363
static FORCE_IMPL_FILENAME_LINE: Cell<bool> = const { Cell::new(false) };
6464
static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = const { Cell::new(false) };
6565
static NO_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
66+
static FORCE_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
6667
static NO_QUERIES: Cell<bool> = const { Cell::new(false) };
6768
static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
6869
}
@@ -116,6 +117,7 @@ define_helper!(
116117
/// of various rustc types, for example `std::vec::Vec` would be trimmed to `Vec`,
117118
/// if no other `Vec` is found.
118119
fn with_no_trimmed_paths(NoTrimmedGuard, NO_TRIMMED_PATH);
120+
fn with_forced_trimmed_paths(ForceTrimmedGuard, FORCE_TRIMMED_PATH);
119121
/// Prevent selection of visible paths. `Display` impl of DefId will prefer
120122
/// visible (public) reexports of types as paths.
121123
fn with_no_visible_paths(NoVisibleGuard, NO_VISIBLE_PATH);
@@ -295,11 +297,89 @@ pub trait PrettyPrinter<'tcx>:
295297
self.try_print_visible_def_path_recur(def_id, &mut callers)
296298
}
297299

300+
// Given a `DefId`, produce a short name. For types and traits, it prints *only* its name,
301+
// For associated items on traits it prints out the trait's name and the associated item's name.
302+
// For enum variants, if they have an unique name, then we only print the name, otherwise we
303+
// print the enum name and the variant name. Otherwise, we do not print anything and let the
304+
// caller use the `print_def_path` fallback.
305+
fn force_print_trimmed_def_path(
306+
mut self,
307+
def_id: DefId,
308+
) -> Result<(Self::Path, bool), Self::Error> {
309+
let key = self.tcx().def_key(def_id);
310+
let visible_parent_map = self.tcx().visible_parent_map(());
311+
let kind = self.tcx().def_kind(def_id);
312+
313+
let get_local_name = |this: &Self, name, def_id, key: DefKey| {
314+
if let Some(visible_parent) = visible_parent_map.get(&def_id)
315+
&& let actual_parent = this.tcx().opt_parent(def_id)
316+
&& let DefPathData::TypeNs(_) = key.disambiguated_data.data
317+
&& Some(*visible_parent) != actual_parent
318+
{
319+
this
320+
.tcx()
321+
.module_children(visible_parent)
322+
.iter()
323+
.filter(|child| child.res.opt_def_id() == Some(def_id))
324+
.find(|child| child.vis.is_public() && child.ident.name != kw::Underscore)
325+
.map(|child| child.ident.name)
326+
.unwrap_or(name)
327+
} else {
328+
name
329+
}
330+
};
331+
if let DefKind::Variant = kind
332+
&& let Some(symbol) = self.tcx().trimmed_def_paths(()).get(&def_id)
333+
{
334+
// If `Assoc` is unique, we don't want to talk about `Trait::Assoc`.
335+
self.write_str(get_local_name(&self, *symbol, def_id, key).as_str())?;
336+
return Ok((self, true));
337+
}
338+
if let Some(symbol) = key.get_opt_name() {
339+
if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = kind
340+
&& let Some(parent) = self.tcx().opt_parent(def_id)
341+
&& let parent_key = self.tcx().def_key(parent)
342+
&& let Some(symbol) = parent_key.get_opt_name()
343+
{
344+
// Trait
345+
self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?;
346+
self.write_str("::")?;
347+
} else if let DefKind::Variant = kind
348+
&& let Some(parent) = self.tcx().opt_parent(def_id)
349+
&& let parent_key = self.tcx().def_key(parent)
350+
&& let Some(symbol) = parent_key.get_opt_name()
351+
{
352+
// Enum
353+
354+
// For associated items and variants, we want the "full" path, namely, include
355+
// the parent type in the path. For example, `Iterator::Item`.
356+
self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?;
357+
self.write_str("::")?;
358+
} else if let DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Trait
359+
| DefKind::TyAlias | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind
360+
{
361+
} else {
362+
// If not covered above, like for example items out of `impl` blocks, fallback.
363+
return Ok((self, false));
364+
}
365+
self.write_str(get_local_name(&self, symbol, def_id, key).as_str())?;
366+
return Ok((self, true));
367+
}
368+
Ok((self, false))
369+
}
370+
298371
/// Try to see if this path can be trimmed to a unique symbol name.
299372
fn try_print_trimmed_def_path(
300373
mut self,
301374
def_id: DefId,
302375
) -> Result<(Self::Path, bool), Self::Error> {
376+
if FORCE_TRIMMED_PATH.with(|flag| flag.get()) {
377+
let (s, trimmed) = self.force_print_trimmed_def_path(def_id)?;
378+
if trimmed {
379+
return Ok((s, true));
380+
}
381+
self = s;
382+
}
303383
if !self.tcx().sess.opts.unstable_opts.trim_diagnostic_paths
304384
|| matches!(self.tcx().sess.opts.trimmed_def_paths, TrimmedDefPaths::Never)
305385
|| NO_TRIMMED_PATH.with(|flag| flag.get())

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use std::fmt;
3636
use super::InferCtxtPrivExt;
3737
use crate::infer::InferCtxtExt as _;
3838
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
39-
use rustc_middle::ty::print::with_no_trimmed_paths;
39+
use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
4040

4141
#[derive(Debug)]
4242
pub enum GeneratorInteriorOrUpvar {
@@ -2412,6 +2412,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
24122412
ObligationCauseCode::BindingObligation(item_def_id, span)
24132413
| ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => {
24142414
let item_name = tcx.def_path_str(item_def_id);
2415+
let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id));
24152416
let mut multispan = MultiSpan::from(span);
24162417
let sm = tcx.sess.source_map();
24172418
if let Some(ident) = tcx.opt_item_ident(item_def_id) {
@@ -2424,9 +2425,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
24242425
multispan.push_span_label(ident.span, "required by a bound in this");
24252426
}
24262427
}
2427-
let descr = format!("required by a bound in `{}`", item_name);
2428+
let descr = format!("required by a bound in `{item_name}`");
24282429
if span.is_visible(sm) {
2429-
let msg = format!("required by this bound in `{}`", item_name);
2430+
let msg = format!("required by this bound in `{short_item_name}`");
24302431
multispan.push_span_label(span, msg);
24312432
err.span_note(multispan, &descr);
24322433
} else {

src/test/ui/closures/closure-return-type-must-be-sized.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ note: required by a bound in `a::bar`
1919
--> $DIR/closure-return-type-must-be-sized.rs:14:19
2020
|
2121
LL | pub fn bar<F: FnOnce() -> R, R: ?Sized>() {}
22-
| ^^^^^^^^^^^^^ required by this bound in `a::bar`
22+
| ^^^^^^^^^^^^^ required by this bound in `bar`
2323

2424
error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
2525
--> $DIR/closure-return-type-must-be-sized.rs:56:5
@@ -51,7 +51,7 @@ note: required by a bound in `b::bar`
5151
--> $DIR/closure-return-type-must-be-sized.rs:28:19
5252
|
5353
LL | pub fn bar<F: Fn() -> R, R: ?Sized>() {}
54-
| ^^^^^^^^^ required by this bound in `b::bar`
54+
| ^^^^^^^^^ required by this bound in `bar`
5555

5656
error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
5757
--> $DIR/closure-return-type-must-be-sized.rs:63:5
@@ -83,7 +83,7 @@ note: required by a bound in `c::bar`
8383
--> $DIR/closure-return-type-must-be-sized.rs:42:19
8484
|
8585
LL | pub fn bar<F: FnMut() -> R, R: ?Sized>() {}
86-
| ^^^^^^^^^^^^ required by this bound in `c::bar`
86+
| ^^^^^^^^^^^^ required by this bound in `bar`
8787

8888
error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
8989
--> $DIR/closure-return-type-must-be-sized.rs:70:5

src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ note: required by a bound in `use_trait_impl::assert_impl`
1414
--> $DIR/abstract-const-as-cast-3.rs:14:23
1515
|
1616
LL | fn assert_impl<T: Trait>() {}
17-
| ^^^^^ required by this bound in `use_trait_impl::assert_impl`
17+
| ^^^^^ required by this bound in `assert_impl`
1818

1919
error[E0308]: mismatched types
2020
--> $DIR/abstract-const-as-cast-3.rs:17:5
@@ -28,7 +28,7 @@ note: required by a bound in `use_trait_impl::assert_impl`
2828
--> $DIR/abstract-const-as-cast-3.rs:14:23
2929
|
3030
LL | fn assert_impl<T: Trait>() {}
31-
| ^^^^^ required by this bound in `use_trait_impl::assert_impl`
31+
| ^^^^^ required by this bound in `assert_impl`
3232

3333
error: unconstrained generic constant
3434
--> $DIR/abstract-const-as-cast-3.rs:20:19
@@ -46,7 +46,7 @@ note: required by a bound in `use_trait_impl::assert_impl`
4646
--> $DIR/abstract-const-as-cast-3.rs:14:23
4747
|
4848
LL | fn assert_impl<T: Trait>() {}
49-
| ^^^^^ required by this bound in `use_trait_impl::assert_impl`
49+
| ^^^^^ required by this bound in `assert_impl`
5050

5151
error[E0308]: mismatched types
5252
--> $DIR/abstract-const-as-cast-3.rs:20:5
@@ -60,7 +60,7 @@ note: required by a bound in `use_trait_impl::assert_impl`
6060
--> $DIR/abstract-const-as-cast-3.rs:14:23
6161
|
6262
LL | fn assert_impl<T: Trait>() {}
63-
| ^^^^^ required by this bound in `use_trait_impl::assert_impl`
63+
| ^^^^^ required by this bound in `assert_impl`
6464

6565
error[E0308]: mismatched types
6666
--> $DIR/abstract-const-as-cast-3.rs:23:5
@@ -74,7 +74,7 @@ note: required by a bound in `use_trait_impl::assert_impl`
7474
--> $DIR/abstract-const-as-cast-3.rs:14:23
7575
|
7676
LL | fn assert_impl<T: Trait>() {}
77-
| ^^^^^ required by this bound in `use_trait_impl::assert_impl`
77+
| ^^^^^ required by this bound in `assert_impl`
7878

7979
error[E0308]: mismatched types
8080
--> $DIR/abstract-const-as-cast-3.rs:25:5
@@ -88,7 +88,7 @@ note: required by a bound in `use_trait_impl::assert_impl`
8888
--> $DIR/abstract-const-as-cast-3.rs:14:23
8989
|
9090
LL | fn assert_impl<T: Trait>() {}
91-
| ^^^^^ required by this bound in `use_trait_impl::assert_impl`
91+
| ^^^^^ required by this bound in `assert_impl`
9292

9393
error: unconstrained generic constant
9494
--> $DIR/abstract-const-as-cast-3.rs:35:19
@@ -106,7 +106,7 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
106106
--> $DIR/abstract-const-as-cast-3.rs:32:23
107107
|
108108
LL | fn assert_impl<T: Trait>() {}
109-
| ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
109+
| ^^^^^ required by this bound in `assert_impl`
110110

111111
error[E0308]: mismatched types
112112
--> $DIR/abstract-const-as-cast-3.rs:35:5
@@ -120,7 +120,7 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
120120
--> $DIR/abstract-const-as-cast-3.rs:32:23
121121
|
122122
LL | fn assert_impl<T: Trait>() {}
123-
| ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
123+
| ^^^^^ required by this bound in `assert_impl`
124124

125125
error: unconstrained generic constant
126126
--> $DIR/abstract-const-as-cast-3.rs:38:19
@@ -138,7 +138,7 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
138138
--> $DIR/abstract-const-as-cast-3.rs:32:23
139139
|
140140
LL | fn assert_impl<T: Trait>() {}
141-
| ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
141+
| ^^^^^ required by this bound in `assert_impl`
142142

143143
error[E0308]: mismatched types
144144
--> $DIR/abstract-const-as-cast-3.rs:38:5
@@ -152,7 +152,7 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
152152
--> $DIR/abstract-const-as-cast-3.rs:32:23
153153
|
154154
LL | fn assert_impl<T: Trait>() {}
155-
| ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
155+
| ^^^^^ required by this bound in `assert_impl`
156156

157157
error[E0308]: mismatched types
158158
--> $DIR/abstract-const-as-cast-3.rs:41:5
@@ -166,7 +166,7 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
166166
--> $DIR/abstract-const-as-cast-3.rs:32:23
167167
|
168168
LL | fn assert_impl<T: Trait>() {}
169-
| ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
169+
| ^^^^^ required by this bound in `assert_impl`
170170

171171
error[E0308]: mismatched types
172172
--> $DIR/abstract-const-as-cast-3.rs:43:5
@@ -180,7 +180,7 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
180180
--> $DIR/abstract-const-as-cast-3.rs:32:23
181181
|
182182
LL | fn assert_impl<T: Trait>() {}
183-
| ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
183+
| ^^^^^ required by this bound in `assert_impl`
184184

185185
error: aborting due to 12 previous errors
186186

src/test/ui/diagnostic-width/long-E0308.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
// compile-flags: --diagnostic-width=60
22
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
33

4-
struct Atype<T, K>(T, K);
5-
struct Btype<T, K>(T, K);
6-
struct Ctype<T, K>(T, K);
4+
mod a {
5+
// Force the "short path for unique types" machinery to trip up
6+
pub struct Atype;
7+
pub struct Btype;
8+
pub struct Ctype;
9+
}
10+
11+
mod b {
12+
pub struct Atype<T, K>(T, K);
13+
pub struct Btype<T, K>(T, K);
14+
pub struct Ctype<T, K>(T, K);
15+
}
16+
17+
use b::*;
718

819
fn main() {
920
let x: Atype<

0 commit comments

Comments
 (0)