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.rs164
1 files changed, 72 insertions, 92 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index b4801cb21..1a3b9095a 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -3,9 +3,8 @@
3use std::{borrow::Cow, fmt}; 3use std::{borrow::Cow, fmt};
4 4
5use crate::{ 5use crate::{
6 db::HirDatabase, primitive, utils::generics, ApplicationTy, CallableDefId, FnSig, 6 db::HirDatabase, primitive, utils::generics, CallableDefId, FnSig, GenericPredicate, Lifetime,
7 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, 7 Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty,
8 TraitRef, Ty, TypeCtor,
9}; 8};
10use arrayvec::ArrayVec; 9use arrayvec::ArrayVec;
11use hir_def::{ 10use hir_def::{
@@ -235,39 +234,62 @@ impl HirDisplay for &Ty {
235 } 234 }
236} 235}
237 236
238impl HirDisplay for ApplicationTy { 237impl HirDisplay for ProjectionTy {
239 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 238 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
240 if f.should_truncate() { 239 if f.should_truncate() {
241 return write!(f, "{}", TYPE_HINT_TRUNCATION); 240 return write!(f, "{}", TYPE_HINT_TRUNCATION);
242 } 241 }
243 242
244 match self.ctor { 243 let trait_ = f.db.trait_data(self.trait_(f.db));
245 TypeCtor::Scalar(Scalar::Bool) => write!(f, "bool")?, 244 let first_parameter = self.parameters[0].into_displayable(
246 TypeCtor::Scalar(Scalar::Char) => write!(f, "char")?, 245 f.db,
247 TypeCtor::Scalar(Scalar::Float(t)) => { 246 f.max_size,
248 write!(f, "{}", primitive::float_ty_to_string(t))? 247 f.omit_verbose_types,
249 } 248 f.display_target,
250 TypeCtor::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, 249 );
251 TypeCtor::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, 250 write!(f, "<{} as {}", first_parameter, trait_.name)?;
252 TypeCtor::Str => write!(f, "str")?, 251 if self.parameters.len() > 1 {
253 TypeCtor::Slice => { 252 write!(f, "<")?;
254 let t = self.parameters.as_single(); 253 f.write_joined(&self.parameters[1..], ", ")?;
254 write!(f, ">")?;
255 }
256 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
257 Ok(())
258 }
259}
260
261impl HirDisplay for Ty {
262 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
263 if f.should_truncate() {
264 return write!(f, "{}", TYPE_HINT_TRUNCATION);
265 }
266
267 match self {
268 Ty::Never => write!(f, "!")?,
269 Ty::Str => write!(f, "str")?,
270 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?,
271 Ty::Scalar(Scalar::Char) => write!(f, "char")?,
272 &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?,
273 &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
274 &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
275 Ty::Slice(parameters) => {
276 let t = parameters.as_single();
255 write!(f, "[")?; 277 write!(f, "[")?;
256 t.hir_fmt(f)?; 278 t.hir_fmt(f)?;
257 write!(f, "]")?; 279 write!(f, "]")?;
258 } 280 }
259 TypeCtor::Array => { 281 Ty::Array(parameters) => {
260 let t = self.parameters.as_single(); 282 let t = parameters.as_single();
261 write!(f, "[")?; 283 write!(f, "[")?;
262 t.hir_fmt(f)?; 284 t.hir_fmt(f)?;
263 write!(f, "; _]")?; 285 write!(f, "; _]")?;
264 } 286 }
265 TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { 287 Ty::RawPtr(m, parameters) | Ty::Ref(m, parameters) => {
266 let t = self.parameters.as_single(); 288 let t = parameters.as_single();
267 let ty_display = 289 let ty_display =
268 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 290 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
269 291
270 if matches!(self.ctor, TypeCtor::RawPtr(_)) { 292 if matches!(self, Ty::RawPtr(..)) {
271 write!(f, "*{}", m.as_keyword_for_ptr())?; 293 write!(f, "*{}", m.as_keyword_for_ptr())?;
272 } else { 294 } else {
273 write!(f, "&{}", m.as_keyword_for_ref())?; 295 write!(f, "&{}", m.as_keyword_for_ref())?;
@@ -308,25 +330,23 @@ impl HirDisplay for ApplicationTy {
308 write!(f, "{}", ty_display)?; 330 write!(f, "{}", ty_display)?;
309 } 331 }
310 } 332 }
311 TypeCtor::Never => write!(f, "!")?, 333 Ty::Tuple { substs, .. } => {
312 TypeCtor::Tuple { .. } => { 334 if substs.len() == 1 {
313 let ts = &self.parameters;
314 if ts.len() == 1 {
315 write!(f, "(")?; 335 write!(f, "(")?;
316 ts[0].hir_fmt(f)?; 336 substs[0].hir_fmt(f)?;
317 write!(f, ",)")?; 337 write!(f, ",)")?;
318 } else { 338 } else {
319 write!(f, "(")?; 339 write!(f, "(")?;
320 f.write_joined(&*ts.0, ", ")?; 340 f.write_joined(&*substs.0, ", ")?;
321 write!(f, ")")?; 341 write!(f, ")")?;
322 } 342 }
323 } 343 }
324 TypeCtor::FnPtr { is_varargs, .. } => { 344 &Ty::FnPtr { is_varargs, ref substs, .. } => {
325 let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); 345 let sig = FnSig::from_fn_ptr_substs(&substs, is_varargs);
326 sig.hir_fmt(f)?; 346 sig.hir_fmt(f)?;
327 } 347 }
328 TypeCtor::FnDef(def) => { 348 &Ty::FnDef(def, ref parameters) => {
329 let sig = f.db.callable_item_signature(def).subst(&self.parameters); 349 let sig = f.db.callable_item_signature(def).subst(parameters);
330 match def { 350 match def {
331 CallableDefId::FunctionId(ff) => { 351 CallableDefId::FunctionId(ff) => {
332 write!(f, "fn {}", f.db.function_data(ff).name)? 352 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -336,7 +356,7 @@ impl HirDisplay for ApplicationTy {
336 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 356 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
337 } 357 }
338 }; 358 };
339 if self.parameters.len() > 0 { 359 if parameters.len() > 0 {
340 let generics = generics(f.db.upcast(), def.into()); 360 let generics = generics(f.db.upcast(), def.into());
341 let (parent_params, self_param, type_params, _impl_trait_params) = 361 let (parent_params, self_param, type_params, _impl_trait_params) =
342 generics.provenance_split(); 362 generics.provenance_split();
@@ -344,7 +364,7 @@ impl HirDisplay for ApplicationTy {
344 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? 364 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
345 if total_len > 0 { 365 if total_len > 0 {
346 write!(f, "<")?; 366 write!(f, "<")?;
347 f.write_joined(&self.parameters.0[..total_len], ", ")?; 367 f.write_joined(&parameters.0[..total_len], ", ")?;
348 write!(f, ">")?; 368 write!(f, ">")?;
349 } 369 }
350 } 370 }
@@ -363,7 +383,7 @@ impl HirDisplay for ApplicationTy {
363 write!(f, " -> {}", ret_display)?; 383 write!(f, " -> {}", ret_display)?;
364 } 384 }
365 } 385 }
366 TypeCtor::Adt(def_id) => { 386 &Ty::Adt(def_id, ref parameters) => {
367 match f.display_target { 387 match f.display_target {
368 DisplayTarget::Diagnostics | DisplayTarget::Test => { 388 DisplayTarget::Diagnostics | DisplayTarget::Test => {
369 let name = match def_id { 389 let name = match def_id {
@@ -388,19 +408,18 @@ impl HirDisplay for ApplicationTy {
388 } 408 }
389 } 409 }
390 410
391 if self.parameters.len() > 0 { 411 if parameters.len() > 0 {
392 let parameters_to_write = 412 let parameters_to_write =
393 if f.display_target.is_source_code() || f.omit_verbose_types() { 413 if f.display_target.is_source_code() || f.omit_verbose_types() {
394 match self 414 match self
395 .ctor
396 .as_generic_def() 415 .as_generic_def()
397 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 416 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
398 .filter(|defaults| !defaults.is_empty()) 417 .filter(|defaults| !defaults.is_empty())
399 { 418 {
400 None => self.parameters.0.as_ref(), 419 None => parameters.0.as_ref(),
401 Some(default_parameters) => { 420 Some(default_parameters) => {
402 let mut default_from = 0; 421 let mut default_from = 0;
403 for (i, parameter) in self.parameters.iter().enumerate() { 422 for (i, parameter) in parameters.iter().enumerate() {
404 match (parameter, default_parameters.get(i)) { 423 match (parameter, default_parameters.get(i)) {
405 (&Ty::Unknown, _) | (_, None) => { 424 (&Ty::Unknown, _) | (_, None) => {
406 default_from = i + 1; 425 default_from = i + 1;
@@ -408,18 +427,18 @@ impl HirDisplay for ApplicationTy {
408 (_, Some(default_parameter)) => { 427 (_, Some(default_parameter)) => {
409 let actual_default = default_parameter 428 let actual_default = default_parameter
410 .clone() 429 .clone()
411 .subst(&self.parameters.prefix(i)); 430 .subst(&parameters.prefix(i));
412 if parameter != &actual_default { 431 if parameter != &actual_default {
413 default_from = i + 1; 432 default_from = i + 1;
414 } 433 }
415 } 434 }
416 } 435 }
417 } 436 }
418 &self.parameters.0[0..default_from] 437 &parameters.0[0..default_from]
419 } 438 }
420 } 439 }
421 } else { 440 } else {
422 self.parameters.0.as_ref() 441 parameters.0.as_ref()
423 }; 442 };
424 if !parameters_to_write.is_empty() { 443 if !parameters_to_write.is_empty() {
425 write!(f, "<")?; 444 write!(f, "<")?;
@@ -428,7 +447,7 @@ impl HirDisplay for ApplicationTy {
428 } 447 }
429 } 448 }
430 } 449 }
431 TypeCtor::AssociatedType(type_alias) => { 450 &Ty::AssociatedType(type_alias, ref parameters) => {
432 let trait_ = match type_alias.lookup(f.db.upcast()).container { 451 let trait_ = match type_alias.lookup(f.db.upcast()).container {
433 AssocContainerId::TraitId(it) => it, 452 AssocContainerId::TraitId(it) => it,
434 _ => panic!("not an associated type"), 453 _ => panic!("not an associated type"),
@@ -439,30 +458,28 @@ impl HirDisplay for ApplicationTy {
439 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 458 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
440 if f.display_target.is_test() { 459 if f.display_target.is_test() {
441 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 460 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
442 if self.parameters.len() > 0 { 461 if parameters.len() > 0 {
443 write!(f, "<")?; 462 write!(f, "<")?;
444 f.write_joined(&*self.parameters.0, ", ")?; 463 f.write_joined(&*parameters.0, ", ")?;
445 write!(f, ">")?; 464 write!(f, ">")?;
446 } 465 }
447 } else { 466 } else {
448 let projection_ty = ProjectionTy { 467 let projection_ty =
449 associated_ty: type_alias, 468 ProjectionTy { associated_ty: type_alias, parameters: parameters.clone() };
450 parameters: self.parameters.clone(),
451 };
452 469
453 projection_ty.hir_fmt(f)?; 470 projection_ty.hir_fmt(f)?;
454 } 471 }
455 } 472 }
456 TypeCtor::ForeignType(type_alias) => { 473 &Ty::ForeignType(type_alias, ref parameters) => {
457 let type_alias = f.db.type_alias_data(type_alias); 474 let type_alias = f.db.type_alias_data(type_alias);
458 write!(f, "{}", type_alias.name)?; 475 write!(f, "{}", type_alias.name)?;
459 if self.parameters.len() > 0 { 476 if parameters.len() > 0 {
460 write!(f, "<")?; 477 write!(f, "<")?;
461 f.write_joined(&*self.parameters.0, ", ")?; 478 f.write_joined(&*parameters.0, ", ")?;
462 write!(f, ">")?; 479 write!(f, ">")?;
463 } 480 }
464 } 481 }
465 TypeCtor::OpaqueType(opaque_ty_id) => { 482 &Ty::OpaqueType(opaque_ty_id, ref parameters) => {
466 match opaque_ty_id { 483 match opaque_ty_id {
467 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 484 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
468 let datas = 485 let datas =
@@ -470,19 +487,19 @@ impl HirDisplay for ApplicationTy {
470 let data = (*datas) 487 let data = (*datas)
471 .as_ref() 488 .as_ref()
472 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 489 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
473 let bounds = data.subst(&self.parameters); 490 let bounds = data.subst(&parameters);
474 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 491 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
475 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 492 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
476 } 493 }
477 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 494 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
478 write!(f, "impl Future<Output = ")?; 495 write!(f, "impl Future<Output = ")?;
479 self.parameters[0].hir_fmt(f)?; 496 parameters[0].hir_fmt(f)?;
480 write!(f, ">")?; 497 write!(f, ">")?;
481 } 498 }
482 } 499 }
483 } 500 }
484 TypeCtor::Closure { .. } => { 501 Ty::Closure { substs, .. } => {
485 let sig = self.parameters[0].callable_sig(f.db); 502 let sig = substs[0].callable_sig(f.db);
486 if let Some(sig) = sig { 503 if let Some(sig) = sig {
487 if sig.params().is_empty() { 504 if sig.params().is_empty() {
488 write!(f, "||")?; 505 write!(f, "||")?;
@@ -505,43 +522,6 @@ impl HirDisplay for ApplicationTy {
505 write!(f, "{{closure}}")?; 522 write!(f, "{{closure}}")?;
506 } 523 }
507 } 524 }
508 }
509 Ok(())
510 }
511}
512
513impl HirDisplay for ProjectionTy {
514 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
515 if f.should_truncate() {
516 return write!(f, "{}", TYPE_HINT_TRUNCATION);
517 }
518
519 let trait_ = f.db.trait_data(self.trait_(f.db));
520 let first_parameter = self.parameters[0].into_displayable(
521 f.db,
522 f.max_size,
523 f.omit_verbose_types,
524 f.display_target,
525 );
526 write!(f, "<{} as {}", first_parameter, trait_.name)?;
527 if self.parameters.len() > 1 {
528 write!(f, "<")?;
529 f.write_joined(&self.parameters[1..], ", ")?;
530 write!(f, ">")?;
531 }
532 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
533 Ok(())
534 }
535}
536
537impl HirDisplay for Ty {
538 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
539 if f.should_truncate() {
540 return write!(f, "{}", TYPE_HINT_TRUNCATION);
541 }
542
543 match self {
544 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
545 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, 525 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
546 Ty::Placeholder(id) => { 526 Ty::Placeholder(id) => {
547 let generics = generics(f.db.upcast(), id.parent); 527 let generics = generics(f.db.upcast(), id.parent);