Skip to content

Commit f5ec9d8

Browse files
committed
Add wrapper to allow customising ty::TraitRef's printing behaviour.
Add a wrapper newtype called `TraitRefPrintOnlyTraitPath` which overrides the printing behaviour of `ty::TraitRef` to be the simple format `Trait<U>`. Printing of `ty::TraitRef` for `Debug` and `Display` is now the more verbose `<T as Trait<U>>`. This fixes rust-lang#59188.
1 parent 112f7e9 commit f5ec9d8

File tree

7 files changed

+80
-19
lines changed

7 files changed

+80
-19
lines changed

src/librustc/infer/error_reporting/mod.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -1260,8 +1260,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12601260
match *values {
12611261
infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found),
12621262
infer::Regions(ref exp_found) => self.expected_found_str(exp_found),
1263-
infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found),
1264-
infer::PolyTraitRefs(ref exp_found) => self.expected_found_str(exp_found),
1263+
infer::TraitRefs(ref exp_found) => {
1264+
let pretty_exp_found = ty::error::ExpectedFound {
1265+
expected: exp_found.expected.print_only_trait_path(),
1266+
found: exp_found.found.print_only_trait_path()
1267+
};
1268+
self.expected_found_str(&pretty_exp_found)
1269+
},
1270+
infer::PolyTraitRefs(ref exp_found) => {
1271+
let pretty_exp_found = ty::error::ExpectedFound {
1272+
expected: exp_found.expected.print_only_trait_path(),
1273+
found: exp_found.found.print_only_trait_path()
1274+
};
1275+
self.expected_found_str(&pretty_exp_found)
1276+
},
12651277
}
12661278
}
12671279

src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
373373
value: trait_ref,
374374
};
375375

376-
let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
376+
let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref.print_only_trait_path());
377377
expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
378378
expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
379379
err.note(&{
@@ -427,7 +427,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
427427
note
428428
});
429429

430-
let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref);
430+
let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref.print_only_trait_path());
431431
actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid);
432432
err.note(&{
433433
let passive_voice = match actual_has_vid {

src/librustc/lint/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
845845
// This shouldn't ever be needed, but just in case:
846846
path.push(match trait_ref {
847847
Some(trait_ref) => {
848-
Symbol::intern(&format!("<impl {} for {}>", trait_ref, self_ty)).as_str()
848+
Symbol::intern(&format!("<impl {} for {}>", trait_ref.print_only_trait_path(), self_ty)).as_str()
849849
},
850850
None => Symbol::intern(&format!("<impl {}>", self_ty)).as_str(),
851851
});

src/librustc/traits/error_reporting.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
641641
let is_try = self.tcx.sess.source_map().span_to_snippet(span)
642642
.map(|s| &s == "?")
643643
.unwrap_or(false);
644-
let is_from = format!("{}", trait_ref).starts_with("std::convert::From<");
644+
let is_from = format!("{}", trait_ref.print_only_trait_path())
645+
.starts_with("std::convert::From<");
645646
let message = if is_try && is_from {
646647
Some(format!(
647648
"`?` couldn't convert the error to `{}`",
@@ -667,7 +668,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
667668
} else {
668669
format!("{}the trait `{}` is not implemented for `{}`",
669670
pre_message,
670-
trait_ref,
671+
trait_ref.print_only_trait_path(),
671672
trait_ref.self_ty())
672673
};
673674

@@ -1630,7 +1631,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
16301631
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
16311632
err.note(
16321633
&format!("required because of the requirements on the impl of `{}` for `{}`",
1633-
parent_trait_ref,
1634+
parent_trait_ref.print_only_trait_path(),
16341635
parent_trait_ref.skip_binder().self_ty()));
16351636
let parent_predicate = parent_trait_ref.to_predicate();
16361637
self.note_obligation_cause_code(err,

src/librustc/traits/specialize/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option<
391391
use std::fmt::Write;
392392

393393
let trait_ref = if let Some(tr) = tcx.impl_trait_ref(impl_def_id) {
394-
tr
394+
tr.print_only_trait_path()
395395
} else {
396396
return None;
397397
};

src/librustc/ty/print/pretty.rs

+57-6
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
406406

407407
p!(print(self_ty));
408408
if let Some(trait_ref) = trait_ref {
409-
p!(write(" as "), print(trait_ref));
409+
p!(write(" as "), print(trait_ref.print_only_trait_path()));
410410
}
411411
Ok(cx)
412412
})
@@ -425,7 +425,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
425425

426426
p!(write("impl "));
427427
if let Some(trait_ref) = trait_ref {
428-
p!(print(trait_ref), write(" for "));
428+
p!(print(trait_ref.print_only_trait_path()), write(" for "));
429429
}
430430
p!(print(self_ty));
431431

@@ -559,7 +559,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
559559

560560
p!(
561561
write("{}", if first { " " } else { "+" }),
562-
print(trait_ref));
562+
print(trait_ref.print_only_trait_path()));
563563
first = false;
564564
}
565565
}
@@ -1395,6 +1395,52 @@ impl<'gcx: 'tcx, 'tcx, T, U, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
13951395
}
13961396
}
13971397

1398+
/// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
1399+
/// the trait path. That is, it will print `Trait<U>` instead of
1400+
/// `<T as Trait<U>>`.
1401+
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
1402+
pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
1403+
1404+
impl TraitRefPrintOnlyTraitPath<'tcx> {
1405+
pub fn self_ty(&self) -> ty::Ty<'tcx> {
1406+
self.0.self_ty()
1407+
}
1408+
}
1409+
1410+
impl fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
1411+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1412+
fmt::Display::fmt(self, f)
1413+
}
1414+
}
1415+
1416+
impl<'a, 'tcx> ty::Lift<'tcx> for TraitRefPrintOnlyTraitPath<'a> {
1417+
type Lifted = TraitRefPrintOnlyTraitPath<'tcx>;
1418+
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
1419+
tcx.lift(&self.0.substs).map(|substs| TraitRefPrintOnlyTraitPath(ty::TraitRef {
1420+
def_id: self.0.def_id,
1421+
substs,
1422+
}))
1423+
}
1424+
}
1425+
1426+
TupleStructTypeFoldableImpl! {
1427+
impl<'tcx> TypeFoldable<'tcx> for TraitRefPrintOnlyTraitPath<'tcx> {
1428+
a
1429+
}
1430+
}
1431+
1432+
impl ty::TraitRef<'tcx> {
1433+
pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
1434+
TraitRefPrintOnlyTraitPath(self)
1435+
}
1436+
}
1437+
1438+
impl ty::PolyTraitRef<'tcx> {
1439+
pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>> {
1440+
self.map_bound(|x| TraitRefPrintOnlyTraitPath(x))
1441+
}
1442+
}
1443+
13981444
macro_rules! forward_display_to_print {
13991445
($($ty:ty),+) => {
14001446
$(impl fmt::Display for $ty {
@@ -1447,6 +1493,7 @@ forward_display_to_print! {
14471493
// because `for<'gcx: 'tcx, 'tcx>` isn't possible yet.
14481494
ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
14491495
ty::Binder<ty::TraitRef<'tcx>>,
1496+
ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>>,
14501497
ty::Binder<ty::FnSig<'tcx>>,
14511498
ty::Binder<ty::TraitPredicate<'tcx>>,
14521499
ty::Binder<ty::SubtypePredicate<'tcx>>,
@@ -1482,7 +1529,7 @@ define_print_and_forward_display! {
14821529
// Use a type that can't appear in defaults of type parameters.
14831530
let dummy_self = cx.tcx().mk_infer(ty::FreshTy(0));
14841531
let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
1485-
p!(print(trait_ref))
1532+
p!(print(trait_ref.print_only_trait_path()))
14861533
}
14871534

14881535
ty::ExistentialProjection<'tcx> {
@@ -1528,7 +1575,11 @@ define_print_and_forward_display! {
15281575
}
15291576

15301577
ty::TraitRef<'tcx> {
1531-
p!(print_def_path(self.def_id, self.substs));
1578+
p!(write("<{} as {}>", self.self_ty(), self))
1579+
}
1580+
1581+
TraitRefPrintOnlyTraitPath<'tcx> {
1582+
p!(print_def_path(self.0.def_id, self.0.substs));
15321583
}
15331584

15341585
&'tcx ty::Const<'tcx> {
@@ -1553,7 +1604,7 @@ define_print_and_forward_display! {
15531604
}
15541605

15551606
ty::TraitPredicate<'tcx> {
1556-
p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
1607+
p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref.print_only_trait_path()))
15571608
}
15581609

15591610
ty::ProjectionPredicate<'tcx> {

src/librustc/ty/structural_impls.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,7 @@ impl fmt::Debug for ty::FloatVarValue {
225225

226226
impl fmt::Debug for ty::TraitRef<'tcx> {
227227
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228-
// FIXME(#59188) this is used across the compiler to print
229-
// a `TraitRef` qualified (with the Self type explicit),
230-
// instead of having a different way to make that choice.
231-
write!(f, "<{} as {}>", self.self_ty(), self)
228+
fmt::Display::fmt(self, f)
232229
}
233230
}
234231

0 commit comments

Comments
 (0)