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.rs59
1 files changed, 38 insertions, 21 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 981ba564d..6149067c7 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{borrow::Cow, fmt}; 3use std::fmt;
4 4
5use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability; 6use chalk_ir::Mutability;
@@ -20,7 +20,7 @@ use crate::{
20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, 20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, 21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, 22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
23 ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, 23 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
24}; 24};
25 25
26pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -329,9 +329,9 @@ impl HirDisplay for Ty {
329 329
330 // FIXME: all this just to decide whether to use parentheses... 330 // FIXME: all this just to decide whether to use parentheses...
331 let datas; 331 let datas;
332 let predicates = match t.interned(&Interner) { 332 let predicates: Vec<_> = match t.interned(&Interner) {
333 TyKind::Dyn(predicates) if predicates.len() > 1 => { 333 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
334 Cow::Borrowed(predicates.as_ref()) 334 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect()
335 } 335 }
336 &TyKind::Alias(AliasTy::Opaque(OpaqueTy { 336 &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
337 opaque_ty_id, 337 opaque_ty_id,
@@ -346,17 +346,21 @@ impl HirDisplay for Ty {
346 .as_ref() 346 .as_ref()
347 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 347 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
348 let bounds = data.subst(parameters); 348 let bounds = data.subst(parameters);
349 Cow::Owned(bounds.value) 349 bounds.value
350 } else { 350 } else {
351 Cow::Borrowed(&[][..]) 351 Vec::new()
352 } 352 }
353 } 353 }
354 _ => Cow::Borrowed(&[][..]), 354 _ => Vec::new(),
355 }; 355 };
356 356
357 if let [WhereClause::Implemented(trait_ref), _] = predicates.as_ref() { 357 if let Some(WhereClause::Implemented(trait_ref)) =
358 predicates.get(0).map(|b| b.skip_binders())
359 {
358 let trait_ = trait_ref.hir_trait_id(); 360 let trait_ = trait_ref.hir_trait_id();
359 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) { 361 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
362 && predicates.len() <= 2
363 {
360 return write!(f, "{}", ty_display); 364 return write!(f, "{}", ty_display);
361 } 365 }
362 } 366 }
@@ -577,19 +581,32 @@ impl HirDisplay for Ty {
577 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 581 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
578 } 582 }
579 TypeParamProvenance::ArgumentImplTrait => { 583 TypeParamProvenance::ArgumentImplTrait => {
580 let bounds = f.db.generic_predicates_for_param(id);
581 let substs = Substitution::type_params_for_generics(f.db, &generics); 584 let substs = Substitution::type_params_for_generics(f.db, &generics);
582 write_bounds_like_dyn_trait_with_prefix( 585 let bounds = f
583 "impl", 586 .db
584 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 587 .generic_predicates(id.parent)
585 f, 588 .into_iter()
586 )?; 589 .map(|pred| pred.clone().subst(&substs))
590 .filter(|wc| match &wc.skip_binders() {
591 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
592 WhereClause::AliasEq(AliasEq {
593 alias: AliasTy::Projection(proj),
594 ty: _,
595 }) => proj.self_type_parameter() == self,
596 _ => false,
597 })
598 .collect::<Vec<_>>();
599 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
587 } 600 }
588 } 601 }
589 } 602 }
590 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 603 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
591 TyKind::Dyn(predicates) => { 604 TyKind::Dyn(dyn_ty) => {
592 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 605 write_bounds_like_dyn_trait_with_prefix(
606 "dyn",
607 dyn_ty.bounds.skip_binders().interned(),
608 f,
609 )?;
593 } 610 }
594 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, 611 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
595 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { 612 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
@@ -658,7 +675,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
658 675
659pub fn write_bounds_like_dyn_trait_with_prefix( 676pub fn write_bounds_like_dyn_trait_with_prefix(
660 prefix: &str, 677 prefix: &str,
661 predicates: &[WhereClause], 678 predicates: &[QuantifiedWhereClause],
662 f: &mut HirFormatter, 679 f: &mut HirFormatter,
663) -> Result<(), HirDisplayError> { 680) -> Result<(), HirDisplayError> {
664 write!(f, "{}", prefix)?; 681 write!(f, "{}", prefix)?;
@@ -671,7 +688,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
671} 688}
672 689
673fn write_bounds_like_dyn_trait( 690fn write_bounds_like_dyn_trait(
674 predicates: &[WhereClause], 691 predicates: &[QuantifiedWhereClause],
675 f: &mut HirFormatter, 692 f: &mut HirFormatter,
676) -> Result<(), HirDisplayError> { 693) -> Result<(), HirDisplayError> {
677 // Note: This code is written to produce nice results (i.e. 694 // Note: This code is written to produce nice results (i.e.
@@ -684,7 +701,7 @@ fn write_bounds_like_dyn_trait(
684 let mut angle_open = false; 701 let mut angle_open = false;
685 let mut is_fn_trait = false; 702 let mut is_fn_trait = false;
686 for p in predicates.iter() { 703 for p in predicates.iter() {
687 match p { 704 match p.skip_binders() {
688 WhereClause::Implemented(trait_ref) => { 705 WhereClause::Implemented(trait_ref) => {
689 let trait_ = trait_ref.hir_trait_id(); 706 let trait_ = trait_ref.hir_trait_id();
690 if !is_fn_trait { 707 if !is_fn_trait {