Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs53
1 files changed, 41 insertions, 12 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 29649cac94..0d2728bb61 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -58,8 +58,7 @@ use hir_def::{
CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternCrateId, FunctionId,
GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId,
LifetimeParamId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
- SyntheticSyntax, TraitAliasId, TraitId, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId,
- UnionId,
+ SyntheticSyntax, TraitAliasId, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
};
use hir_expand::{
attrs::collect_attrs, proc_macro::ProcMacroKind, AstId, MacroCallKind, RenderedExpandError,
@@ -128,7 +127,7 @@ pub use {
ImportPathConfig,
// FIXME: This is here since some queries take it as input that are used
// outside of hir.
- ModuleDefId,
+ {ModuleDefId, TraitId},
},
hir_expand::{
attrs::{Attr, AttrId},
@@ -4749,6 +4748,14 @@ impl Type {
Some((self.derived(ty.clone()), m))
}
+ pub fn add_reference(&self, mutability: Mutability) -> Type {
+ let ty_mutability = match mutability {
+ Mutability::Shared => hir_ty::Mutability::Not,
+ Mutability::Mut => hir_ty::Mutability::Mut,
+ };
+ self.derived(TyKind::Ref(ty_mutability, error_lifetime(), self.ty.clone()).intern(Interner))
+ }
+
pub fn is_slice(&self) -> bool {
matches!(self.ty.kind(Interner), TyKind::Slice(..))
}
@@ -4804,9 +4811,9 @@ impl Type {
}
/// Checks that particular type `ty` implements `std::future::IntoFuture` or
- /// `std::future::Future`.
+ /// `std::future::Future` and returns the `Output` associated type.
/// This function is used in `.await` syntax completion.
- pub fn impls_into_future(&self, db: &dyn HirDatabase) -> bool {
+ pub fn into_future_output(&self, db: &dyn HirDatabase) -> Option<Type> {
let trait_ = db
.lang_item(self.env.krate, LangItem::IntoFutureIntoFuture)
.and_then(|it| {
@@ -4818,16 +4825,18 @@ impl Type {
.or_else(|| {
let future_trait = db.lang_item(self.env.krate, LangItem::Future)?;
future_trait.as_trait()
- });
-
- let trait_ = match trait_ {
- Some(it) => it,
- None => return false,
- };
+ })?;
let canonical_ty =
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
- method_resolution::implements_trait(&canonical_ty, db, &self.env, trait_)
+ if !method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, trait_) {
+ return None;
+ }
+
+ let output_assoc_type = db
+ .trait_data(trait_)
+ .associated_type_by_name(&Name::new_symbol_root(sym::Output.clone()))?;
+ self.normalize_trait_assoc_type(db, &[], output_assoc_type.into())
}
/// This does **not** resolve `IntoFuture`, only `Future`.
@@ -4846,6 +4855,26 @@ impl Type {
self.normalize_trait_assoc_type(db, &[], iterator_item.into())
}
+ pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<Type> {
+ let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| {
+ let into_iter_fn = it.as_function()?;
+ let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?;
+ let into_iter_trait = assoc_item.container_or_implemented_trait(db)?;
+ Some(into_iter_trait.id)
+ })?;
+
+ let canonical_ty =
+ Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
+ if !method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, trait_) {
+ return None;
+ }
+
+ let into_iter_assoc_type = db
+ .trait_data(trait_)
+ .associated_type_by_name(&Name::new_symbol_root(sym::IntoIter.clone()))?;
+ self.normalize_trait_assoc_type(db, &[], into_iter_assoc_type.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