about summary refs log tree commit diff
path: root/src/tools
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2024-08-22 14:35:39 +0300
committerChayim Refael Friedman <chayimfr@gmail.com>2024-08-24 23:46:32 +0300
commit737a969aa56d686ecdc9a5d689a3602ec2f7d164 (patch)
tree78955dd1a1f79779b2d26973b4e42c3501d5ec14 /src/tools
parent2c6a521bab941d77713617daa3440c7feb8255ad (diff)
downloadrust-737a969aa56d686ecdc9a5d689a3602ec2f7d164.tar.gz
rust-737a969aa56d686ecdc9a5d689a3602ec2f7d164.zip
Add helper methods to retrieve `Future::Output` and `Iterator::Item`
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs18
2 files changed, 24 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
index cdcd7208f37..166c965d14c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
@@ -74,6 +74,13 @@ impl LangItemTarget {
             _ => None,
         }
     }
+
+    pub fn as_type_alias(self) -> Option<TypeAliasId> {
+        match self {
+            LangItemTarget::TypeAlias(id) => Some(id),
+            _ => None,
+        }
+    }
 }
 
 #[derive(Default, Debug, Clone, PartialEq, Eq)]
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 1e8127161d6..2ff5f0d538a 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -78,7 +78,7 @@ use hir_ty::{
 use itertools::Itertools;
 use nameres::diagnostics::DefDiagnosticKind;
 use rustc_hash::FxHashSet;
-use span::{Edition, EditionedFileId, FileId, MacroCallId};
+use span::{Edition, EditionedFileId, FileId, MacroCallId, SyntaxContextId};
 use stdx::{impl_from, never};
 use syntax::{
     ast::{self, HasAttrs as _, HasGenericParams, HasName},
@@ -4379,6 +4379,22 @@ impl Type {
         method_resolution::implements_trait(&canonical_ty, db, &self.env, trait_)
     }
 
+    /// This does **not** resolve `IntoFuture`, only `Future`.
+    pub fn future_output(self, db: &dyn HirDatabase) -> Option<Type> {
+        let future_output =
+            db.lang_item(self.env.krate, LangItem::FutureOutput)?.as_type_alias()?;
+        self.normalize_trait_assoc_type(db, &[], future_output.into())
+    }
+
+    /// This does **not** resolve `IntoIterator`, only `Iterator`.
+    pub fn iterator_item(self, db: &dyn HirDatabase) -> Option<Type> {
+        let iterator_trait = db.lang_item(self.env.krate, LangItem::Iterator)?.as_trait()?;
+        let iterator_item = db
+            .trait_data(iterator_trait)
+            .associated_type_by_name(&Name::new_symbol(sym::Item.clone(), SyntaxContextId::ROOT))?;
+        self.normalize_trait_assoc_type(db, &[], iterator_item.into())
+    }
+
     /// Checks that particular type `ty` implements `std::ops::FnOnce`.
     ///
     /// This function can be used to check if a particular type is callable, since FnOnce is a