diff options
-rw-r--r-- | crates/hir/src/code_model.rs | 5 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 29 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 34 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/method_resolution.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 6 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 4 |
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 | }; |
29 | use hir_ty::{ | 29 | use 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 | ||
630 | pub fn write_bounds_like_dyn_trait( | 627 | pub 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 | |||
641 | fn 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 | ||
671 | impl GenericPredicate { | 660 | impl 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() { | |||
1114 | trait Foo {} | 1114 | trait Foo {} |
1115 | 1115 | ||
1116 | impl Foo for u32 {} | 1116 | impl Foo for u32 {} |
1117 | impl dyn Foo { | 1117 | impl 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 | ||
1123 | fn main() { | 1123 | fn 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#" |
3423 | struct Foo<T>(T); | 3423 | struct 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 | ); |