From 8c2670026a4c864a67a06bab654e203ed068f021 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 28 Apr 2020 00:40:32 +0200 Subject: Complete assoc. items on type parameters --- crates/ra_hir/src/code_model.rs | 10 +++++++++ crates/ra_hir/src/semantics.rs | 47 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 3fb419571..af59aa1b6 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -953,6 +953,16 @@ impl TypeParam { pub fn module(self, db: &dyn HirDatabase) -> Module { self.id.parent.module(db.upcast()).into() } + + pub fn ty(self, db: &dyn HirDatabase) -> Type { + let resolver = self.id.parent.resolver(db.upcast()); + let environment = TraitEnvironment::lower(db, &resolver); + let ty = Ty::Placeholder(self.id); + Type { + krate: self.id.parent.module(db.upcast()).krate, + ty: InEnvironment { value: ty, environment }, + } + } } // FIXME: rename from `ImplDef` to `Impl` diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 86bfb416c..687f83f60 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -9,6 +9,7 @@ use hir_def::{ AsMacroCall, TraitId, }; use hir_expand::ExpansionInfo; +use hir_ty::associated_types; use itertools::Itertools; use ra_db::{FileId, FileRange}; use ra_prof::profile; @@ -24,8 +25,9 @@ use crate::{ semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{resolve_hir_path, SourceAnalyzer}, AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef, - Name, Origin, Path, ScopeDef, Trait, Type, TypeParam, + Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, }; +use resolver::TypeNs; #[derive(Debug, Clone, PartialEq, Eq)] pub enum PathResolution { @@ -40,6 +42,49 @@ pub enum PathResolution { AssocItem(AssocItem), } +impl PathResolution { + fn in_type_ns(self) -> Option { + match self { + PathResolution::Def(ModuleDef::Adt(adt)) => Some(TypeNs::AdtId(adt.into())), + PathResolution::Def(ModuleDef::BuiltinType(builtin)) => { + Some(TypeNs::BuiltinType(builtin)) + } + PathResolution::Def(ModuleDef::Const(_)) => None, + PathResolution::Def(ModuleDef::EnumVariant(_)) => None, + PathResolution::Def(ModuleDef::Function(_)) => None, + PathResolution::Def(ModuleDef::Module(_)) => None, + PathResolution::Def(ModuleDef::Static(_)) => None, + PathResolution::Def(ModuleDef::Trait(_)) => None, + PathResolution::Def(ModuleDef::TypeAlias(alias)) => { + Some(TypeNs::TypeAliasId(alias.into())) + } + PathResolution::Local(_) => None, + PathResolution::TypeParam(param) => Some(TypeNs::GenericParam(param.into())), + PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType(impl_def.into())), + PathResolution::Macro(_) => None, + PathResolution::AssocItem(AssocItem::Const(_)) => None, + PathResolution::AssocItem(AssocItem::Function(_)) => None, + PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => { + Some(TypeNs::TypeAliasId(alias.into())) + } + } + } + + /// Returns an iterator over associated types that may be specified after this path (using + /// `Ty::Assoc` syntax). + pub fn assoc_type_shorthand_candidates( + &self, + db: &dyn HirDatabase, + mut cb: impl FnMut(TypeAlias) -> Option, + ) -> Option { + if let Some(res) = self.clone().in_type_ns() { + associated_types(db, res, |_, _, id| cb(id.into())) + } else { + None + } + } +} + /// Primary API to get semantic information, like types, from syntax trees. pub struct Semantics<'db, DB> { pub db: &'db DB, -- cgit v1.2.3