From 63e1e63a9160d28597a8d77fd83c43a2c90d3f6b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Sep 2019 20:39:10 +0300 Subject: start cleaning up the resolution Nameres related types, like `PerNs`, can represent unreasonable situations, like a local in a type namespace. We should clean this up, by requiring that call-site specifies the kind of resolution it expects. --- crates/ra_hir/src/resolve.rs | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir/src/resolve.rs') diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index d9bdd0e22..1ed150f5a 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -15,7 +15,7 @@ use crate::{ name::{Name, SELF_PARAM, SELF_TYPE}, nameres::{CrateDefMap, CrateModuleId, PerNs}, path::Path, - MacroDef, ModuleDef, Trait, + Enum, MacroDef, ModuleDef, Struct, Trait, }; #[derive(Debug, Clone, Default)] @@ -39,6 +39,8 @@ pub(crate) struct ExprScope { #[derive(Debug, Clone)] pub(crate) struct PathResult { /// The actual path resolution + // FIXME: `PerNs` type doesn't make sense, as not every + // Resolution variant can appear in every namespace resolution: PerNs, /// The first index in the path that we /// were unable to resolve. @@ -113,6 +115,9 @@ pub(crate) enum Scope { pub enum Resolution { /// An item Def(ModuleDef), + + // FIXME: there's no way we can syntactically confuse a local with generic + // param, so these two should not be members of the single enum /// A local binding (only value namespace) LocalBinding(PatId), /// A generic parameter @@ -121,6 +126,37 @@ pub enum Resolution { } impl Resolver { + /// Resolve known trait from std, like `std::futures::Future` + pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option { + let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?; + match res { + Resolution::Def(ModuleDef::Trait(it)) => Some(it), + _ => None, + } + } + + /// Resolve known struct from std, like `std::boxed::Box` + pub(crate) fn resolve_known_struct( + &self, + db: &impl HirDatabase, + path: &Path, + ) -> Option { + let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?; + match res { + Resolution::Def(ModuleDef::Struct(it)) => Some(it), + _ => None, + } + } + + /// Resolve known enum from std, like `std::result::Result` + pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option { + let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?; + match res { + Resolution::Def(ModuleDef::Enum(it)) => Some(it), + _ => None, + } + } + pub(crate) fn resolve_name(&self, db: &impl HirDatabase, name: &Name) -> PerNs { let mut resolution = PerNs::none(); for scope in self.scopes.iter().rev() { -- cgit v1.2.3