diff options
Diffstat (limited to 'crates/hir_ty/src/display.rs')
-rw-r--r-- | crates/hir_ty/src/display.rs | 59 |
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 | ||
3 | use std::{borrow::Cow, fmt}; | 3 | use std::fmt; |
4 | 4 | ||
5 | use arrayvec::ArrayVec; | 5 | use arrayvec::ArrayVec; |
6 | use chalk_ir::Mutability; | 6 | use 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 | ||
26 | pub struct HirFormatter<'a> { | 26 | pub 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 | ||
659 | pub fn write_bounds_like_dyn_trait_with_prefix( | 676 | pub 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 | ||
673 | fn write_bounds_like_dyn_trait( | 690 | fn 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 { |