diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 9f94243062b3..e704511d655c 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2790,25 +2790,26 @@ impl Function { } let ret_type = self.ret_type(db); - let Some(impl_traits) = ret_type.as_impl_traits(db) else { return false }; let lang_items = hir_def::lang_item::lang_items(db, self.krate(db).id); let Some(future_trait_id) = lang_items.Future else { return false; }; - let Some(sized_trait_id) = lang_items.Sized else { - return false; - }; - let mut has_impl_future = false; - 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 + if let Some(impl_traits) = ret_type.as_impl_traits(db) { + let sized_trait_id = lang_items.Sized; + let mut has_impl_future = false; + return impl_traits + .filter(|t| { + let fut = t.id == future_trait_id; + has_impl_future |= fut; + !fut && sized_trait_id.map_or(true, |sid| t.id != sid) + }) + // all traits but the future trait must be auto traits + .all(|t| t.is_auto(db)) + && has_impl_future; + } + + ret_type.impls_trait(db, Trait::from(future_trait_id), &[]) } /// Does this function have `#[test]` attribute? diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 6823736d1273..9101aaffb8ed 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -520,7 +520,7 @@ pub(super) fn highlight_def( if !is_ref && func.is_unsafe_to_call(db, None, edition) { h |= HlMod::Unsafe; } - if func.is_async(db) { + if func.returns_impl_future(db) { h |= HlMod::Async; } if func.is_const(db) { @@ -706,7 +706,7 @@ fn highlight_method_call( if is_unsafe { h |= HlMod::Unsafe; } - if func.is_async(sema.db) { + if func.returns_impl_future(sema.db) { h |= HlMod::Async; } if func.is_const(sema.db) { diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_async.html b/crates/ide/src/syntax_highlighting/test_data/highlight_async.html new file mode 100644 index 000000000000..d4866679c603 --- /dev/null +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_async.html @@ -0,0 +1,96 @@ + + +
use core::future::Future;
+use core::pin::Pin;
+use core::task::{Context, Poll};
+
+async fn async_fn() {}
+
+fn returns_impl_future() -> impl Future<Output = ()> {
+ async {}
+}
+
+struct MyFuture;
+
+impl Future for MyFuture {
+ type Output = ();
+ fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+ Poll::Ready(())
+ }
+}
+
+struct Foo;
+
+impl Foo {
+ async fn async_method(&self) {}
+ fn impl_future_method(&self) -> impl Future<Output = ()> {
+ async {}
+ }
+ fn concrete_future_method(&self) -> MyFuture {
+ MyFuture
+ }
+}
+
+fn returns_concrete_future() -> MyFuture {
+ MyFuture
+}
+
+type AliasFuture = MyFuture;
+
+fn returns_alias_future() -> AliasFuture {
+ MyFuture
+}
+
+fn not_async() {}
+
+fn use_them() {
+ returns_impl_future();
+ returns_concrete_future();
+ returns_alias_future();
+ not_async();
+ let foo = Foo;
+ foo.async_method();
+ foo.impl_future_method();
+ foo.concrete_future_method();
+}
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index ab69578ed9d0..74a95642acb7 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -1584,3 +1584,67 @@ static STATIC: () = ();
false,
);
}
+
+#[test]
+fn test_async_highlighting() {
+ check_highlighting(
+ r#"
+//- minicore: future, pin, sized
+use core::future::Future;
+use core::pin::Pin;
+use core::task::{Context, Poll};
+
+async fn async_fn() {}
+
+fn returns_impl_future() -> impl Future