aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/display.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/display.rs')
-rw-r--r--crates/hir_ty/src/display.rs149
1 files changed, 105 insertions, 44 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index d2e151f25..14e8c0633 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -26,6 +26,20 @@ pub trait HirDisplay {
26 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError>; 26 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError>;
27 27
28 /// Returns a `Display`able type that is human-readable. 28 /// Returns a `Display`able type that is human-readable.
29 fn into_displayable<'a>(
30 &'a self,
31 db: &'a dyn HirDatabase,
32 max_size: Option<usize>,
33 omit_verbose_types: bool,
34 display_target: DisplayTarget,
35 ) -> HirDisplayWrapper<'a, Self>
36 where
37 Self: Sized,
38 {
39 HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target }
40 }
41
42 /// Returns a `Display`able type that is human-readable.
29 /// Use this for showing types to the user (e.g. diagnostics) 43 /// Use this for showing types to the user (e.g. diagnostics)
30 fn display<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self> 44 fn display<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
31 where 45 where
@@ -82,6 +96,20 @@ pub trait HirDisplay {
82 }; 96 };
83 Ok(result) 97 Ok(result)
84 } 98 }
99
100 /// Returns a String representation of `self` for test purposes
101 fn display_test<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
102 where
103 Self: Sized,
104 {
105 HirDisplayWrapper {
106 db,
107 t: self,
108 max_size: None,
109 omit_verbose_types: false,
110 display_target: DisplayTarget::Test,
111 }
112 }
85} 113}
86 114
87impl<'a> HirFormatter<'a> { 115impl<'a> HirFormatter<'a> {
@@ -126,7 +154,7 @@ impl<'a> HirFormatter<'a> {
126} 154}
127 155
128#[derive(Clone, Copy)] 156#[derive(Clone, Copy)]
129enum DisplayTarget { 157pub enum DisplayTarget {
130 /// Display types for inlays, doc popups, autocompletion, etc... 158 /// Display types for inlays, doc popups, autocompletion, etc...
131 /// Showing `{unknown}` or not qualifying paths is fine here. 159 /// Showing `{unknown}` or not qualifying paths is fine here.
132 /// There's no reason for this to fail. 160 /// There's no reason for this to fail.
@@ -134,12 +162,17 @@ enum DisplayTarget {
134 /// Display types for inserting them in source files. 162 /// Display types for inserting them in source files.
135 /// The generated code should compile, so paths need to be qualified. 163 /// The generated code should compile, so paths need to be qualified.
136 SourceCode { module_id: ModuleId }, 164 SourceCode { module_id: ModuleId },
165 /// Only for test purpose to keep real types
166 Test,
137} 167}
138 168
139impl DisplayTarget { 169impl DisplayTarget {
140 fn is_source_code(&self) -> bool { 170 fn is_source_code(&self) -> bool {
141 matches!(self, Self::SourceCode {..}) 171 matches!(self, Self::SourceCode {..})
142 } 172 }
173 fn is_test(&self) -> bool {
174 matches!(self, Self::Test)
175 }
143} 176}
144 177
145#[derive(Debug)] 178#[derive(Debug)]
@@ -213,32 +246,32 @@ impl HirDisplay for ApplicationTy {
213 TypeCtor::Str => write!(f, "str")?, 246 TypeCtor::Str => write!(f, "str")?,
214 TypeCtor::Slice => { 247 TypeCtor::Slice => {
215 let t = self.parameters.as_single(); 248 let t = self.parameters.as_single();
216 write!(f, "[{}]", t.display(f.db))?; 249 write!(f, "[")?;
250 t.hir_fmt(f)?;
251 write!(f, "]")?;
217 } 252 }
218 TypeCtor::Array => { 253 TypeCtor::Array => {
219 let t = self.parameters.as_single(); 254 let t = self.parameters.as_single();
220 write!(f, "[{}; _]", t.display(f.db))?; 255 write!(f, "[")?;
256 t.hir_fmt(f)?;
257 write!(f, "; _]")?;
221 } 258 }
222 TypeCtor::RawPtr(m) => { 259 TypeCtor::RawPtr(m) => {
223 let t = self.parameters.as_single(); 260 let t = self.parameters.as_single();
224 let ty_display = t.display(f.db);
225 261
226 write!(f, "*{}", m.as_keyword_for_ptr())?; 262 write!(f, "*{}", m.as_keyword_for_ptr())?;
227 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) { 263 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) {
228 write!(f, "(")?; 264 write!(f, "(")?;
229 write!(f, "{}", ty_display)?; 265 t.hir_fmt(f)?;
230 write!(f, ")")?; 266 write!(f, ")")?;
231 } else { 267 } else {
232 write!(f, "{}", ty_display)?; 268 t.hir_fmt(f)?;
233 } 269 }
234 } 270 }
235 TypeCtor::Ref(m) => { 271 TypeCtor::Ref(m) => {
236 let t = self.parameters.as_single(); 272 let t = self.parameters.as_single();
237 let ty_display = if f.omit_verbose_types() { 273 let ty_display =
238 t.display_truncated(f.db, f.max_size) 274 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
239 } else {
240 t.display(f.db)
241 };
242 275
243 write!(f, "&{}", m.as_keyword_for_ref())?; 276 write!(f, "&{}", m.as_keyword_for_ref())?;
244 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) { 277 if matches!(t, Ty::Dyn(predicates) if predicates.len() > 1) {
@@ -253,7 +286,9 @@ impl HirDisplay for ApplicationTy {
253 TypeCtor::Tuple { .. } => { 286 TypeCtor::Tuple { .. } => {
254 let ts = &self.parameters; 287 let ts = &self.parameters;
255 if ts.len() == 1 { 288 if ts.len() == 1 {
256 write!(f, "({},)", ts[0].display(f.db))?; 289 write!(f, "(")?;
290 ts[0].hir_fmt(f)?;
291 write!(f, ",)")?;
257 } else { 292 } else {
258 write!(f, "(")?; 293 write!(f, "(")?;
259 f.write_joined(&*ts.0, ", ")?; 294 f.write_joined(&*ts.0, ", ")?;
@@ -274,11 +309,12 @@ impl HirDisplay for ApplicationTy {
274 write!(f, ")")?; 309 write!(f, ")")?;
275 let ret = sig.ret(); 310 let ret = sig.ret();
276 if *ret != Ty::unit() { 311 if *ret != Ty::unit() {
277 let ret_display = if f.omit_verbose_types() { 312 let ret_display = ret.into_displayable(
278 ret.display_truncated(f.db, f.max_size) 313 f.db,
279 } else { 314 f.max_size,
280 ret.display(f.db) 315 f.omit_verbose_types,
281 }; 316 f.display_target,
317 );
282 write!(f, " -> {}", ret_display)?; 318 write!(f, " -> {}", ret_display)?;
283 } 319 }
284 } 320 }
@@ -310,17 +346,19 @@ impl HirDisplay for ApplicationTy {
310 write!(f, ")")?; 346 write!(f, ")")?;
311 let ret = sig.ret(); 347 let ret = sig.ret();
312 if *ret != Ty::unit() { 348 if *ret != Ty::unit() {
313 let ret_display = if f.omit_verbose_types() { 349 let ret_display = ret.into_displayable(
314 ret.display_truncated(f.db, f.max_size) 350 f.db,
315 } else { 351 f.max_size,
316 ret.display(f.db) 352 f.omit_verbose_types,
317 }; 353 f.display_target,
354 );
355
318 write!(f, " -> {}", ret_display)?; 356 write!(f, " -> {}", ret_display)?;
319 } 357 }
320 } 358 }
321 TypeCtor::Adt(def_id) => { 359 TypeCtor::Adt(def_id) => {
322 match f.display_target { 360 match f.display_target {
323 DisplayTarget::Diagnostics => { 361 DisplayTarget::Diagnostics | DisplayTarget::Test => {
324 let name = match def_id { 362 let name = match def_id {
325 AdtId::StructId(it) => f.db.struct_data(it).name.clone(), 363 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
326 AdtId::UnionId(it) => f.db.union_data(it).name.clone(), 364 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
@@ -389,12 +427,23 @@ impl HirDisplay for ApplicationTy {
389 _ => panic!("not an associated type"), 427 _ => panic!("not an associated type"),
390 }; 428 };
391 let trait_ = f.db.trait_data(trait_); 429 let trait_ = f.db.trait_data(trait_);
392 let type_alias = f.db.type_alias_data(type_alias); 430 let type_alias_data = f.db.type_alias_data(type_alias);
393 write!(f, "{}::{}", trait_.name, type_alias.name)?; 431
394 if self.parameters.len() > 0 { 432 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
395 write!(f, "<")?; 433 if f.display_target.is_test() {
396 f.write_joined(&*self.parameters.0, ", ")?; 434 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
397 write!(f, ">")?; 435 if self.parameters.len() > 0 {
436 write!(f, "<")?;
437 f.write_joined(&*self.parameters.0, ", ")?;
438 write!(f, ">")?;
439 }
440 } else {
441 let projection_ty = ProjectionTy {
442 associated_ty: type_alias,
443 parameters: self.parameters.clone(),
444 };
445
446 projection_ty.hir_fmt(f)?;
398 } 447 }
399 } 448 }
400 TypeCtor::ForeignType(type_alias) => { 449 TypeCtor::ForeignType(type_alias) => {
@@ -439,11 +488,12 @@ impl HirDisplay for ApplicationTy {
439 write!(f, "|")?; 488 write!(f, "|")?;
440 }; 489 };
441 490
442 let ret_display = if f.omit_verbose_types() { 491 let ret_display = sig.ret().into_displayable(
443 sig.ret().display_truncated(f.db, f.max_size) 492 f.db,
444 } else { 493 f.max_size,
445 sig.ret().display(f.db) 494 f.omit_verbose_types,
446 }; 495 f.display_target,
496 );
447 write!(f, " -> {}", ret_display)?; 497 write!(f, " -> {}", ret_display)?;
448 } else { 498 } else {
449 write!(f, "{{closure}}")?; 499 write!(f, "{{closure}}")?;
@@ -461,7 +511,13 @@ impl HirDisplay for ProjectionTy {
461 } 511 }
462 512
463 let trait_ = f.db.trait_data(self.trait_(f.db)); 513 let trait_ = f.db.trait_data(self.trait_(f.db));
464 write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_.name)?; 514 let first_parameter = self.parameters[0].into_displayable(
515 f.db,
516 f.max_size,
517 f.omit_verbose_types,
518 f.display_target,
519 );
520 write!(f, "<{} as {}", first_parameter, trait_.name)?;
465 if self.parameters.len() > 1 { 521 if self.parameters.len() > 1 {
466 write!(f, "<")?; 522 write!(f, "<")?;
467 f.write_joined(&self.parameters[1..], ", ")?; 523 f.write_joined(&self.parameters[1..], ", ")?;
@@ -640,10 +696,10 @@ impl HirDisplay for GenericPredicate {
640 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; 696 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
641 write!( 697 write!(
642 f, 698 f,
643 ">::{} = {}", 699 ">::{} = ",
644 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, 700 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name,
645 projection_pred.ty.display(f.db)
646 )?; 701 )?;
702 projection_pred.ty.hir_fmt(f)?;
647 } 703 }
648 GenericPredicate::Error => write!(f, "{{error}}")?, 704 GenericPredicate::Error => write!(f, "{{error}}")?,
649 } 705 }
@@ -654,13 +710,18 @@ impl HirDisplay for GenericPredicate {
654impl HirDisplay for Obligation { 710impl HirDisplay for Obligation {
655 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 711 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
656 match self { 712 match self {
657 Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)), 713 Obligation::Trait(tr) => {
658 Obligation::Projection(proj) => write!( 714 write!(f, "Implements(")?;
659 f, 715 tr.hir_fmt(f)?;
660 "Normalize({} => {})", 716 write!(f, ")")
661 proj.projection_ty.display(f.db), 717 }
662 proj.ty.display(f.db) 718 Obligation::Projection(proj) => {
663 ), 719 write!(f, "Normalize(")?;
720 proj.projection_ty.hir_fmt(f)?;
721 write!(f, " => ")?;
722 proj.ty.hir_fmt(f)?;
723 write!(f, ")")
724 }
664 } 725 }
665 } 726 }
666} 727}