Skip to content

Commit 785ccda

Browse files
committed
rustc: pretty-print impl Trait on-demand in ty_param_name.
1 parent bb163c6 commit 785ccda

File tree

5 files changed

+48
-22
lines changed

5 files changed

+48
-22
lines changed

src/librustc/ty/mod.rs

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use session::DataTypeKind;
4242
use serialize::{self, Encodable, Encoder};
4343
use std::cell::RefCell;
4444
use std::cmp::{self, Ordering};
45-
use std::fmt;
45+
use std::fmt::{self, Write};
4646
use std::hash::{Hash, Hasher};
4747
use std::ops::Deref;
4848
use rustc_data_structures::sync::{self, Lrc, ParallelIterator, par_iter};
@@ -2640,37 +2640,63 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
26402640
pub fn ty_param_name(self, id: DefId) -> InternedString {
26412641
let def_key = self.def_key(id);
26422642
match def_key.disambiguated_data.data {
2643-
DefPathData::TypeParam(name) => name,
26442643
DefPathData::ImplTrait => {
2645-
let param_owner_def_id = DefId {
2644+
// HACK(eddyb) on-demand pretty-printing of `impl Trait`
2645+
// parameters - hopefully this is not used too often.
2646+
2647+
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, by
2648+
// looking up the predicates associated with the owner's def_id.
2649+
let predicates_of_owner = self.predicates_of(DefId {
26462650
krate: id.krate,
26472651
index: def_key.parent.unwrap()
2648-
};
2649-
let generics = self.generics_of(param_owner_def_id);
2650-
let index = generics.param_def_id_to_index[&id];
2651-
generics.param_at(index, self).name
2652+
});
2653+
2654+
let mut first = true;
2655+
let mut is_sized = false;
2656+
let mut s = String::from("impl");
2657+
for predicate in predicates_of_owner.predicates {
2658+
if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
2659+
// Ignore bounds other than those on this parameter.
2660+
match trait_ref.self_ty().sty {
2661+
ty::TyParam(p) if p.def_id == id => {}
2662+
_ => continue,
2663+
}
2664+
2665+
// Don't print +Sized, but rather +?Sized if absent.
2666+
if Some(trait_ref.def_id()) == self.lang_items().sized_trait() {
2667+
is_sized = true;
2668+
continue;
2669+
}
2670+
2671+
let _ = write!(s, "{}{}", if first { " " } else { "+" }, trait_ref);
2672+
first = false;
2673+
}
2674+
}
2675+
if !is_sized {
2676+
let _ = write!(s, "{}?Sized", if first { " " } else { "+" });
2677+
}
2678+
2679+
Symbol::intern(&s).as_interned_str()
26522680
}
26532681
DefPathData::Trait(_) => {
26542682
keywords::SelfType.name().as_interned_str()
26552683
}
26562684
DefPathData::ClosureExpr => {
26572685
Symbol::intern("<synthetic closure param>").as_interned_str()
26582686
}
2659-
_ => bug!("ty_param_name: {:?} not a type parameter", id),
2687+
data => data.as_interned_str()
26602688
}
26612689
}
26622690

26632691
pub fn ty_param_owner(self, id: DefId) -> DefId {
26642692
let def_key = self.def_key(id);
26652693
match def_key.disambiguated_data.data {
2666-
DefPathData::ImplTrait |
2667-
DefPathData::TypeParam(_) => DefId {
2694+
DefPathData::Trait(_) |
2695+
DefPathData::ClosureExpr => id,
2696+
_ => DefId {
26682697
krate: id.krate,
26692698
index: def_key.parent.unwrap()
26702699
},
2671-
DefPathData::Trait(_) |
2672-
DefPathData::ClosureExpr => id,
2673-
_ => bug!("ty_param_owner: {:?} not a type parameter", id),
26742700
}
26752701
}
26762702

src/librustc/util/ppaux.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ define_print! {
11241124
return Ok(());
11251125
}
11261126
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
1127-
// by looking up the projections associated with the def_id.
1127+
// by looking up the predicates associated with the def_id.
11281128
let predicates_of = tcx.predicates_of(def_id);
11291129
let substs = tcx.lift(&substs).unwrap_or_else(|| {
11301130
tcx.intern_substs(&[])

src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ LL | fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
55
| -- type in trait
66
...
77
LL | fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
8-
| ^^^^^^^^^^^ expected `B` parameter, found `impl Debug` parameter
8+
| ^^^^^^^^^^^ expected `B` parameter, found `impl std::fmt::Debug` parameter
99
|
10-
= note: expected type `fn(&(), &B, &impl Debug)`
11-
found type `fn(&(), &impl Debug, &B)`
10+
= note: expected type `fn(&(), &B, &impl std::fmt::Debug)`
11+
found type `fn(&(), &impl std::fmt::Debug, &B)`
1212

1313
error: aborting due to previous error
1414

src/test/ui/impl-trait/universal-mismatched-type.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ error[E0308]: mismatched types
44
LL | fn foo(x: impl Debug) -> String {
55
| ------ expected `std::string::String` because of return type
66
LL | x //~ ERROR mismatched types
7-
| ^ expected struct `std::string::String`, found `impl Debug` parameter
7+
| ^ expected struct `std::string::String`, found `impl std::fmt::Debug` parameter
88
|
99
= note: expected type `std::string::String`
10-
found type `impl Debug`
10+
found type `impl std::fmt::Debug`
1111

1212
error: aborting due to previous error
1313

src/test/ui/impl-trait/universal-two-impl-traits.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ error[E0308]: mismatched types
22
--> $DIR/universal-two-impl-traits.rs:15:9
33
|
44
LL | a = y; //~ ERROR mismatched
5-
| ^ expected `impl Debug` parameter, found a different `impl Debug` parameter
5+
| ^ expected `impl std::fmt::Debug` parameter, found a different `impl std::fmt::Debug` parameter
66
|
7-
= note: expected type `impl Debug` (`impl Debug` parameter)
8-
found type `impl Debug` (`impl Debug` parameter)
7+
= note: expected type `impl std::fmt::Debug` (`impl std::fmt::Debug` parameter)
8+
found type `impl std::fmt::Debug` (`impl std::fmt::Debug` parameter)
99

1010
error: aborting due to previous error
1111

0 commit comments

Comments
 (0)