diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 8f747e397c87..00171233133f 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2403,25 +2403,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.is_none_or(|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 92daacd6d314..abc3644f4db6 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 7a3d71f519f8..7e4ee42970f5 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -1666,3 +1666,67 @@ macro_rules! bar {
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