mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 04:44:57 +00:00
Fix type walking about type of async block
This commit is contained in:
parent
cc4e287bb5
commit
529c369c9b
3 changed files with 78 additions and 14 deletions
|
@ -1602,6 +1602,11 @@ impl Type {
|
||||||
cb(type_.derived(ty.clone()));
|
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,
|
AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
|
||||||
TypeParamId,
|
TypeParamId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::name;
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -848,26 +847,22 @@ impl Ty {
|
||||||
|
|
||||||
pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
|
pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
|
||||||
match self {
|
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 {
|
match opaque_ty_id {
|
||||||
OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
|
OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
|
||||||
let krate = def.module(db.upcast()).krate;
|
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())
|
.lang_item(krate, "future_trait".into())
|
||||||
.and_then(|item| item.as_trait())
|
.and_then(|item| item.as_trait())
|
||||||
.and_then(|trait_| {
|
|
||||||
db.trait_data(trait_).associated_type_by_name(&name![Output])
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
let proj = GenericPredicate::Projection(ProjectionPredicate {
|
// This is only used by type walking.
|
||||||
projection_ty: ProjectionTy {
|
// Parameters will be walked outside, and projection predicate is not used.
|
||||||
associated_ty: future_output,
|
// So just provide the Future trait.
|
||||||
// Self type.
|
let impl_bound = GenericPredicate::Implemented(TraitRef {
|
||||||
parameters: Substs::single(self.clone()),
|
trait_: future_trait,
|
||||||
},
|
substs: Substs::empty(),
|
||||||
ty: parameters[0].clone(),
|
|
||||||
});
|
});
|
||||||
Some(vec![proj])
|
Some(vec![impl_bound])
|
||||||
} else {
|
} else {
|
||||||
None
|
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]
|
#[test]
|
||||||
fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
|
fn test_hover_arg_generic_impl_trait_has_goto_type_action() {
|
||||||
check_actions(
|
check_actions(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue