aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authoroxalica <[email protected]>2020-09-11 18:03:28 +0100
committeroxalica <[email protected]>2020-09-11 18:08:50 +0100
commit529c369c9bc15a73e7a03260eca84ccef99ac281 (patch)
treea7b7d23711cdc583467c1ab5c5b8e608e8530861 /crates
parentcc4e287bb519565e1d6d79d6e9bba19adbe9cc77 (diff)
Fix type walking about type of async block
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/code_model.rs5
-rw-r--r--crates/hir_ty/src/lib.rs23
-rw-r--r--crates/ide/src/hover.rs64
3 files changed, 78 insertions, 14 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 613b35afd..7a9747fc7 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -1602,6 +1602,11 @@ impl Type {
1602 cb(type_.derived(ty.clone())); 1602 cb(type_.derived(ty.clone()));
1603 } 1603 }
1604 } 1604 }
1605 TypeCtor::OpaqueType(..) => {
1606 if let Some(bounds) = ty.impl_trait_bounds(db) {
1607 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1608 }
1609 }
1605 _ => (), 1610 _ => (),
1606 } 1611 }
1607 1612
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 4a7d3a0d9..f16d1fc97 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -33,7 +33,6 @@ use hir_def::{
33 AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, 33 AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
34 TypeParamId, 34 TypeParamId,
35}; 35};
36use hir_expand::name::name;
37use itertools::Itertools; 36use itertools::Itertools;
38 37
39use crate::{ 38use crate::{
@@ -848,26 +847,22 @@ impl Ty {
848 847
849 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 848 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
850 match self { 849 match self {
851 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), parameters }) => { 850 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => {
852 match opaque_ty_id { 851 match opaque_ty_id {
853 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 852 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
854 let krate = def.module(db.upcast()).krate; 853 let krate = def.module(db.upcast()).krate;
855 if let Some(future_output) = db 854 if let Some(future_trait) = db
856 .lang_item(krate, "future_trait".into()) 855 .lang_item(krate, "future_trait".into())
857 .and_then(|item| item.as_trait()) 856 .and_then(|item| item.as_trait())
858 .and_then(|trait_| {
859 db.trait_data(trait_).associated_type_by_name(&name![Output])
860 })
861 { 857 {
862 let proj = GenericPredicate::Projection(ProjectionPredicate { 858 // This is only used by type walking.
863 projection_ty: ProjectionTy { 859 // Parameters will be walked outside, and projection predicate is not used.
864 associated_ty: future_output, 860 // So just provide the Future trait.
865 // Self type. 861 let impl_bound = GenericPredicate::Implemented(TraitRef {
866 parameters: Substs::single(self.clone()), 862 trait_: future_trait,
867 }, 863 substs: Substs::empty(),
868 ty: parameters[0].clone(),
869 }); 864 });
870 Some(vec![proj]) 865 Some(vec![impl_bound])
871 } else { 866 } else {
872 None 867 None
873 } 868 }
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index efec0184e..37171cbef 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -2647,6 +2647,70 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
2647 } 2647 }
2648 2648
2649 #[test] 2649 #[test]
2650 fn test_hover_async_block_impl_trait_has_goto_type_action() {
2651 check_actions(
2652 r#"
2653struct S;
2654fn foo() {
2655 let fo<|>o = async { S };
2656}
2657
2658#[prelude_import] use future::*;
2659mod future {
2660 #[lang = "future_trait"]
2661 pub trait Future { type Output; }
2662}
2663"#,
2664 expect![[r#"
2665 [
2666 GoToType(
2667 [
2668 HoverGotoTypeData {
2669 mod_path: "test::future::Future",
2670 nav: NavigationTarget {
2671 file_id: FileId(
2672 1,
2673 ),
2674 full_range: 101..163,
2675 focus_range: Some(
2676 140..146,
2677 ),
2678 name: "Future",
2679 kind: TRAIT,
2680 container_name: None,
2681 description: Some(
2682 "pub trait Future",
2683 ),
2684 docs: None,
2685 },
2686 },
2687 HoverGotoTypeData {
2688 mod_path: "test::S",
2689 nav: NavigationTarget {
2690 file_id: FileId(
2691 1,
2692 ),
2693 full_range: 0..9,
2694 focus_range: Some(
2695 7..8,
2696 ),
2697 name: "S",
2698 kind: STRUCT,
2699 container_name: None,
2700 description: Some(
2701 "struct S",
2702 ),
2703 docs: None,
2704 },
2705 },
2706 ],
2707 ),
2708 ]
2709 "#]],
2710 );
2711 }
2712
2713 #[test]
2650 fn test_hover_arg_generic_impl_trait_has_goto_type_action() { 2714 fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
2651 check_actions( 2715 check_actions(
2652 r#" 2716 r#"