Fix type walking about type of async block
This commit is contained in:
parent
cc4e287bb5
commit
529c369c9b
crates
@ -1602,6 +1602,11 @@ impl Type {
|
||||
cb(type_.derived(ty.clone()));
|
||||
}
|
||||
}
|
||||
TypeCtor::OpaqueType(..) => {
|
||||
if let Some(bounds) = ty.impl_trait_bounds(db) {
|
||||
walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ use hir_def::{
|
||||
AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
|
||||
TypeParamId,
|
||||
};
|
||||
use hir_expand::name::name;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{
|
||||
@ -848,26 +847,22 @@ impl Ty {
|
||||
|
||||
pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
|
||||
match self {
|
||||
Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), parameters }) => {
|
||||
Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => {
|
||||
match opaque_ty_id {
|
||||
OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
|
||||
let krate = def.module(db.upcast()).krate;
|
||||
if let Some(future_output) = db
|
||||
if let Some(future_trait) = db
|
||||
.lang_item(krate, "future_trait".into())
|
||||
.and_then(|item| item.as_trait())
|
||||
.and_then(|trait_| {
|
||||
db.trait_data(trait_).associated_type_by_name(&name![Output])
|
||||
})
|
||||
{
|
||||
let proj = GenericPredicate::Projection(ProjectionPredicate {
|
||||
projection_ty: ProjectionTy {
|
||||
associated_ty: future_output,
|
||||
// Self type.
|
||||
parameters: Substs::single(self.clone()),
|
||||
},
|
||||
ty: parameters[0].clone(),
|
||||
// This is only used by type walking.
|
||||
// Parameters will be walked outside, and projection predicate is not used.
|
||||
// So just provide the Future trait.
|
||||
let impl_bound = GenericPredicate::Implemented(TraitRef {
|
||||
trait_: future_trait,
|
||||
substs: Substs::empty(),
|
||||
});
|
||||
Some(vec![proj])
|
||||
Some(vec![impl_bound])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -2646,6 +2646,70 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hover_async_block_impl_trait_has_goto_type_action() {
|
||||
check_actions(
|
||||
r#"
|
||||
struct S;
|
||||
fn foo() {
|
||||
let fo<|>o = async { S };
|
||||
}
|
||||
|
||||
#[prelude_import] use future::*;
|
||||
mod future {
|
||||
#[lang = "future_trait"]
|
||||
pub trait Future { type Output; }
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
[
|
||||
GoToType(
|
||||
[
|
||||
HoverGotoTypeData {
|
||||
mod_path: "test::future::Future",
|
||||
nav: NavigationTarget {
|
||||
file_id: FileId(
|
||||
1,
|
||||
),
|
||||
full_range: 101..163,
|
||||
focus_range: Some(
|
||||
140..146,
|
||||
),
|
||||
name: "Future",
|
||||
kind: TRAIT,
|
||||
container_name: None,
|
||||
description: Some(
|
||||
"pub trait Future",
|
||||
),
|
||||
docs: None,
|
||||
},
|
||||
},
|
||||
HoverGotoTypeData {
|
||||
mod_path: "test::S",
|
||||
nav: NavigationTarget {
|
||||
file_id: FileId(
|
||||
1,
|
||||
),
|
||||
full_range: 0..9,
|
||||
focus_range: Some(
|
||||
7..8,
|
||||
),
|
||||
name: "S",
|
||||
kind: STRUCT,
|
||||
container_name: None,
|
||||
description: Some(
|
||||
"struct S",
|
||||
),
|
||||
docs: None,
|
||||
},
|
||||
},
|
||||
],
|
||||
),
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
|
||||
check_actions(
|
||||
|
Loading…
x
Reference in New Issue
Block a user