mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 20:42:04 +00:00
Complete desugared and resugared async fn in trait impls
This commit is contained in:
parent
18feb726be
commit
eb64cc8c35
5 changed files with 267 additions and 87 deletions
|
@ -2207,51 +2207,33 @@ impl Function {
|
|||
db.function_data(self.id).is_async()
|
||||
}
|
||||
|
||||
/// Whether this function is a `fn` that returns `impl Future`.
|
||||
pub fn is_desugar_async(self, db: &dyn HirDatabase) -> bool {
|
||||
if self.is_async(db) || self.is_const(db) {
|
||||
return false;
|
||||
pub fn returns_impl_future(self, db: &dyn HirDatabase) -> bool {
|
||||
if self.is_async(db) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let Some(impl_traits) = self.ret_type(db).as_impl_traits(db) else { return false };
|
||||
|
||||
let Some(future_trait_id) =
|
||||
db.lang_item(self.ty(db).env.krate, LangItem::Future).and_then(|t| t.as_trait())
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let Some(size_trait_id) =
|
||||
let Some(sized_trait_id) =
|
||||
db.lang_item(self.ty(db).env.krate, LangItem::Sized).and_then(|t| t.as_trait())
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let Some(sync_trait_id) =
|
||||
db.lang_item(self.ty(db).env.krate, LangItem::Sync).and_then(|t| t.as_trait())
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
||||
// TODO: There's no `LangItem::Send`. How do we get the id of `Send` trait?
|
||||
// let Some(send_trait_id) = db.lang_item(self.ty(db).env.krate, LangItem::Send).and_then(|t| t.as_trait()) else {
|
||||
// eprint!("no future_trait_id\n");
|
||||
// return false
|
||||
// };
|
||||
|
||||
let allowed_to_leaked_types = vec![size_trait_id, sync_trait_id];
|
||||
|
||||
let mut has_impl_future = false;
|
||||
let mut has_types_not_allow_to_leaked = false;
|
||||
for impl_trait in impl_traits {
|
||||
if impl_trait.id == future_trait_id {
|
||||
has_impl_future = true;
|
||||
} else if !allowed_to_leaked_types.contains(&impl_trait.id) {
|
||||
has_types_not_allow_to_leaked = true;
|
||||
}
|
||||
}
|
||||
|
||||
has_impl_future && !has_types_not_allow_to_leaked
|
||||
impl_traits
|
||||
.filter(|t| {
|
||||
let fut = t.id == future_trait_id;
|
||||
has_impl_future |= fut;
|
||||
!fut && t.id != sized_trait_id
|
||||
})
|
||||
// all traits but the future trait must be auto traits
|
||||
.all(|t| t.is_auto(db))
|
||||
&& has_impl_future
|
||||
}
|
||||
|
||||
/// Does this function have `#[test]` attribute?
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue