Skip to content

Commit b23648f

Browse files
committed
improve the printing of substs and trait-refs
1 parent 31247e5 commit b23648f

File tree

118 files changed

+350
-291
lines changed

Some content is hidden

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

118 files changed

+350
-291
lines changed

src/librustc/util/ppaux.rs

Lines changed: 103 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use ty::TyClosure;
1919
use ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
2020
use ty::{self, Ty, TyCtxt, TypeFoldable};
2121

22+
use std::cell::Cell;
2223
use std::fmt;
2324
use syntax::abi::Abi;
2425
use syntax::parse::token;
@@ -67,6 +68,45 @@ pub enum Ns {
6768
Value
6869
}
6970

71+
fn number_of_supplied_defaults<'tcx, GG>(tcx: &ty::TyCtxt<'tcx>,
72+
substs: &subst::Substs,
73+
space: subst::ParamSpace,
74+
get_generics: GG)
75+
-> usize
76+
where GG: FnOnce(&TyCtxt<'tcx>) -> ty::Generics<'tcx>
77+
{
78+
let generics = get_generics(tcx);
79+
80+
let has_self = substs.self_ty().is_some();
81+
let ty_params = generics.types.get_slice(space);
82+
let tps = substs.types.get_slice(space);
83+
if ty_params.last().map_or(false, |def| def.default.is_some()) {
84+
let substs = tcx.lift(&substs);
85+
ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
86+
match def.default {
87+
Some(default) => {
88+
if !has_self && default.has_self_ty() {
89+
// In an object type, there is no `Self`, and
90+
// thus if the default value references Self,
91+
// the user will be required to give an
92+
// explicit value. We can't even do the
93+
// substitution below to check without causing
94+
// an ICE. (#18956).
95+
false
96+
} else {
97+
let default = tcx.lift(&default);
98+
substs.and_then(|substs| default.subst(tcx, substs))
99+
== Some(actual)
100+
}
101+
}
102+
None => false
103+
}
104+
}).count()
105+
} else {
106+
0
107+
}
108+
}
109+
70110
pub fn parameterized<GG>(f: &mut fmt::Formatter,
71111
substs: &subst::Substs,
72112
did: DefId,
@@ -80,8 +120,8 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
80120
write!(f, "<{} as ", self_ty)?;
81121
}
82122

83-
let (fn_trait_kind, verbose, last_name) = ty::tls::with(|tcx| {
84-
let (did, last_name) = if ns == Ns::Value {
123+
let (fn_trait_kind, verbose, item_name) = ty::tls::with(|tcx| {
124+
let (did, item_name) = if ns == Ns::Value {
85125
// Try to get the impl/trait parent, if this is an
86126
// associated value item (method or constant).
87127
tcx.trait_of_item(did).or_else(|| tcx.impl_of_method(did))
@@ -90,97 +130,64 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
90130
(did, None)
91131
};
92132
write!(f, "{}", tcx.item_path_str(did))?;
93-
Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose(), last_name))
133+
Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose(), item_name))
94134
})?;
95135

96-
let mut empty = true;
97-
let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
98-
if empty {
99-
empty = false;
100-
write!(f, "{}", start)
101-
} else {
102-
write!(f, "{}", cont)
103-
}
104-
};
105-
106-
if verbose {
107-
for region in &substs.regions {
108-
start_or_continue(f, "<", ", ")?;
109-
write!(f, "{:?}", region)?;
110-
}
111-
for &ty in &substs.types {
112-
start_or_continue(f, "<", ", ")?;
113-
write!(f, "{}", ty)?;
114-
}
115-
for projection in projections {
116-
start_or_continue(f, "<", ", ")?;
117-
write!(f, "{}={}",
118-
projection.projection_ty.item_name,
119-
projection.ty)?;
120-
}
121-
return start_or_continue(f, "", ">");
122-
}
123-
124-
if fn_trait_kind.is_some() && projections.len() == 1 {
136+
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
125137
let projection_ty = projections[0].ty;
126138
if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
127139
return fn_sig(f, args, false, ty::FnConverging(projection_ty));
128140
}
129141
}
130142

131-
for &r in &substs.regions {
132-
start_or_continue(f, "<", ", ")?;
133-
let s = r.to_string();
134-
if s.is_empty() {
135-
// This happens when the value of the region
136-
// parameter is not easily serialized. This may be
137-
// because the user omitted it in the first place,
138-
// or because it refers to some block in the code,
139-
// etc. I'm not sure how best to serialize this.
140-
write!(f, "'_")?;
143+
let empty = Cell::new(true);
144+
let start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
145+
if empty.get() {
146+
empty.set(false);
147+
write!(f, "{}", start)
141148
} else {
142-
write!(f, "{}", s)?;
149+
write!(f, "{}", cont)
143150
}
151+
};
152+
let print_region = |f: &mut fmt::Formatter, region: &ty::Region| -> _ {
153+
if verbose {
154+
write!(f, "{:?}", region)
155+
} else {
156+
let s = region.to_string();
157+
if s.is_empty() {
158+
// This happens when the value of the region
159+
// parameter is not easily serialized. This may be
160+
// because the user omitted it in the first place,
161+
// or because it refers to some block in the code,
162+
// etc. I'm not sure how best to serialize this.
163+
write!(f, "'_")
164+
} else {
165+
write!(f, "{}", s)
166+
}
167+
}
168+
};
169+
170+
for region in substs.regions.get_slice(subst::TypeSpace) {
171+
start_or_continue(f, "<", ", ")?;
172+
print_region(f, region)?;
144173
}
145174

146-
// It is important to execute this conditionally, only if -Z
147-
// verbose is false. Otherwise, debug logs can sometimes cause
148-
// ICEs trying to fetch the generics early in the pipeline. This
149-
// is kind of a hacky workaround in that -Z verbose is required to
150-
// avoid those ICEs.
175+
let num_supplied_defaults = if verbose {
176+
0
177+
} else {
178+
// It is important to execute this conditionally, only if -Z
179+
// verbose is false. Otherwise, debug logs can sometimes cause
180+
// ICEs trying to fetch the generics early in the pipeline. This
181+
// is kind of a hacky workaround in that -Z verbose is required to
182+
// avoid those ICEs.
183+
ty::tls::with(|tcx| {
184+
number_of_supplied_defaults(tcx, substs, subst::TypeSpace, get_generics)
185+
})
186+
};
187+
151188
let tps = substs.types.get_slice(subst::TypeSpace);
152-
let num_defaults = ty::tls::with(|tcx| {
153-
let generics = get_generics(tcx);
154-
155-
let has_self = substs.self_ty().is_some();
156-
let ty_params = generics.types.get_slice(subst::TypeSpace);
157-
if ty_params.last().map_or(false, |def| def.default.is_some()) {
158-
let substs = tcx.lift(&substs);
159-
ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
160-
match def.default {
161-
Some(default) => {
162-
if !has_self && default.has_self_ty() {
163-
// In an object type, there is no `Self`, and
164-
// thus if the default value references Self,
165-
// the user will be required to give an
166-
// explicit value. We can't even do the
167-
// substitution below to check without causing
168-
// an ICE. (#18956).
169-
false
170-
} else {
171-
let default = tcx.lift(&default);
172-
substs.and_then(|substs| default.subst(tcx, substs)) == Some(actual)
173-
}
174-
}
175-
None => false
176-
}
177-
}).count()
178-
} else {
179-
0
180-
}
181-
});
182189

183-
for &ty in &tps[..tps.len() - num_defaults] {
190+
for &ty in &tps[..tps.len() - num_supplied_defaults] {
184191
start_or_continue(f, "<", ", ")?;
185192
write!(f, "{}", ty)?;
186193
}
@@ -196,21 +203,28 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
196203

197204
// For values, also print their name and type parameters.
198205
if ns == Ns::Value {
206+
empty.set(true);
207+
199208
if substs.self_ty().is_some() {
200209
write!(f, ">")?;
201210
}
202211

203-
if let Some(name) = last_name {
204-
write!(f, "::{}", name)?;
212+
if let Some(item_name) = item_name {
213+
write!(f, "::{}", item_name)?;
205214
}
206-
let tps = substs.types.get_slice(subst::FnSpace);
207-
if !tps.is_empty() {
208-
write!(f, "::<{}", tps[0])?;
209-
for ty in &tps[1..] {
210-
write!(f, ", {}", ty)?;
211-
}
212-
write!(f, ">")?;
215+
216+
for region in substs.regions.get_slice(subst::FnSpace) {
217+
start_or_continue(f, "::<", ", ")?;
218+
print_region(f, region)?;
219+
}
220+
221+
// FIXME: consider being smart with defaults here too
222+
for ty in substs.types.get_slice(subst::FnSpace) {
223+
start_or_continue(f, "::<", ", ")?;
224+
write!(f, "{}", ty)?;
213225
}
226+
227+
start_or_continue(f, "", ">")?;
214228
}
215229

216230
Ok(())
@@ -997,9 +1011,7 @@ impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
9971011

9981012
impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
9991013
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1000-
write!(f, "{} : {}",
1001-
self.trait_ref.self_ty(),
1002-
self.trait_ref)
1014+
write!(f, "{}: {}", self.trait_ref.self_ty(), self.trait_ref)
10031015
}
10041016
}
10051017

src/test/compile-fail/associated-types-for-unimpl-trait.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ trait Get {
1515

1616
trait Other {
1717
fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
18-
//~^ ERROR the trait bound `Self : Get` is not satisfied
18+
//~^ ERROR the trait bound `Self: Get` is not satisfied
1919
}
2020

2121
fn main() {

src/test/compile-fail/associated-types-invalid-trait-ref-issue-18865.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ trait Foo<T> {
1818

1919
fn f<T:Foo<isize>>(t: &T) {
2020
let u: <T as Foo<usize>>::Bar = t.get_bar();
21-
//~^ ERROR the trait bound `T : Foo<usize>` is not satisfied
21+
//~^ ERROR the trait bound `T: Foo<usize>` is not satisfied
2222
}
2323

2424
fn main() { }

src/test/compile-fail/associated-types-no-suitable-bound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct Struct {
1919

2020
impl Struct {
2121
fn uhoh<T>(foo: <T as Get>::Value) {}
22-
//~^ ERROR the trait bound `T : Get` is not satisfied
22+
//~^ ERROR the trait bound `T: Get` is not satisfied
2323
}
2424

2525
fn main() {

src/test/compile-fail/associated-types-no-suitable-supertrait-2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ trait Get {
2525

2626
trait Other {
2727
fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
28-
//~^ ERROR the trait bound `Self : Get` is not satisfied
28+
//~^ ERROR the trait bound `Self: Get` is not satisfied
2929
}
3030

3131
fn main() { }

src/test/compile-fail/associated-types-no-suitable-supertrait.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ trait Get {
2525

2626
trait Other {
2727
fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
28-
//~^ ERROR the trait bound `Self : Get` is not satisfied
28+
//~^ ERROR the trait bound `Self: Get` is not satisfied
2929
}
3030

3131
impl<T:Get> Other for T {
3232
fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
33-
//~^ ERROR the trait bound `(T, U) : Get` is not satisfied
33+
//~^ ERROR the trait bound `(T, U): Get` is not satisfied
3434
}
3535

3636
fn main() { }

src/test/compile-fail/associated-types-path-2.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ pub fn f1_int_uint() {
3838

3939
pub fn f1_uint_uint() {
4040
f1(2u32, 4u32);
41-
//~^ ERROR `u32 : Foo` is not satisfied
41+
//~^ ERROR `u32: Foo` is not satisfied
4242
}
4343

4444
pub fn f1_uint_int() {
4545
f1(2u32, 4i32);
46-
//~^ ERROR `u32 : Foo` is not satisfied
46+
//~^ ERROR `u32: Foo` is not satisfied
4747
}
4848

4949
pub fn f2_int() {

src/test/compile-fail/associated-types-unsized.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trait Get {
1414
}
1515

1616
fn foo<T:Get>(t: T) {
17-
let x = t.get(); //~ ERROR `<T as Get>::Value : std::marker::Sized` is not
17+
let x = t.get(); //~ ERROR `<T as Get>::Value: std::marker::Sized` is not
1818
}
1919

2020
fn main() {

src/test/compile-fail/bad-method-typaram-kind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
fn foo<T:'static>() {
12-
1.bar::<T>(); //~ ERROR `T : std::marker::Send` is not satisfied
12+
1.bar::<T>(); //~ ERROR `T: std::marker::Send` is not satisfied
1313
}
1414

1515
trait bar {

src/test/compile-fail/bad-sized.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ trait Trait {}
1212

1313
pub fn main() {
1414
let x: Vec<Trait + Sized> = Vec::new();
15-
//~^ ERROR `Trait + Sized : std::marker::Sized` is not satisfied
16-
//~| ERROR `Trait + Sized : std::marker::Sized` is not satisfied
17-
//~| ERROR `Trait + Sized : std::marker::Sized` is not satisfied
15+
//~^ ERROR `Trait + Sized: std::marker::Sized` is not satisfied
16+
//~| ERROR `Trait + Sized: std::marker::Sized` is not satisfied
17+
//~| ERROR `Trait + Sized: std::marker::Sized` is not satisfied
1818
}

src/test/compile-fail/builtin-superkinds-double-superkind.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
trait Foo : Send+Sync { }
1515

16-
impl <T: Sync+'static> Foo for (T,) { } //~ ERROR `T : std::marker::Send` is not satisfied
16+
impl <T: Sync+'static> Foo for (T,) { } //~ ERROR `T: std::marker::Send` is not satisfied
1717

18-
impl <T: Send> Foo for (T,T) { } //~ ERROR `T : std::marker::Sync` is not satisfied
18+
impl <T: Send> Foo for (T,T) { } //~ ERROR `T: std::marker::Sync` is not satisfied
1919

2020
impl <T: Send+Sync> Foo for (T,T,T) { } // (ok)
2121

src/test/compile-fail/builtin-superkinds-in-metadata.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ struct X<T>(T);
2222
impl <T:Sync> RequiresShare for X<T> { }
2323

2424
impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
25-
//~^ ERROR `T : std::marker::Send` is not satisfied
25+
//~^ ERROR `T: std::marker::Send` is not satisfied
2626

2727
fn main() { }

src/test/compile-fail/builtin-superkinds-simple.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
trait Foo : Send { }
1515

1616
impl Foo for std::rc::Rc<i8> { }
17-
//~^ ERROR `std::rc::Rc<i8> : std::marker::Send` is not satisfied
17+
//~^ ERROR `std::rc::Rc<i8>: std::marker::Send` is not satisfied
1818

1919
fn main() { }

src/test/compile-fail/builtin-superkinds-typaram-not-send.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212

1313
trait Foo : Send { }
1414

15-
impl <T: Sync+'static> Foo for T { } //~ ERROR `T : std::marker::Send` is not satisfied
15+
impl <T: Sync+'static> Foo for T { } //~ ERROR `T: std::marker::Send` is not satisfied
1616

1717
fn main() { }

0 commit comments

Comments
 (0)