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.rs46
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
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> {
@@ -190,6 +190,7 @@ impl DisplayTarget {
190pub enum DisplaySourceCodeError { 190pub enum DisplaySourceCodeError {
191 PathNotFound, 191 PathNotFound,
192 UnknownType, 192 UnknownType,
193 Closure,
193} 194}
194 195
195pub enum HirDisplayError { 196pub 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
662pub fn write_bounds_like_dyn_trait_with_prefix( 676pub 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
676fn write_bounds_like_dyn_trait( 690fn 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 {