aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/code_model.rs5
-rw-r--r--crates/hir_ty/src/display.rs29
-rw-r--r--crates/hir_ty/src/lower.rs34
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs4
-rw-r--r--crates/hir_ty/src/tests/traits.rs6
-rw-r--r--crates/ide/src/hover.rs4
6 files changed, 45 insertions, 37 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 021e4ad31..b3218833d 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -28,7 +28,7 @@ use hir_expand::{
28}; 28};
29use hir_ty::{ 29use hir_ty::{
30 autoderef, 30 autoderef,
31 display::{write_bounds_like_dyn_trait, HirDisplayError, HirFormatter}, 31 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
32 method_resolution, 32 method_resolution,
33 traits::{FnTrait, Solution, SolutionVariables}, 33 traits::{FnTrait, Solution, SolutionVariables},
34 ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, 34 ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
@@ -1379,8 +1379,7 @@ impl HirDisplay for TypeParam {
1379 let substs = Substs::type_params(f.db, self.id.parent); 1379 let substs = Substs::type_params(f.db, self.id.parent);
1380 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); 1380 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
1381 if !(predicates.is_empty() || f.omit_verbose_types()) { 1381 if !(predicates.is_empty() || f.omit_verbose_types()) {
1382 write!(f, ": ")?; 1382 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
1383 write_bounds_like_dyn_trait(&predicates, f)?;
1384 } 1383 }
1385 Ok(()) 1384 Ok(())
1386 } 1385 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 38a043c48..271fcbfaf 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -467,8 +467,7 @@ impl HirDisplay for ApplicationTy {
467 .as_ref() 467 .as_ref()
468 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 468 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
469 let bounds = data.subst(&self.parameters); 469 let bounds = data.subst(&self.parameters);
470 write!(f, "impl ")?; 470 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
471 write_bounds_like_dyn_trait(&bounds.value, f)?;
472 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 471 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
473 } 472 }
474 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 473 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
@@ -548,10 +547,10 @@ impl HirDisplay for Ty {
548 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 547 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
549 } 548 }
550 TypeParamProvenance::ArgumentImplTrait => { 549 TypeParamProvenance::ArgumentImplTrait => {
551 write!(f, "impl ")?;
552 let bounds = f.db.generic_predicates_for_param(*id); 550 let bounds = f.db.generic_predicates_for_param(*id);
553 let substs = Substs::type_params_for_generics(&generics); 551 let substs = Substs::type_params_for_generics(&generics);
554 write_bounds_like_dyn_trait( 552 write_bounds_like_dyn_trait_with_prefix(
553 "impl",
555 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 554 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(),
556 f, 555 f,
557 )?; 556 )?;
@@ -560,8 +559,7 @@ impl HirDisplay for Ty {
560 } 559 }
561 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 560 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
562 Ty::Dyn(predicates) => { 561 Ty::Dyn(predicates) => {
563 write!(f, "dyn ")?; 562 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?;
564 write_bounds_like_dyn_trait(predicates, f)?;
565 } 563 }
566 Ty::Opaque(opaque_ty) => { 564 Ty::Opaque(opaque_ty) => {
567 match opaque_ty.opaque_ty_id { 565 match opaque_ty.opaque_ty_id {
@@ -572,8 +570,7 @@ impl HirDisplay for Ty {
572 .as_ref() 570 .as_ref()
573 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 571 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
574 let bounds = data.subst(&opaque_ty.parameters); 572 let bounds = data.subst(&opaque_ty.parameters);
575 write!(f, "impl ")?; 573 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
576 write_bounds_like_dyn_trait(&bounds.value, f)?;
577 } 574 }
578 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 575 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
579 write!(f, "{{async block}}")?; 576 write!(f, "{{async block}}")?;
@@ -627,7 +624,21 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
627 ArrayVec::from(fn_traits).into_iter().flatten().flat_map(|it| it.as_trait()) 624 ArrayVec::from(fn_traits).into_iter().flatten().flat_map(|it| it.as_trait())
628} 625}
629 626
630pub fn write_bounds_like_dyn_trait( 627pub fn write_bounds_like_dyn_trait_with_prefix(
628 prefix: &str,
629 predicates: &[GenericPredicate],
630 f: &mut HirFormatter,
631) -> Result<(), HirDisplayError> {
632 write!(f, "{}", prefix)?;
633 if !predicates.is_empty() {
634 write!(f, " ")?;
635 write_bounds_like_dyn_trait(predicates, f)
636 } else {
637 Ok(())
638 }
639}
640
641fn write_bounds_like_dyn_trait(
631 predicates: &[GenericPredicate], 642 predicates: &[GenericPredicate],
632 f: &mut HirFormatter, 643 f: &mut HirFormatter,
633) -> Result<(), HirDisplayError> { 644) -> Result<(), HirDisplayError> {
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index f9dc832bd..99b0ecf3b 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -655,17 +655,6 @@ impl TraitRef {
655 ) -> Substs { 655 ) -> Substs {
656 substs_from_path_segment(ctx, segment, Some(resolved.into()), false) 656 substs_from_path_segment(ctx, segment, Some(resolved.into()), false)
657 } 657 }
658
659 pub(crate) fn from_type_bound(
660 ctx: &TyLoweringContext<'_>,
661 bound: &TypeBound,
662 self_ty: Ty,
663 ) -> Option<TraitRef> {
664 match bound {
665 TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)),
666 TypeBound::Lifetime(_) | TypeBound::Error => None,
667 }
668 }
669} 658}
670 659
671impl GenericPredicate { 660impl GenericPredicate {
@@ -705,13 +694,22 @@ impl GenericPredicate {
705 bound: &'a TypeBound, 694 bound: &'a TypeBound,
706 self_ty: Ty, 695 self_ty: Ty,
707 ) -> impl Iterator<Item = GenericPredicate> + 'a { 696 ) -> impl Iterator<Item = GenericPredicate> + 'a {
708 let trait_ref = TraitRef::from_type_bound(ctx, bound, self_ty); 697 let mut bindings = None;
709 iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented)) 698 let trait_ref = match bound {
710 .chain( 699 TypeBound::Path(path) => {
711 trait_ref 700 bindings = TraitRef::from_path(ctx, path, Some(self_ty));
712 .into_iter() 701 Some(
713 .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)), 702 bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented),
714 ) 703 )
704 }
705 TypeBound::Lifetime(_) => None,
706 TypeBound::Error => Some(GenericPredicate::Error),
707 };
708 trait_ref.into_iter().chain(
709 bindings
710 .into_iter()
711 .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)),
712 )
715 } 713 }
716} 714}
717 715
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index 80e795fbf..659b8fce9 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -1114,14 +1114,14 @@ fn method_on_dyn_impl() {
1114trait Foo {} 1114trait Foo {}
1115 1115
1116impl Foo for u32 {} 1116impl Foo for u32 {}
1117impl dyn Foo { 1117impl dyn Foo + '_ {
1118 pub fn dyn_foo(&self) -> u32 { 1118 pub fn dyn_foo(&self) -> u32 {
1119 0 1119 0
1120 } 1120 }
1121} 1121}
1122 1122
1123fn main() { 1123fn main() {
1124 let f = &42u32 as &dyn Foo<u32>; 1124 let f = &42u32 as &dyn Foo;
1125 f.dyn_foo(); 1125 f.dyn_foo();
1126 // ^u32 1126 // ^u32
1127} 1127}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 7fce441f2..1298e5a88 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -1409,10 +1409,10 @@ fn weird_bounds() {
1409 fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} 1409 fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {}
1410 "#, 1410 "#,
1411 expect![[r#" 1411 expect![[r#"
1412 23..24 'a': impl Trait + {error} 1412 23..24 'a': impl Trait
1413 50..51 'b': impl {error} 1413 50..51 'b': impl
1414 69..70 'c': impl Trait 1414 69..70 'c': impl Trait
1415 86..87 'd': impl {error} 1415 86..87 'd': impl
1416 107..108 'e': impl {error} 1416 107..108 'e': impl {error}
1417 123..124 'f': impl Trait + {error} 1417 123..124 'f': impl Trait + {error}
1418 147..149 '{}': () 1418 147..149 '{}': ()
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 69b828f47..9a605b09d 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3417,7 +3417,7 @@ impl<T> Foo<T$0> {}
3417 ``` 3417 ```
3418 "#]], 3418 "#]],
3419 ); 3419 );
3420 // lifetimes aren't being substituted yet 3420 // lifetimes bounds arent being tracked yet
3421 check( 3421 check(
3422 r#" 3422 r#"
3423struct Foo<T>(T); 3423struct Foo<T>(T);
@@ -3427,7 +3427,7 @@ impl<T: 'static> Foo<T$0> {}
3427 *T* 3427 *T*
3428 3428
3429 ```rust 3429 ```rust
3430 T: {error} 3430 T
3431 ``` 3431 ```
3432 "#]], 3432 "#]],
3433 ); 3433 );