diff options
Diffstat (limited to 'crates/hir_ty/src/display.rs')
-rw-r--r-- | crates/hir_ty/src/display.rs | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 9d3b79be3..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> { |
@@ -190,6 +190,7 @@ impl DisplayTarget { | |||
190 | pub enum DisplaySourceCodeError { | 190 | pub enum DisplaySourceCodeError { |
191 | PathNotFound, | 191 | PathNotFound, |
192 | UnknownType, | 192 | UnknownType, |
193 | Closure, | ||
193 | } | 194 | } |
194 | 195 | ||
195 | pub enum HirDisplayError { | 196 | pub enum HirDisplayError { |
@@ -328,9 +329,9 @@ impl HirDisplay for Ty { | |||
328 | 329 | ||
329 | // FIXME: all this just to decide whether to use parentheses... | 330 | // FIXME: all this just to decide whether to use parentheses... |
330 | let datas; | 331 | let datas; |
331 | let predicates = match t.interned(&Interner) { | 332 | let predicates: Vec<_> = match t.interned(&Interner) { |
332 | TyKind::Dyn(predicates) if predicates.len() > 1 => { | 333 | TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => { |
333 | Cow::Borrowed(predicates.as_ref()) | 334 | dyn_ty.bounds.skip_binders().interned().iter().cloned().collect() |
334 | } | 335 | } |
335 | &TyKind::Alias(AliasTy::Opaque(OpaqueTy { | 336 | &TyKind::Alias(AliasTy::Opaque(OpaqueTy { |
336 | opaque_ty_id, | 337 | opaque_ty_id, |
@@ -345,17 +346,21 @@ impl HirDisplay for Ty { | |||
345 | .as_ref() | 346 | .as_ref() |
346 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 347 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
347 | let bounds = data.subst(parameters); | 348 | let bounds = data.subst(parameters); |
348 | Cow::Owned(bounds.value) | 349 | bounds.value |
349 | } else { | 350 | } else { |
350 | Cow::Borrowed(&[][..]) | 351 | Vec::new() |
351 | } | 352 | } |
352 | } | 353 | } |
353 | _ => Cow::Borrowed(&[][..]), | 354 | _ => Vec::new(), |
354 | }; | 355 | }; |
355 | 356 | ||
356 | 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 | { | ||
357 | let trait_ = trait_ref.hir_trait_id(); | 360 | let trait_ = trait_ref.hir_trait_id(); |
358 | 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 | { | ||
359 | return write!(f, "{}", ty_display); | 364 | return write!(f, "{}", ty_display); |
360 | } | 365 | } |
361 | } | 366 | } |
@@ -539,6 +544,11 @@ impl HirDisplay for Ty { | |||
539 | } | 544 | } |
540 | } | 545 | } |
541 | TyKind::Closure(.., substs) => { | 546 | TyKind::Closure(.., substs) => { |
547 | if f.display_target.is_source_code() { | ||
548 | return Err(HirDisplayError::DisplaySourceCodeError( | ||
549 | DisplaySourceCodeError::Closure, | ||
550 | )); | ||
551 | } | ||
542 | let sig = substs[0].callable_sig(f.db); | 552 | let sig = substs[0].callable_sig(f.db); |
543 | if let Some(sig) = sig { | 553 | if let Some(sig) = sig { |
544 | if sig.params().is_empty() { | 554 | if sig.params().is_empty() { |
@@ -577,7 +587,7 @@ impl HirDisplay for Ty { | |||
577 | .generic_predicates(id.parent) | 587 | .generic_predicates(id.parent) |
578 | .into_iter() | 588 | .into_iter() |
579 | .map(|pred| pred.clone().subst(&substs)) | 589 | .map(|pred| pred.clone().subst(&substs)) |
580 | .filter(|wc| match &wc { | 590 | .filter(|wc| match &wc.skip_binders() { |
581 | WhereClause::Implemented(tr) => tr.self_type_parameter() == self, | 591 | WhereClause::Implemented(tr) => tr.self_type_parameter() == self, |
582 | WhereClause::AliasEq(AliasEq { | 592 | WhereClause::AliasEq(AliasEq { |
583 | alias: AliasTy::Projection(proj), | 593 | alias: AliasTy::Projection(proj), |
@@ -591,8 +601,12 @@ impl HirDisplay for Ty { | |||
591 | } | 601 | } |
592 | } | 602 | } |
593 | TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, | 603 | TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, |
594 | TyKind::Dyn(predicates) => { | 604 | TyKind::Dyn(dyn_ty) => { |
595 | 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 | )?; | ||
596 | } | 610 | } |
597 | TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, | 611 | TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, |
598 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { | 612 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
@@ -661,7 +675,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai | |||
661 | 675 | ||
662 | pub fn write_bounds_like_dyn_trait_with_prefix( | 676 | pub fn write_bounds_like_dyn_trait_with_prefix( |
663 | prefix: &str, | 677 | prefix: &str, |
664 | predicates: &[WhereClause], | 678 | predicates: &[QuantifiedWhereClause], |
665 | f: &mut HirFormatter, | 679 | f: &mut HirFormatter, |
666 | ) -> Result<(), HirDisplayError> { | 680 | ) -> Result<(), HirDisplayError> { |
667 | write!(f, "{}", prefix)?; | 681 | write!(f, "{}", prefix)?; |
@@ -674,7 +688,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix( | |||
674 | } | 688 | } |
675 | 689 | ||
676 | fn write_bounds_like_dyn_trait( | 690 | fn write_bounds_like_dyn_trait( |
677 | predicates: &[WhereClause], | 691 | predicates: &[QuantifiedWhereClause], |
678 | f: &mut HirFormatter, | 692 | f: &mut HirFormatter, |
679 | ) -> Result<(), HirDisplayError> { | 693 | ) -> Result<(), HirDisplayError> { |
680 | // Note: This code is written to produce nice results (i.e. | 694 | // Note: This code is written to produce nice results (i.e. |
@@ -687,7 +701,7 @@ fn write_bounds_like_dyn_trait( | |||
687 | let mut angle_open = false; | 701 | let mut angle_open = false; |
688 | let mut is_fn_trait = false; | 702 | let mut is_fn_trait = false; |
689 | for p in predicates.iter() { | 703 | for p in predicates.iter() { |
690 | match p { | 704 | match p.skip_binders() { |
691 | WhereClause::Implemented(trait_ref) => { | 705 | WhereClause::Implemented(trait_ref) => { |
692 | let trait_ = trait_ref.hir_trait_id(); | 706 | let trait_ = trait_ref.hir_trait_id(); |
693 | if !is_fn_trait { | 707 | if !is_fn_trait { |