aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-09-12 18:39:10 +0100
committerAleksey Kladov <[email protected]>2019-09-12 19:34:22 +0100
commit63e1e63a9160d28597a8d77fd83c43a2c90d3f6b (patch)
tree381f2d4a92db5cdfd35c9e76d5c6b11bcb247c41 /crates/ra_hir/src
parent5c09c5949a94012b5ae95735dc8c086efd5039e4 (diff)
start cleaning up the resolution
Nameres related types, like `PerNs<Resolution>`, 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.
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr/validation.rs11
-rw-r--r--crates/ra_hir/src/resolve.rs38
-rw-r--r--crates/ra_hir/src/source_binder.rs11
-rw-r--r--crates/ra_hir/src/ty/infer.rs46
-rw-r--r--crates/ra_hir/src/ty/lower.rs2
5 files changed, 59 insertions, 49 deletions
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs
index 6a22e1318..c985dbdad 100644
--- a/crates/ra_hir/src/expr/validation.rs
+++ b/crates/ra_hir/src/expr/validation.rs
@@ -11,7 +11,7 @@ use crate::{
11 name, 11 name,
12 path::{PathKind, PathSegment}, 12 path::{PathKind, PathSegment},
13 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, 13 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor},
14 Function, ModuleDef, Name, Path, PerNs, Resolution, 14 Function, Name, Path,
15}; 15};
16 16
17use super::{Expr, ExprId, RecordLitField}; 17use super::{Expr, ExprId, RecordLitField};
@@ -119,11 +119,10 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
119 }; 119 };
120 120
121 let resolver = self.func.resolver(db); 121 let resolver = self.func.resolver(db);
122 let std_result_enum = 122 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) {
123 match resolver.resolve_path_segments(db, &std_result_path).into_fully_resolved() { 123 Some(it) => it,
124 PerNs { types: Some(Resolution::Def(ModuleDef::Enum(e))), .. } => e, 124 _ => return,
125 _ => return, 125 };
126 };
127 126
128 let std_result_ctor = TypeCtor::Adt(AdtDef::Enum(std_result_enum)); 127 let std_result_ctor = TypeCtor::Adt(AdtDef::Enum(std_result_enum));
129 let params = match &mismatch.expected { 128 let params = match &mismatch.expected {
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::{
15 name::{Name, SELF_PARAM, SELF_TYPE}, 15 name::{Name, SELF_PARAM, SELF_TYPE},
16 nameres::{CrateDefMap, CrateModuleId, PerNs}, 16 nameres::{CrateDefMap, CrateModuleId, PerNs},
17 path::Path, 17 path::Path,
18 MacroDef, ModuleDef, Trait, 18 Enum, MacroDef, ModuleDef, Struct, Trait,
19}; 19};
20 20
21#[derive(Debug, Clone, Default)] 21#[derive(Debug, Clone, Default)]
@@ -39,6 +39,8 @@ pub(crate) struct ExprScope {
39#[derive(Debug, Clone)] 39#[derive(Debug, Clone)]
40pub(crate) struct PathResult { 40pub(crate) struct PathResult {
41 /// The actual path resolution 41 /// The actual path resolution
42 // FIXME: `PerNs<Resolution>` type doesn't make sense, as not every
43 // Resolution variant can appear in every namespace
42 resolution: PerNs<Resolution>, 44 resolution: PerNs<Resolution>,
43 /// The first index in the path that we 45 /// The first index in the path that we
44 /// were unable to resolve. 46 /// were unable to resolve.
@@ -113,6 +115,9 @@ pub(crate) enum Scope {
113pub enum Resolution { 115pub enum Resolution {
114 /// An item 116 /// An item
115 Def(ModuleDef), 117 Def(ModuleDef),
118
119 // FIXME: there's no way we can syntactically confuse a local with generic
120 // param, so these two should not be members of the single enum
116 /// A local binding (only value namespace) 121 /// A local binding (only value namespace)
117 LocalBinding(PatId), 122 LocalBinding(PatId),
118 /// A generic parameter 123 /// A generic parameter
@@ -121,6 +126,37 @@ pub enum Resolution {
121} 126}
122 127
123impl Resolver { 128impl Resolver {
129 /// Resolve known trait from std, like `std::futures::Future`
130 pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option<Trait> {
131 let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?;
132 match res {
133 Resolution::Def(ModuleDef::Trait(it)) => Some(it),
134 _ => None,
135 }
136 }
137
138 /// Resolve known struct from std, like `std::boxed::Box`
139 pub(crate) fn resolve_known_struct(
140 &self,
141 db: &impl HirDatabase,
142 path: &Path,
143 ) -> Option<Struct> {
144 let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?;
145 match res {
146 Resolution::Def(ModuleDef::Struct(it)) => Some(it),
147 _ => None,
148 }
149 }
150
151 /// Resolve known enum from std, like `std::result::Result`
152 pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option<Enum> {
153 let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?;
154 match res {
155 Resolution::Def(ModuleDef::Enum(it)) => Some(it),
156 _ => None,
157 }
158 }
159
124 pub(crate) fn resolve_name(&self, db: &impl HirDatabase, name: &Name) -> PerNs<Resolution> { 160 pub(crate) fn resolve_name(&self, db: &impl HirDatabase, name: &Name) -> PerNs<Resolution> {
125 let mut resolution = PerNs::none(); 161 let mut resolution = PerNs::none();
126 for scope in self.scopes.iter().rev() { 162 for scope in self.scopes.iter().rev() {
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index afdcd5415..65b304b43 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -29,7 +29,7 @@ use crate::{
29 path::{PathKind, PathSegment}, 29 path::{PathKind, PathSegment},
30 ty::method_resolution::implements_trait, 30 ty::method_resolution::implements_trait,
31 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HasBody, HirFileId, MacroDef, 31 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HasBody, HirFileId, MacroDef,
32 Module, ModuleDef, Name, Path, PerNs, Resolution, Resolver, Static, Struct, Trait, Ty, 32 Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty,
33}; 33};
34 34
35/// Locates the module by `FileId`. Picks topmost module in the file. 35/// Locates the module by `FileId`. Picks topmost module in the file.
@@ -426,11 +426,10 @@ impl SourceAnalyzer {
426 ], 426 ],
427 }; 427 };
428 428
429 let std_future_trait = 429 let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) {
430 match self.resolver.resolve_path_segments(db, &std_future_path).into_fully_resolved() { 430 Some(it) => it,
431 PerNs { types: Some(Resolution::Def(ModuleDef::Trait(trait_))), .. } => trait_, 431 _ => return false,
432 _ => return false, 432 };
433 };
434 433
435 let krate = match self.resolver.krate() { 434 let krate = match self.resolver.krate() {
436 Some(krate) => krate, 435 Some(krate) => krate,
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 1057bbbec..3970c49e3 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -34,7 +34,7 @@ use super::{
34}; 34};
35use crate::{ 35use crate::{
36 adt::VariantDef, 36 adt::VariantDef,
37 code_model::{ModuleDef::Trait, TypeAlias}, 37 code_model::TypeAlias,
38 db::HirDatabase, 38 db::HirDatabase,
39 diagnostics::DiagnosticSink, 39 diagnostics::DiagnosticSink,
40 expr::{ 40 expr::{
@@ -43,12 +43,9 @@ use crate::{
43 }, 43 },
44 generics::{GenericParams, HasGenericParams}, 44 generics::{GenericParams, HasGenericParams},
45 name, 45 name,
46 nameres::{Namespace, PerNs}, 46 nameres::Namespace,
47 path::{GenericArg, GenericArgs, PathKind, PathSegment}, 47 path::{GenericArg, GenericArgs, PathKind, PathSegment},
48 resolve::{ 48 resolve::{Resolution, Resolver},
49 Resolution::{self, Def},
50 Resolver,
51 },
52 ty::infer::diagnostics::InferenceDiagnostic, 49 ty::infer::diagnostics::InferenceDiagnostic,
53 type_ref::{Mutability, TypeRef}, 50 type_ref::{Mutability, TypeRef},
54 AdtDef, ConstData, DefWithBody, FnData, Function, HasBody, ImplItem, ModuleDef, Name, Path, 51 AdtDef, ConstData, DefWithBody, FnData, Function, HasBody, ImplItem, ModuleDef, Name, Path,
@@ -1460,12 +1457,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1460 ], 1457 ],
1461 }; 1458 };
1462 1459
1463 match self.resolver.resolve_path_segments(self.db, &into_iter_path).into_fully_resolved() { 1460 let trait_ = self.resolver.resolve_known_trait(self.db, &into_iter_path)?;
1464 PerNs { types: Some(Def(Trait(trait_))), .. } => { 1461 trait_.associated_type_by_name(self.db, &name::ITEM)
1465 Some(trait_.associated_type_by_name(self.db, &name::ITEM)?)
1466 }
1467 _ => None,
1468 }
1469 } 1462 }
1470 1463
1471 fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { 1464 fn resolve_ops_try_ok(&self) -> Option<TypeAlias> {
@@ -1478,12 +1471,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1478 ], 1471 ],
1479 }; 1472 };
1480 1473
1481 match self.resolver.resolve_path_segments(self.db, &ops_try_path).into_fully_resolved() { 1474 let trait_ = self.resolver.resolve_known_trait(self.db, &ops_try_path)?;
1482 PerNs { types: Some(Def(Trait(trait_))), .. } => { 1475 trait_.associated_type_by_name(self.db, &name::OK)
1483 Some(trait_.associated_type_by_name(self.db, &name::OK)?)
1484 }
1485 _ => None,
1486 }
1487 } 1476 }
1488 1477
1489 fn resolve_future_future_output(&self) -> Option<TypeAlias> { 1478 fn resolve_future_future_output(&self) -> Option<TypeAlias> {
@@ -1496,16 +1485,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1496 ], 1485 ],
1497 }; 1486 };
1498 1487
1499 match self 1488 let trait_ = self.resolver.resolve_known_trait(self.db, &future_future_path)?;
1500 .resolver 1489 trait_.associated_type_by_name(self.db, &name::OUTPUT)
1501 .resolve_path_segments(self.db, &future_future_path)
1502 .into_fully_resolved()
1503 {
1504 PerNs { types: Some(Def(Trait(trait_))), .. } => {
1505 Some(trait_.associated_type_by_name(self.db, &name::OUTPUT)?)
1506 }
1507 _ => None,
1508 }
1509 } 1490 }
1510 1491
1511 fn resolve_boxed_box(&self) -> Option<AdtDef> { 1492 fn resolve_boxed_box(&self) -> Option<AdtDef> {
@@ -1517,13 +1498,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1517 PathSegment { name: name::BOX_TYPE, args_and_bindings: None }, 1498 PathSegment { name: name::BOX_TYPE, args_and_bindings: None },
1518 ], 1499 ],
1519 }; 1500 };
1520 1501 let struct_ = self.resolver.resolve_known_struct(self.db, &boxed_box_path)?;
1521 match self.resolver.resolve_path_segments(self.db, &boxed_box_path).into_fully_resolved() { 1502 Some(AdtDef::Struct(struct_))
1522 PerNs { types: Some(Def(ModuleDef::Struct(struct_))), .. } => {
1523 Some(AdtDef::Struct(struct_))
1524 }
1525 _ => None,
1526 }
1527 } 1503 }
1528} 1504}
1529 1505
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 061229842..e67525a74 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -86,7 +86,7 @@ impl Ty {
86 } 86 }
87 } 87 }
88 88
89 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { 89 pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty {
90 // Resolve the path (in type namespace) 90 // Resolve the path (in type namespace)
91 let (resolution, remaining_index) = resolver.resolve_path_segments(db, path).into_inner(); 91 let (resolution, remaining_index) = resolver.resolve_path_segments(db, path).into_inner();
92 let resolution = resolution.take_types(); 92 let resolution = resolution.take_types();