Skip to content

Commit 529c369

Browse files
committed
Fix type walking about type of async block
1 parent cc4e287 commit 529c369

File tree

3 files changed

+78
-14
lines changed

3 files changed

+78
-14
lines changed

crates/hir/src/code_model.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,11 @@ impl Type {
16021602
cb(type_.derived(ty.clone()));
16031603
}
16041604
}
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+
}
16051610
_ => (),
16061611
}
16071612

crates/hir_ty/src/lib.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use hir_def::{
3333
AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
3434
TypeParamId,
3535
};
36-
use hir_expand::name::name;
3736
use itertools::Itertools;
3837

3938
use crate::{
@@ -848,26 +847,22 @@ impl Ty {
848847

849848
pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
850849
match self {
851-
Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), parameters }) => {
850+
Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => {
852851
match opaque_ty_id {
853852
OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
854853
let krate = def.module(db.upcast()).krate;
855-
if let Some(future_output) = db
854+
if let Some(future_trait) = db
856855
.lang_item(krate, "future_trait".into())
857856
.and_then(|item| item.as_trait())
858-
.and_then(|trait_| {
859-
db.trait_data(trait_).associated_type_by_name(&name![Output])
860-
})
861857
{
862-
let proj = GenericPredicate::Projection(ProjectionPredicate {
863-
projection_ty: ProjectionTy {
864-
associated_ty: future_output,
865-
// Self type.
866-
parameters: Substs::single(self.clone()),
867-
},
868-
ty: parameters[0].clone(),
858+
// This is only used by type walking.
859+
// Parameters will be walked outside, and projection predicate is not used.
860+
// So just provide the Future trait.
861+
let impl_bound = GenericPredicate::Implemented(TraitRef {
862+
trait_: future_trait,
863+
substs: Substs::empty(),
869864
});
870-
Some(vec![proj])
865+
Some(vec![impl_bound])
871866
} else {
872867
None
873868
}

crates/ide/src/hover.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,6 +2646,70 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
26462646
);
26472647
}
26482648

2649+
#[test]
2650+
fn test_hover_async_block_impl_trait_has_goto_type_action() {
2651+
check_actions(
2652+
r#"
2653+
struct S;
2654+
fn foo() {
2655+
let fo<|>o = async { S };
2656+
}
2657+
2658+
#[prelude_import] use future::*;
2659+
mod 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+
26492713
#[test]
26502714
fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
26512715
check_actions(

0 commit comments

Comments
 (0)