diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/Cargo.toml | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/validation.rs | 77 | ||||
-rw-r--r-- | crates/ra_hir/src/generics.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/mock.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests.rs | 286 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/globs.rs | 76 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/macros.rs | 54 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/unify.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 86 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 10 |
15 files changed, 373 insertions, 306 deletions
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 68ffcb2e9..294d047d8 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml | |||
@@ -21,10 +21,10 @@ tt = { path = "../ra_tt", package = "ra_tt" } | |||
21 | test_utils = { path = "../test_utils" } | 21 | test_utils = { path = "../test_utils" } |
22 | ra_prof = { path = "../ra_prof" } | 22 | ra_prof = { path = "../ra_prof" } |
23 | 23 | ||
24 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git" } | 24 | chalk-solve = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } |
25 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git" } | 25 | chalk-rust-ir = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } |
26 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git" } | 26 | chalk-ir = { git = "https://github.com/flodiebold/chalk.git", branch = "fuel" } |
27 | 27 | ||
28 | [dev-dependencies] | 28 | [dev-dependencies] |
29 | flexi_logger = "0.11.0" | 29 | flexi_logger = "0.11.0" |
30 | insta = "0.7.0" | 30 | insta = "0.8.1" |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 8e827d4f5..11cdf9c34 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -11,7 +11,7 @@ use crate::{ | |||
11 | DefWithBody, Trait, | 11 | DefWithBody, Trait, |
12 | ids, | 12 | ids, |
13 | nameres::{Namespace, ImportSourceMap, RawItems, CrateDefMap}, | 13 | nameres::{Namespace, ImportSourceMap, RawItems, CrateDefMap}, |
14 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig, TypeCtor, GenericPredicate}, | 14 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig, TypeCtor, GenericPredicate, Substs}, |
15 | adt::{StructData, EnumData}, | 15 | adt::{StructData, EnumData}, |
16 | impl_block::{ModuleImplBlocks, ImplSourceMap, ImplBlock}, | 16 | impl_block::{ModuleImplBlocks, ImplSourceMap, ImplBlock}, |
17 | generics::{GenericParams, GenericDef}, | 17 | generics::{GenericParams, GenericDef}, |
@@ -126,7 +126,7 @@ pub trait HirDatabase: DefDatabase { | |||
126 | #[salsa::invoke(ExprScopes::expr_scopes_query)] | 126 | #[salsa::invoke(ExprScopes::expr_scopes_query)] |
127 | fn expr_scopes(&self, def: DefWithBody) -> Arc<ExprScopes>; | 127 | fn expr_scopes(&self, def: DefWithBody) -> Arc<ExprScopes>; |
128 | 128 | ||
129 | #[salsa::invoke(crate::ty::infer)] | 129 | #[salsa::invoke(crate::ty::infer_query)] |
130 | fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; | 130 | fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; |
131 | 131 | ||
132 | #[salsa::invoke(crate::ty::type_for_def)] | 132 | #[salsa::invoke(crate::ty::type_for_def)] |
@@ -141,6 +141,9 @@ pub trait HirDatabase: DefDatabase { | |||
141 | #[salsa::invoke(crate::ty::generic_predicates)] | 141 | #[salsa::invoke(crate::ty::generic_predicates)] |
142 | fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; | 142 | fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; |
143 | 143 | ||
144 | #[salsa::invoke(crate::ty::generic_defaults)] | ||
145 | fn generic_defaults(&self, def: GenericDef) -> Substs; | ||
146 | |||
144 | #[salsa::invoke(crate::expr::body_with_source_map_query)] | 147 | #[salsa::invoke(crate::expr::body_with_source_map_query)] |
145 | fn body_with_source_map( | 148 | fn body_with_source_map( |
146 | &self, | 149 | &self, |
@@ -153,7 +156,7 @@ pub trait HirDatabase: DefDatabase { | |||
153 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | 156 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] |
154 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | 157 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; |
155 | 158 | ||
156 | #[salsa::invoke(crate::ty::traits::impls_for_trait)] | 159 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] |
157 | fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; | 160 | fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; |
158 | 161 | ||
159 | /// This provides the Chalk trait solver instance. Because Chalk always | 162 | /// This provides the Chalk trait solver instance. Because Chalk always |
@@ -161,11 +164,11 @@ pub trait HirDatabase: DefDatabase { | |||
161 | /// because Chalk does its own internal caching, the solver is wrapped in a | 164 | /// because Chalk does its own internal caching, the solver is wrapped in a |
162 | /// Mutex and the query is marked volatile, to make sure the cached state is | 165 | /// Mutex and the query is marked volatile, to make sure the cached state is |
163 | /// thrown away when input facts change. | 166 | /// thrown away when input facts change. |
164 | #[salsa::invoke(crate::ty::traits::solver)] | 167 | #[salsa::invoke(crate::ty::traits::solver_query)] |
165 | #[salsa::volatile] | 168 | #[salsa::volatile] |
166 | fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>; | 169 | fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>; |
167 | 170 | ||
168 | #[salsa::invoke(crate::ty::traits::implements)] | 171 | #[salsa::invoke(crate::ty::traits::implements_query)] |
169 | fn implements( | 172 | fn implements( |
170 | &self, | 173 | &self, |
171 | krate: Crate, | 174 | krate: Crate, |
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs index aebed6788..3f758f283 100644 --- a/crates/ra_hir/src/expr/validation.rs +++ b/crates/ra_hir/src/expr/validation.rs | |||
@@ -5,13 +5,11 @@ use ra_syntax::ast::{AstNode, StructLit}; | |||
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | expr::AstPtr, | 7 | expr::AstPtr, |
8 | HirDatabase, | 8 | HirDatabase, Function, Name, |
9 | Function, | ||
10 | Name, | ||
11 | diagnostics::{DiagnosticSink, MissingFields}, | 9 | diagnostics::{DiagnosticSink, MissingFields}, |
12 | adt::AdtDef, | 10 | adt::AdtDef, |
13 | Path, | 11 | Path, |
14 | ty::InferenceResult | 12 | ty::InferenceResult, |
15 | }; | 13 | }; |
16 | use super::{Expr, StructLitField, ExprId}; | 14 | use super::{Expr, StructLitField, ExprId}; |
17 | 15 | ||
@@ -50,43 +48,46 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
50 | spread: &Option<ExprId>, | 48 | spread: &Option<ExprId>, |
51 | db: &impl HirDatabase, | 49 | db: &impl HirDatabase, |
52 | ) { | 50 | ) { |
53 | if let Some(_) = spread { | 51 | if spread.is_some() { |
54 | return; | 52 | return; |
55 | } | 53 | } |
54 | |||
55 | let struct_def = match self.infer[id].as_adt() { | ||
56 | Some((AdtDef::Struct(s), _)) => s, | ||
57 | _ => return, | ||
58 | }; | ||
59 | |||
56 | let lit_fields: FxHashSet<_> = fields.into_iter().map(|f| &f.name).collect(); | 60 | let lit_fields: FxHashSet<_> = fields.into_iter().map(|f| &f.name).collect(); |
57 | let struct_ty = &self.infer[id]; | 61 | let missed_fields: Vec<Name> = struct_def |
58 | if let Some((AdtDef::Struct(s), _)) = struct_ty.as_adt() { | 62 | .fields(db) |
59 | let missed_fields: Vec<Name> = s | 63 | .iter() |
60 | .fields(db) | 64 | .filter_map(|f| { |
61 | .iter() | 65 | let name = f.name(db); |
62 | .filter_map(|f| { | 66 | if lit_fields.contains(&name) { |
63 | let name = f.name(db); | 67 | None |
64 | if lit_fields.contains(&name) { | 68 | } else { |
65 | None | 69 | Some(name) |
66 | } else { | 70 | } |
67 | Some(name) | 71 | }) |
68 | } | 72 | .collect(); |
69 | }) | 73 | if missed_fields.is_empty() { |
70 | .collect(); | 74 | return; |
71 | if missed_fields.is_empty() { | 75 | } |
72 | return; | 76 | let source_map = self.func.body_source_map(db); |
73 | } | 77 | let file_id = self.func.source(db).0; |
74 | let source_map = self.func.body_source_map(db); | 78 | let source_file = db.parse(file_id.original_file(db)); |
75 | let file_id = self.func.source(db).0; | 79 | if let Some(field_list_node) = source_map |
76 | let source_file = db.parse(file_id.original_file(db)); | 80 | .expr_syntax(id) |
77 | if let Some(field_list_node) = source_map | 81 | .map(|ptr| ptr.to_node(source_file.syntax())) |
78 | .expr_syntax(id) | 82 | .and_then(StructLit::cast) |
79 | .map(|ptr| ptr.to_node(source_file.syntax())) | 83 | .and_then(|lit| lit.named_field_list()) |
80 | .and_then(StructLit::cast) | 84 | { |
81 | .and_then(|lit| lit.named_field_list()) | 85 | let field_list_ptr = AstPtr::new(field_list_node); |
82 | { | 86 | self.sink.push(MissingFields { |
83 | let field_list_ptr = AstPtr::new(field_list_node); | 87 | file: file_id, |
84 | self.sink.push(MissingFields { | 88 | field_list: field_list_ptr, |
85 | file: file_id, | 89 | missed_fields, |
86 | field_list: field_list_ptr, | 90 | }) |
87 | missed_fields, | ||
88 | }) | ||
89 | } | ||
90 | } | 91 | } |
91 | } | 92 | } |
92 | } | 93 | } |
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index c29b96f50..79a7fa23a 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | use std::sync::Arc; | 6 | use std::sync::Arc; |
7 | 7 | ||
8 | use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner}; | 8 | use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner, DefaultTypeParamOwner}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::{ HirDatabase, DefDatabase}, | 11 | db::{ HirDatabase, DefDatabase}, |
@@ -18,6 +18,7 @@ pub struct GenericParam { | |||
18 | // FIXME: give generic params proper IDs | 18 | // FIXME: give generic params proper IDs |
19 | pub(crate) idx: u32, | 19 | pub(crate) idx: u32, |
20 | pub(crate) name: Name, | 20 | pub(crate) name: Name, |
21 | pub(crate) default: Option<Path>, | ||
21 | } | 22 | } |
22 | 23 | ||
23 | /// Data about the generic parameters of a function, struct, impl, etc. | 24 | /// Data about the generic parameters of a function, struct, impl, etc. |
@@ -68,7 +69,11 @@ impl GenericParams { | |||
68 | GenericDef::Enum(it) => generics.fill(&*it.source(db).1, start), | 69 | GenericDef::Enum(it) => generics.fill(&*it.source(db).1, start), |
69 | GenericDef::Trait(it) => { | 70 | GenericDef::Trait(it) => { |
70 | // traits get the Self type as an implicit first type parameter | 71 | // traits get the Self type as an implicit first type parameter |
71 | generics.params.push(GenericParam { idx: start, name: Name::self_type() }); | 72 | generics.params.push(GenericParam { |
73 | idx: start, | ||
74 | name: Name::self_type(), | ||
75 | default: None, | ||
76 | }); | ||
72 | generics.fill(&*it.source(db).1, start + 1); | 77 | generics.fill(&*it.source(db).1, start + 1); |
73 | } | 78 | } |
74 | GenericDef::TypeAlias(it) => generics.fill(&*it.source(db).1, start), | 79 | GenericDef::TypeAlias(it) => generics.fill(&*it.source(db).1, start), |
@@ -90,7 +95,9 @@ impl GenericParams { | |||
90 | fn fill_params(&mut self, params: &ast::TypeParamList, start: u32) { | 95 | fn fill_params(&mut self, params: &ast::TypeParamList, start: u32) { |
91 | for (idx, type_param) in params.type_params().enumerate() { | 96 | for (idx, type_param) in params.type_params().enumerate() { |
92 | let name = type_param.name().map(AsName::as_name).unwrap_or_else(Name::missing); | 97 | let name = type_param.name().map(AsName::as_name).unwrap_or_else(Name::missing); |
93 | let param = GenericParam { idx: idx as u32 + start, name: name.clone() }; | 98 | let default = type_param.default_type().and_then(|t| t.path()).and_then(Path::from_ast); |
99 | |||
100 | let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; | ||
94 | self.params.push(param); | 101 | self.params.push(param); |
95 | 102 | ||
96 | let type_ref = TypeRef::Path(name.into()); | 103 | let type_ref = TypeRef::Path(name.into()); |
@@ -190,13 +197,13 @@ impl From<crate::adt::AdtDef> for GenericDef { | |||
190 | } | 197 | } |
191 | } | 198 | } |
192 | 199 | ||
193 | pub trait HasGenericParams { | 200 | pub trait HasGenericParams: Copy { |
194 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>; | 201 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams>; |
195 | } | 202 | } |
196 | 203 | ||
197 | impl<T> HasGenericParams for T | 204 | impl<T> HasGenericParams for T |
198 | where | 205 | where |
199 | T: Into<GenericDef>, | 206 | T: Into<GenericDef> + Copy, |
200 | { | 207 | { |
201 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> { | 208 | fn generic_params(self, db: &impl DefDatabase) -> Arc<GenericParams> { |
202 | db.generic_params(self.into()) | 209 | db.generic_params(self.into()) |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index fa5882dea..b84cb7503 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -236,7 +236,7 @@ impl MockDatabase { | |||
236 | } | 236 | } |
237 | 237 | ||
238 | #[derive(Default)] | 238 | #[derive(Default)] |
239 | pub struct CrateGraphFixture(pub FxHashMap<String, (String, Edition, Vec<String>)>); | 239 | pub struct CrateGraphFixture(pub Vec<(String, (String, Edition, Vec<String>))>); |
240 | 240 | ||
241 | #[macro_export] | 241 | #[macro_export] |
242 | macro_rules! crate_graph { | 242 | macro_rules! crate_graph { |
@@ -246,10 +246,10 @@ macro_rules! crate_graph { | |||
246 | #[allow(unused_mut, unused_assignments)] | 246 | #[allow(unused_mut, unused_assignments)] |
247 | let mut edition = ra_db::Edition::Edition2018; | 247 | let mut edition = ra_db::Edition::Edition2018; |
248 | $(edition = ra_db::Edition::from_string($edition);)? | 248 | $(edition = ra_db::Edition::from_string($edition);)? |
249 | res.0.insert( | 249 | res.0.push(( |
250 | $crate_name.to_string(), | 250 | $crate_name.to_string(), |
251 | ($crate_path.to_string(), edition, vec![$($dep.to_string()),*]) | 251 | ($crate_path.to_string(), edition, vec![$($dep.to_string()),*]) |
252 | ); | 252 | )); |
253 | )* | 253 | )* |
254 | res | 254 | res |
255 | }} | 255 | }} |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs index 9a999e66c..e3a82cf03 100644 --- a/crates/ra_hir/src/name.rs +++ b/crates/ra_hir/src/name.rs | |||
@@ -5,7 +5,7 @@ use ra_syntax::{ast, SmolStr}; | |||
5 | /// `Name` is a wrapper around string, which is used in hir for both references | 5 | /// `Name` is a wrapper around string, which is used in hir for both references |
6 | /// and declarations. In theory, names should also carry hygiene info, but we are | 6 | /// and declarations. In theory, names should also carry hygiene info, but we are |
7 | /// not there yet! | 7 | /// not there yet! |
8 | #[derive(Clone, PartialEq, Eq, Hash)] | 8 | #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] |
9 | pub struct Name { | 9 | pub struct Name { |
10 | text: SmolStr, | 10 | text: SmolStr, |
11 | } | 11 | } |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 572bd1bf7..14c8ee50b 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -8,7 +8,11 @@ use ra_db::SourceDatabase; | |||
8 | use test_utils::covers; | 8 | use test_utils::covers; |
9 | use insta::assert_snapshot_matches; | 9 | use insta::assert_snapshot_matches; |
10 | 10 | ||
11 | use crate::{Crate, mock::{MockDatabase, CrateGraphFixture}, nameres::Resolution}; | 11 | use crate::{ |
12 | Crate, | ||
13 | mock::{MockDatabase, CrateGraphFixture}, | ||
14 | nameres::Resolution, | ||
15 | }; | ||
12 | 16 | ||
13 | use super::*; | 17 | use super::*; |
14 | 18 | ||
@@ -25,12 +29,15 @@ fn compute_crate_def_map(fixture: &str, graph: Option<CrateGraphFixture>) -> Arc | |||
25 | fn render_crate_def_map(map: &CrateDefMap) -> String { | 29 | fn render_crate_def_map(map: &CrateDefMap) -> String { |
26 | let mut buf = String::new(); | 30 | let mut buf = String::new(); |
27 | go(&mut buf, map, "\ncrate", map.root); | 31 | go(&mut buf, map, "\ncrate", map.root); |
28 | return buf; | 32 | return buf.trim().to_string(); |
29 | 33 | ||
30 | fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: CrateModuleId) { | 34 | fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: CrateModuleId) { |
31 | *buf += path; | 35 | *buf += path; |
32 | *buf += "\n"; | 36 | *buf += "\n"; |
33 | for (name, res) in map.modules[module].scope.items.iter() { | 37 | |
38 | let mut entries = map.modules[module].scope.items.iter().collect::<Vec<_>>(); | ||
39 | entries.sort_by_key(|(name, _)| *name); | ||
40 | for (name, res) in entries { | ||
34 | *buf += &format!("{}: {}\n", name, dump_resolution(res)) | 41 | *buf += &format!("{}: {}\n", name, dump_resolution(res)) |
35 | } | 42 | } |
36 | for (name, child) in map.modules[module].children.iter() { | 43 | for (name, child) in map.modules[module].children.iter() { |
@@ -54,8 +61,8 @@ fn def_map(fixtute: &str) -> String { | |||
54 | render_crate_def_map(&dm) | 61 | render_crate_def_map(&dm) |
55 | } | 62 | } |
56 | 63 | ||
57 | fn def_map_with_crate_graph(fixtute: &str, graph: CrateGraphFixture) -> String { | 64 | fn def_map_with_crate_graph(fixture: &str, graph: CrateGraphFixture) -> String { |
58 | let dm = compute_crate_def_map(fixtute, Some(graph)); | 65 | let dm = compute_crate_def_map(fixture, Some(graph)); |
59 | render_crate_def_map(&dm) | 66 | render_crate_def_map(&dm) |
60 | } | 67 | } |
61 | 68 | ||
@@ -79,21 +86,20 @@ fn crate_def_map_smoke_test() { | |||
79 | ", | 86 | ", |
80 | ); | 87 | ); |
81 | assert_snapshot_matches!(map, @r###" | 88 | assert_snapshot_matches!(map, @r###" |
82 | crate | 89 | â‹®crate |
83 | V: t v | 90 | â‹®E: t |
84 | E: t | 91 | â‹®S: t v |
85 | foo: t | 92 | â‹®V: t v |
86 | S: t v | 93 | â‹®foo: t |
87 | 94 | â‹® | |
88 | crate::foo | 95 | â‹®crate::foo |
89 | bar: t | 96 | â‹®bar: t |
90 | f: v | 97 | â‹®f: v |
91 | 98 | â‹® | |
92 | crate::foo::bar | 99 | â‹®crate::foo::bar |
93 | Baz: t v | 100 | â‹®Baz: t v |
94 | E: t | 101 | â‹®E: t |
95 | "### | 102 | "###) |
96 | ) | ||
97 | } | 103 | } |
98 | 104 | ||
99 | #[test] | 105 | #[test] |
@@ -113,12 +119,12 @@ fn bogus_paths() { | |||
113 | ", | 119 | ", |
114 | ); | 120 | ); |
115 | assert_snapshot_matches!(map, @r###" | 121 | assert_snapshot_matches!(map, @r###" |
116 | crate | 122 | â‹®crate |
117 | foo: t | 123 | â‹®S: t v |
118 | S: t v | 124 | â‹®foo: t |
119 | 125 | â‹® | |
120 | crate::foo | 126 | â‹®crate::foo |
121 | "### | 127 | "### |
122 | ) | 128 | ) |
123 | } | 129 | } |
124 | 130 | ||
@@ -137,13 +143,13 @@ fn use_as() { | |||
137 | ); | 143 | ); |
138 | assert_snapshot_matches!(map, | 144 | assert_snapshot_matches!(map, |
139 | @r###" | 145 | @r###" |
140 | crate | 146 | â‹®crate |
141 | Foo: t v | 147 | â‹®Foo: t v |
142 | foo: t | 148 | â‹®foo: t |
143 | 149 | â‹® | |
144 | crate::foo | 150 | â‹®crate::foo |
145 | Baz: t v | 151 | â‹®Baz: t v |
146 | "### | 152 | "### |
147 | ); | 153 | ); |
148 | } | 154 | } |
149 | 155 | ||
@@ -164,21 +170,19 @@ fn use_trees() { | |||
164 | pub enum Quux {}; | 170 | pub enum Quux {}; |
165 | ", | 171 | ", |
166 | ); | 172 | ); |
167 | assert_snapshot_matches!(map, | 173 | assert_snapshot_matches!(map, @r###" |
168 | @r###" | 174 | â‹®crate |
169 | crate | 175 | â‹®Baz: t v |
170 | Quux: t | 176 | â‹®Quux: t |
171 | Baz: t v | 177 | â‹®foo: t |
172 | foo: t | 178 | â‹® |
173 | 179 | â‹®crate::foo | |
174 | crate::foo | 180 | â‹®bar: t |
175 | bar: t | 181 | â‹® |
176 | 182 | â‹®crate::foo::bar | |
177 | crate::foo::bar | 183 | â‹®Baz: t v |
178 | Quux: t | 184 | â‹®Quux: t |
179 | Baz: t v | 185 | "###); |
180 | "### | ||
181 | ); | ||
182 | } | 186 | } |
183 | 187 | ||
184 | #[test] | 188 | #[test] |
@@ -199,20 +203,18 @@ fn re_exports() { | |||
199 | pub struct Baz; | 203 | pub struct Baz; |
200 | ", | 204 | ", |
201 | ); | 205 | ); |
202 | assert_snapshot_matches!(map, | 206 | assert_snapshot_matches!(map, @r###" |
203 | @r###" | 207 | â‹®crate |
204 | crate | 208 | â‹®Baz: t v |
205 | Baz: t v | 209 | â‹®foo: t |
206 | foo: t | 210 | â‹® |
207 | 211 | â‹®crate::foo | |
208 | crate::foo | 212 | â‹®Baz: t v |
209 | bar: t | 213 | â‹®bar: t |
210 | Baz: t v | 214 | â‹® |
211 | 215 | â‹®crate::foo::bar | |
212 | crate::foo::bar | 216 | â‹®Baz: t v |
213 | Baz: t v | 217 | "###); |
214 | "### | ||
215 | ); | ||
216 | } | 218 | } |
217 | 219 | ||
218 | #[test] | 220 | #[test] |
@@ -237,10 +239,10 @@ fn std_prelude() { | |||
237 | }, | 239 | }, |
238 | ); | 240 | ); |
239 | assert_snapshot_matches!(map, @r###" | 241 | assert_snapshot_matches!(map, @r###" |
240 | crate | 242 | â‹®crate |
241 | Bar: t v | 243 | â‹®Bar: t v |
242 | Baz: t v | 244 | â‹®Baz: t v |
243 | "###); | 245 | "###); |
244 | } | 246 | } |
245 | 247 | ||
246 | #[test] | 248 | #[test] |
@@ -254,10 +256,10 @@ fn can_import_enum_variant() { | |||
254 | ", | 256 | ", |
255 | ); | 257 | ); |
256 | assert_snapshot_matches!(map, @r###" | 258 | assert_snapshot_matches!(map, @r###" |
257 | crate | 259 | â‹®crate |
258 | V: t v | 260 | â‹®E: t |
259 | E: t | 261 | â‹®V: t v |
260 | "### | 262 | "### |
261 | ); | 263 | ); |
262 | } | 264 | } |
263 | 265 | ||
@@ -285,20 +287,18 @@ fn edition_2015_imports() { | |||
285 | }, | 287 | }, |
286 | ); | 288 | ); |
287 | 289 | ||
288 | assert_snapshot_matches!(map, | 290 | assert_snapshot_matches!(map, @r###" |
289 | @r###" | 291 | â‹®crate |
290 | crate | 292 | â‹®bar: t |
291 | bar: t | 293 | â‹®foo: t |
292 | foo: t | 294 | â‹® |
293 | 295 | â‹®crate::bar | |
294 | crate::bar | 296 | â‹®Bar: t v |
295 | Bar: t v | 297 | â‹® |
296 | 298 | â‹®crate::foo | |
297 | crate::foo | 299 | â‹®Bar: t v |
298 | FromLib: t v | 300 | â‹®FromLib: t v |
299 | Bar: t v | 301 | "###); |
300 | "### | ||
301 | ); | ||
302 | } | 302 | } |
303 | 303 | ||
304 | #[test] | 304 | #[test] |
@@ -317,16 +317,14 @@ fn module_resolution_works_for_non_standard_filenames() { | |||
317 | }, | 317 | }, |
318 | ); | 318 | ); |
319 | 319 | ||
320 | assert_snapshot_matches!(map, | 320 | assert_snapshot_matches!(map, @r###" |
321 | @r###" | 321 | â‹®crate |
322 | crate | 322 | â‹®Bar: t v |
323 | Bar: t v | 323 | â‹®foo: t |
324 | foo: t | 324 | â‹® |
325 | 325 | â‹®crate::foo | |
326 | crate::foo | 326 | â‹®Bar: t v |
327 | Bar: t v | 327 | "###); |
328 | "### | ||
329 | ); | ||
330 | } | 328 | } |
331 | 329 | ||
332 | #[test] | 330 | #[test] |
@@ -348,12 +346,10 @@ fn name_res_works_for_broken_modules() { | |||
348 | pub struct Baz; | 346 | pub struct Baz; |
349 | ", | 347 | ", |
350 | ); | 348 | ); |
351 | assert_snapshot_matches!(map, | 349 | assert_snapshot_matches!(map, @r###" |
352 | @r###" | 350 | â‹®crate |
353 | crate | 351 | â‹®Baz: _ |
354 | Baz: _ | 352 | "###); |
355 | "### | ||
356 | ); | ||
357 | } | 353 | } |
358 | 354 | ||
359 | #[test] | 355 | #[test] |
@@ -369,19 +365,17 @@ fn item_map_using_self() { | |||
369 | pub struct Baz; | 365 | pub struct Baz; |
370 | ", | 366 | ", |
371 | ); | 367 | ); |
372 | assert_snapshot_matches!(map, | 368 | assert_snapshot_matches!(map, @r###" |
373 | @r###" | 369 | â‹®crate |
374 | crate | 370 | â‹®Baz: t v |
375 | Baz: t v | 371 | â‹®foo: t |
376 | foo: t | 372 | â‹® |
377 | 373 | â‹®crate::foo | |
378 | crate::foo | 374 | â‹®bar: t |
379 | bar: t | 375 | â‹® |
380 | 376 | â‹®crate::foo::bar | |
381 | crate::foo::bar | 377 | â‹®Baz: t v |
382 | Baz: t v | 378 | "###); |
383 | "### | ||
384 | ); | ||
385 | } | 379 | } |
386 | 380 | ||
387 | #[test] | 381 | #[test] |
@@ -400,12 +394,10 @@ fn item_map_across_crates() { | |||
400 | }, | 394 | }, |
401 | ); | 395 | ); |
402 | 396 | ||
403 | assert_snapshot_matches!(map, | 397 | assert_snapshot_matches!(map, @r###" |
404 | @r###" | 398 | â‹®crate |
405 | crate | 399 | â‹®Baz: t v |
406 | Baz: t v | 400 | "###); |
407 | "### | ||
408 | ); | ||
409 | } | 401 | } |
410 | 402 | ||
411 | #[test] | 403 | #[test] |
@@ -430,12 +422,14 @@ fn extern_crate_rename() { | |||
430 | }, | 422 | }, |
431 | ); | 423 | ); |
432 | 424 | ||
433 | assert_snapshot_matches!(map, | 425 | assert_snapshot_matches!(map, @r###" |
434 | @r###" | 426 | â‹®crate |
435 | crate | 427 | â‹®alloc_crate: t |
436 | Arc: t v | 428 | â‹®sync: t |
437 | "### | 429 | â‹® |
438 | ); | 430 | â‹®crate::sync |
431 | â‹®Arc: t v | ||
432 | "###); | ||
439 | } | 433 | } |
440 | 434 | ||
441 | #[test] | 435 | #[test] |
@@ -462,9 +456,13 @@ fn extern_crate_rename_2015_edition() { | |||
462 | 456 | ||
463 | assert_snapshot_matches!(map, | 457 | assert_snapshot_matches!(map, |
464 | @r###" | 458 | @r###" |
465 | crate | 459 | â‹®crate |
466 | Arc: t v | 460 | â‹®alloc_crate: t |
467 | "### | 461 | â‹®sync: t |
462 | â‹® | ||
463 | â‹®crate::sync | ||
464 | â‹®Arc: t v | ||
465 | "### | ||
468 | ); | 466 | ); |
469 | } | 467 | } |
470 | 468 | ||
@@ -490,12 +488,10 @@ fn import_across_source_roots() { | |||
490 | }, | 488 | }, |
491 | ); | 489 | ); |
492 | 490 | ||
493 | assert_snapshot_matches!(map, | 491 | assert_snapshot_matches!(map, @r###" |
494 | @r###" | 492 | â‹®crate |
495 | crate | 493 | â‹®C: t v |
496 | C: t v | 494 | "###); |
497 | "### | ||
498 | ); | ||
499 | } | 495 | } |
500 | 496 | ||
501 | #[test] | 497 | #[test] |
@@ -519,12 +515,10 @@ fn reexport_across_crates() { | |||
519 | }, | 515 | }, |
520 | ); | 516 | ); |
521 | 517 | ||
522 | assert_snapshot_matches!(map, | 518 | assert_snapshot_matches!(map, @r###" |
523 | @r###" | 519 | â‹®crate |
524 | crate | 520 | â‹®Baz: t v |
525 | Baz: t v | 521 | "###); |
526 | "### | ||
527 | ); | ||
528 | } | 522 | } |
529 | 523 | ||
530 | #[test] | 524 | #[test] |
@@ -544,13 +538,11 @@ fn values_dont_shadow_extern_crates() { | |||
544 | }, | 538 | }, |
545 | ); | 539 | ); |
546 | 540 | ||
547 | assert_snapshot_matches!(map, | 541 | assert_snapshot_matches!(map, @r###" |
548 | @r###" | 542 | â‹®crate |
549 | crate | 543 | â‹®Bar: t v |
550 | Bar: t v | 544 | â‹®foo: v |
551 | foo: v | 545 | "###); |
552 | "### | ||
553 | ); | ||
554 | } | 546 | } |
555 | 547 | ||
556 | #[test] | 548 | #[test] |
diff --git a/crates/ra_hir/src/nameres/tests/globs.rs b/crates/ra_hir/src/nameres/tests/globs.rs index 6e50c7ff6..e1519ca6b 100644 --- a/crates/ra_hir/src/nameres/tests/globs.rs +++ b/crates/ra_hir/src/nameres/tests/globs.rs | |||
@@ -18,20 +18,20 @@ fn glob_1() { | |||
18 | ", | 18 | ", |
19 | ); | 19 | ); |
20 | assert_snapshot_matches!(map, @r###" | 20 | assert_snapshot_matches!(map, @r###" |
21 | crate | 21 | â‹®crate |
22 | bar: t | 22 | â‹®Baz: t v |
23 | Foo: t v | 23 | â‹®Foo: t v |
24 | Baz: t v | 24 | â‹®bar: t |
25 | foo: t | 25 | â‹®foo: t |
26 | 26 | â‹® | |
27 | crate::foo | 27 | â‹®crate::foo |
28 | bar: t | 28 | â‹®Baz: t v |
29 | Foo: t v | 29 | â‹®Foo: t v |
30 | Baz: t v | 30 | â‹®bar: t |
31 | 31 | â‹® | |
32 | crate::foo::bar | 32 | â‹®crate::foo::bar |
33 | Baz: t v | 33 | â‹®Baz: t v |
34 | "### | 34 | "### |
35 | ); | 35 | ); |
36 | } | 36 | } |
37 | 37 | ||
@@ -54,22 +54,22 @@ fn glob_2() { | |||
54 | ", | 54 | ", |
55 | ); | 55 | ); |
56 | assert_snapshot_matches!(map, @r###" | 56 | assert_snapshot_matches!(map, @r###" |
57 | crate | 57 | â‹®crate |
58 | bar: t | 58 | â‹®Baz: t v |
59 | Foo: t v | 59 | â‹®Foo: t v |
60 | Baz: t v | 60 | â‹®bar: t |
61 | foo: t | 61 | â‹®foo: t |
62 | 62 | â‹® | |
63 | crate::foo | 63 | â‹®crate::foo |
64 | bar: t | 64 | â‹®Baz: t v |
65 | Foo: t v | 65 | â‹®Foo: t v |
66 | Baz: t v | 66 | â‹®bar: t |
67 | 67 | â‹® | |
68 | crate::foo::bar | 68 | â‹®crate::foo::bar |
69 | bar: t | 69 | â‹®Baz: t v |
70 | Foo: t v | 70 | â‹®Foo: t v |
71 | Baz: t v | 71 | â‹®bar: t |
72 | "### | 72 | "### |
73 | ); | 73 | ); |
74 | } | 74 | } |
75 | 75 | ||
@@ -90,9 +90,9 @@ fn glob_across_crates() { | |||
90 | }, | 90 | }, |
91 | ); | 91 | ); |
92 | assert_snapshot_matches!(map, @r###" | 92 | assert_snapshot_matches!(map, @r###" |
93 | crate | 93 | â‹®crate |
94 | Baz: t v | 94 | â‹®Baz: t v |
95 | "### | 95 | "### |
96 | ); | 96 | ); |
97 | } | 97 | } |
98 | 98 | ||
@@ -109,10 +109,10 @@ fn glob_enum() { | |||
109 | ", | 109 | ", |
110 | ); | 110 | ); |
111 | assert_snapshot_matches!(map, @r###" | 111 | assert_snapshot_matches!(map, @r###" |
112 | crate | 112 | â‹®crate |
113 | Foo: t | 113 | â‹®Bar: t v |
114 | Bar: t v | 114 | â‹®Baz: t v |
115 | Baz: t v | 115 | â‹®Foo: t |
116 | "### | 116 | "### |
117 | ); | 117 | ); |
118 | } | 118 | } |
diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs index 8781b026b..f7ca380ad 100644 --- a/crates/ra_hir/src/nameres/tests/macros.rs +++ b/crates/ra_hir/src/nameres/tests/macros.rs | |||
@@ -18,14 +18,14 @@ fn macro_rules_are_globally_visible() { | |||
18 | ", | 18 | ", |
19 | ); | 19 | ); |
20 | assert_snapshot_matches!(map, @r###" | 20 | assert_snapshot_matches!(map, @r###" |
21 | crate | 21 | â‹®crate |
22 | nested: t | 22 | â‹®Foo: t v |
23 | Foo: t v | 23 | â‹®nested: t |
24 | 24 | â‹® | |
25 | crate::nested | 25 | â‹®crate::nested |
26 | Bar: t v | 26 | â‹®Bar: t v |
27 | Baz: t v | 27 | â‹®Baz: t v |
28 | "###); | 28 | "###); |
29 | } | 29 | } |
30 | 30 | ||
31 | #[test] | 31 | #[test] |
@@ -45,15 +45,15 @@ fn macro_rules_can_define_modules() { | |||
45 | ", | 45 | ", |
46 | ); | 46 | ); |
47 | assert_snapshot_matches!(map, @r###" | 47 | assert_snapshot_matches!(map, @r###" |
48 | crate | 48 | â‹®crate |
49 | n1: t | 49 | â‹®n1: t |
50 | 50 | â‹® | |
51 | crate::n1 | 51 | â‹®crate::n1 |
52 | n2: t | 52 | â‹®n2: t |
53 | 53 | â‹® | |
54 | crate::n1::n2 | 54 | â‹®crate::n1::n2 |
55 | X: t v | 55 | â‹®X: t v |
56 | "###); | 56 | "###); |
57 | } | 57 | } |
58 | 58 | ||
59 | #[test] | 59 | #[test] |
@@ -81,14 +81,14 @@ fn macro_rules_from_other_crates_are_visible() { | |||
81 | }, | 81 | }, |
82 | ); | 82 | ); |
83 | assert_snapshot_matches!(map, @r###" | 83 | assert_snapshot_matches!(map, @r###" |
84 | crate | 84 | â‹®crate |
85 | bar: t | 85 | â‹®Bar: t v |
86 | Foo: t v | 86 | â‹®Foo: t v |
87 | Bar: t v | 87 | â‹®bar: t |
88 | 88 | â‹® | |
89 | crate::bar | 89 | â‹®crate::bar |
90 | bar: t | 90 | â‹®Bar: t v |
91 | Foo: t v | 91 | â‹®Foo: t v |
92 | Bar: t v | 92 | â‹®bar: t |
93 | "###); | 93 | "###); |
94 | } | 94 | } |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index cfe07156b..3679a2242 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -19,8 +19,8 @@ use std::{fmt, mem}; | |||
19 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams}; | 19 | use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams}; |
20 | use display::{HirDisplay, HirFormatter}; | 20 | use display::{HirDisplay, HirFormatter}; |
21 | 21 | ||
22 | pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig, generic_predicates}; | 22 | pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig, generic_predicates, generic_defaults}; |
23 | pub(crate) use infer::{infer, InferenceResult, InferTy}; | 23 | pub(crate) use infer::{infer_query, InferenceResult, InferTy}; |
24 | pub use lower::CallableDef; | 24 | pub use lower::CallableDef; |
25 | 25 | ||
26 | /// A type constructor or type name: this might be something like the primitive | 26 | /// A type constructor or type name: this might be something like the primitive |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 1e7d97f51..a48272981 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -23,6 +23,7 @@ use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError}; | |||
23 | use rustc_hash::FxHashMap; | 23 | use rustc_hash::FxHashMap; |
24 | 24 | ||
25 | use ra_arena::map::ArenaMap; | 25 | use ra_arena::map::ArenaMap; |
26 | use ra_prof::profile; | ||
26 | use test_utils::tested_by; | 27 | use test_utils::tested_by; |
27 | 28 | ||
28 | use crate::{ | 29 | use crate::{ |
@@ -51,7 +52,8 @@ use super::{ | |||
51 | mod unify; | 52 | mod unify; |
52 | 53 | ||
53 | /// The entry point of type inference. | 54 | /// The entry point of type inference. |
54 | pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { | 55 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { |
56 | let _p = profile("infer_query"); | ||
55 | db.check_canceled(); | 57 | db.check_canceled(); |
56 | let body = def.body(db); | 58 | let body = def.body(db); |
57 | let resolver = def.resolver(db); | 59 | let resolver = def.resolver(db); |
diff --git a/crates/ra_hir/src/ty/infer/unify.rs b/crates/ra_hir/src/ty/infer/unify.rs index 8ca7e957d..bc9719725 100644 --- a/crates/ra_hir/src/ty/infer/unify.rs +++ b/crates/ra_hir/src/ty/infer/unify.rs | |||
@@ -56,7 +56,12 @@ where | |||
56 | self.var_stack.pop(); | 56 | self.var_stack.pop(); |
57 | result | 57 | result |
58 | } else { | 58 | } else { |
59 | let free_var = InferTy::TypeVar(self.ctx.var_unification_table.find(inner)); | 59 | let root = self.ctx.var_unification_table.find(inner); |
60 | let free_var = match tv { | ||
61 | InferTy::TypeVar(_) => InferTy::TypeVar(root), | ||
62 | InferTy::IntVar(_) => InferTy::IntVar(root), | ||
63 | InferTy::FloatVar(_) => InferTy::FloatVar(root), | ||
64 | }; | ||
60 | let position = self.add(free_var); | 65 | let position = self.add(free_var); |
61 | Ty::Bound(position as u32) | 66 | Ty::Bound(position as u32) |
62 | } | 67 | } |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 09d26ce5a..a1a2d0f6b 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -9,17 +9,18 @@ use std::sync::Arc; | |||
9 | use std::iter; | 9 | use std::iter; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | Function, Struct, StructField, Enum, EnumVariant, Path, | 12 | Function, Struct, StructField, Enum, EnumVariant, Path, ModuleDef, TypeAlias, Const, Static, |
13 | ModuleDef, TypeAlias, | ||
14 | Const, Static, | ||
15 | HirDatabase, | 13 | HirDatabase, |
16 | type_ref::TypeRef, | 14 | type_ref::TypeRef, |
17 | name::KnownName, | 15 | name::KnownName, |
18 | nameres::Namespace, | 16 | nameres::Namespace, |
19 | resolve::{Resolver, Resolution}, | 17 | resolve::{Resolver, Resolution}, |
20 | path::{PathSegment, GenericArg}, | 18 | path::{PathSegment, GenericArg}, |
21 | generics::{GenericParams, HasGenericParams}, | 19 | generics::{HasGenericParams}, |
22 | adt::VariantDef, Trait, generics::{ WherePredicate, GenericDef} | 20 | adt::VariantDef, |
21 | Trait, | ||
22 | generics::{WherePredicate, GenericDef}, | ||
23 | ty::AdtDef, | ||
23 | }; | 24 | }; |
24 | use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef, GenericPredicate}; | 25 | use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef, GenericPredicate}; |
25 | 26 | ||
@@ -120,15 +121,15 @@ impl Ty { | |||
120 | segment: &PathSegment, | 121 | segment: &PathSegment, |
121 | resolved: TypableDef, | 122 | resolved: TypableDef, |
122 | ) -> Substs { | 123 | ) -> Substs { |
123 | let def_generics = match resolved { | 124 | let def_generic: Option<GenericDef> = match resolved { |
124 | TypableDef::Function(func) => func.generic_params(db), | 125 | TypableDef::Function(func) => Some(func.into()), |
125 | TypableDef::Struct(s) => s.generic_params(db), | 126 | TypableDef::Struct(s) => Some(s.into()), |
126 | TypableDef::Enum(e) => e.generic_params(db), | 127 | TypableDef::Enum(e) => Some(e.into()), |
127 | TypableDef::EnumVariant(var) => var.parent_enum(db).generic_params(db), | 128 | TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()), |
128 | TypableDef::TypeAlias(t) => t.generic_params(db), | 129 | TypableDef::TypeAlias(t) => Some(t.into()), |
129 | TypableDef::Const(_) | TypableDef::Static(_) => GenericParams::default().into(), | 130 | TypableDef::Const(_) | TypableDef::Static(_) => None, |
130 | }; | 131 | }; |
131 | substs_from_path_segment(db, resolver, segment, &def_generics, false) | 132 | substs_from_path_segment(db, resolver, segment, def_generic, false) |
132 | } | 133 | } |
133 | 134 | ||
134 | /// Collect generic arguments from a path into a `Substs`. See also | 135 | /// Collect generic arguments from a path into a `Substs`. See also |
@@ -172,10 +173,12 @@ pub(super) fn substs_from_path_segment( | |||
172 | db: &impl HirDatabase, | 173 | db: &impl HirDatabase, |
173 | resolver: &Resolver, | 174 | resolver: &Resolver, |
174 | segment: &PathSegment, | 175 | segment: &PathSegment, |
175 | def_generics: &GenericParams, | 176 | def_generic: Option<GenericDef>, |
176 | add_self_param: bool, | 177 | add_self_param: bool, |
177 | ) -> Substs { | 178 | ) -> Substs { |
178 | let mut substs = Vec::new(); | 179 | let mut substs = Vec::new(); |
180 | let def_generics = def_generic.map(|def| def.generic_params(db)).unwrap_or_default(); | ||
181 | |||
179 | let parent_param_count = def_generics.count_parent_params(); | 182 | let parent_param_count = def_generics.count_parent_params(); |
180 | substs.extend(iter::repeat(Ty::Unknown).take(parent_param_count)); | 183 | substs.extend(iter::repeat(Ty::Unknown).take(parent_param_count)); |
181 | if add_self_param { | 184 | if add_self_param { |
@@ -199,12 +202,24 @@ pub(super) fn substs_from_path_segment( | |||
199 | } | 202 | } |
200 | } | 203 | } |
201 | // add placeholders for args that were not provided | 204 | // add placeholders for args that were not provided |
202 | // FIXME: handle defaults | ||
203 | let supplied_params = substs.len(); | 205 | let supplied_params = substs.len(); |
204 | for _ in supplied_params..def_generics.count_params_including_parent() { | 206 | for _ in supplied_params..def_generics.count_params_including_parent() { |
205 | substs.push(Ty::Unknown); | 207 | substs.push(Ty::Unknown); |
206 | } | 208 | } |
207 | assert_eq!(substs.len(), def_generics.count_params_including_parent()); | 209 | assert_eq!(substs.len(), def_generics.count_params_including_parent()); |
210 | |||
211 | // handle defaults | ||
212 | if let Some(def_generic) = def_generic { | ||
213 | let default_substs = db.generic_defaults(def_generic); | ||
214 | assert_eq!(substs.len(), default_substs.len()); | ||
215 | |||
216 | for (i, default_ty) in default_substs.iter().enumerate() { | ||
217 | if substs[i] == Ty::Unknown { | ||
218 | substs[i] = default_ty.clone(); | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | |||
208 | Substs(substs.into()) | 223 | Substs(substs.into()) |
209 | } | 224 | } |
210 | 225 | ||
@@ -249,7 +264,7 @@ impl TraitRef { | |||
249 | resolved: Trait, | 264 | resolved: Trait, |
250 | ) -> Substs { | 265 | ) -> Substs { |
251 | let segment = path.segments.last().expect("path should have at least one segment"); | 266 | let segment = path.segments.last().expect("path should have at least one segment"); |
252 | substs_from_path_segment(db, resolver, segment, &resolved.generic_params(db), true) | 267 | substs_from_path_segment(db, resolver, segment, Some(resolved.into()), true) |
253 | } | 268 | } |
254 | 269 | ||
255 | pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { | 270 | pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { |
@@ -274,9 +289,9 @@ impl TraitRef { | |||
274 | pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty { | 289 | pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty { |
275 | match (def, ns) { | 290 | match (def, ns) { |
276 | (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f), | 291 | (TypableDef::Function(f), Namespace::Values) => type_for_fn(db, f), |
277 | (TypableDef::Struct(s), Namespace::Types) => type_for_struct(db, s), | 292 | (TypableDef::Struct(s), Namespace::Types) => type_for_adt(db, s), |
278 | (TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s), | 293 | (TypableDef::Struct(s), Namespace::Values) => type_for_struct_constructor(db, s), |
279 | (TypableDef::Enum(e), Namespace::Types) => type_for_enum(db, e), | 294 | (TypableDef::Enum(e), Namespace::Types) => type_for_adt(db, e), |
280 | (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v), | 295 | (TypableDef::EnumVariant(v), Namespace::Values) => type_for_enum_variant_constructor(db, v), |
281 | (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t), | 296 | (TypableDef::TypeAlias(t), Namespace::Types) => type_for_type_alias(db, t), |
282 | (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c), | 297 | (TypableDef::Const(c), Namespace::Values) => type_for_const(db, c), |
@@ -331,6 +346,22 @@ pub(crate) fn generic_predicates( | |||
331 | predicates.into() | 346 | predicates.into() |
332 | } | 347 | } |
333 | 348 | ||
349 | /// Resolve the default type params from generics | ||
350 | pub(crate) fn generic_defaults(db: &impl HirDatabase, def: GenericDef) -> Substs { | ||
351 | let resolver = def.resolver(db); | ||
352 | let generic_params = def.generic_params(db); | ||
353 | |||
354 | let defaults = generic_params | ||
355 | .params_including_parent() | ||
356 | .into_iter() | ||
357 | .map(|p| { | ||
358 | p.default.as_ref().map_or(Ty::Unknown, |path| Ty::from_hir_path(db, &resolver, path)) | ||
359 | }) | ||
360 | .collect::<Vec<_>>(); | ||
361 | |||
362 | Substs(defaults.into()) | ||
363 | } | ||
364 | |||
334 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 365 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { |
335 | let signature = def.signature(db); | 366 | let signature = def.signature(db); |
336 | let resolver = def.resolver(db); | 367 | let resolver = def.resolver(db); |
@@ -375,7 +406,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | |||
375 | .iter() | 406 | .iter() |
376 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 407 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
377 | .collect::<Vec<_>>(); | 408 | .collect::<Vec<_>>(); |
378 | let ret = type_for_struct(db, def); | 409 | let ret = type_for_adt(db, def); |
379 | FnSig::from_params_and_return(params, ret) | 410 | FnSig::from_params_and_return(params, ret) |
380 | } | 411 | } |
381 | 412 | ||
@@ -383,7 +414,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | |||
383 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | 414 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { |
384 | let var_data = def.variant_data(db); | 415 | let var_data = def.variant_data(db); |
385 | if var_data.fields().is_none() { | 416 | if var_data.fields().is_none() { |
386 | return type_for_struct(db, def); // Unit struct | 417 | return type_for_adt(db, def); // Unit struct |
387 | } | 418 | } |
388 | let generics = def.generic_params(db); | 419 | let generics = def.generic_params(db); |
389 | let substs = Substs::identity(&generics); | 420 | let substs = Substs::identity(&generics); |
@@ -403,7 +434,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) | |||
403 | .collect::<Vec<_>>(); | 434 | .collect::<Vec<_>>(); |
404 | let generics = def.parent_enum(db).generic_params(db); | 435 | let generics = def.parent_enum(db).generic_params(db); |
405 | let substs = Substs::identity(&generics); | 436 | let substs = Substs::identity(&generics); |
406 | let ret = type_for_enum(db, def.parent_enum(db)).subst(&substs); | 437 | let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); |
407 | FnSig::from_params_and_return(params, ret) | 438 | FnSig::from_params_and_return(params, ret) |
408 | } | 439 | } |
409 | 440 | ||
@@ -411,21 +442,16 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) | |||
411 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | 442 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { |
412 | let var_data = def.variant_data(db); | 443 | let var_data = def.variant_data(db); |
413 | if var_data.fields().is_none() { | 444 | if var_data.fields().is_none() { |
414 | return type_for_enum(db, def.parent_enum(db)); // Unit variant | 445 | return type_for_adt(db, def.parent_enum(db)); // Unit variant |
415 | } | 446 | } |
416 | let generics = def.parent_enum(db).generic_params(db); | 447 | let generics = def.parent_enum(db).generic_params(db); |
417 | let substs = Substs::identity(&generics); | 448 | let substs = Substs::identity(&generics); |
418 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 449 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
419 | } | 450 | } |
420 | 451 | ||
421 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { | 452 | fn type_for_adt(db: &impl HirDatabase, adt: impl Into<AdtDef> + HasGenericParams) -> Ty { |
422 | let generics = s.generic_params(db); | 453 | let generics = adt.generic_params(db); |
423 | Ty::apply(TypeCtor::Adt(s.into()), Substs::identity(&generics)) | 454 | Ty::apply(TypeCtor::Adt(adt.into()), Substs::identity(&generics)) |
424 | } | ||
425 | |||
426 | fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { | ||
427 | let generics = s.generic_params(db); | ||
428 | Ty::apply(TypeCtor::Adt(s.into()), Substs::identity(&generics)) | ||
429 | } | 455 | } |
430 | 456 | ||
431 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { | 457 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index f8364203d..cd24faba5 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -1449,6 +1449,35 @@ fn test() { | |||
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | #[test] | 1451 | #[test] |
1452 | fn infer_associated_method_generics_with_default_param() { | ||
1453 | assert_snapshot_matches!( | ||
1454 | infer(r#" | ||
1455 | struct Gen<T=u32> { | ||
1456 | val: T | ||
1457 | } | ||
1458 | |||
1459 | impl<T> Gen<T> { | ||
1460 | pub fn make() -> Gen<T> { | ||
1461 | loop { } | ||
1462 | } | ||
1463 | } | ||
1464 | |||
1465 | fn test() { | ||
1466 | let a = Gen::make(); | ||
1467 | } | ||
1468 | "#), | ||
1469 | @r###" | ||
1470 | [80; 104) '{ ... }': ! | ||
1471 | [90; 98) 'loop { }': ! | ||
1472 | [95; 98) '{ }': () | ||
1473 | [118; 146) '{ ...e(); }': () | ||
1474 | [128; 129) 'a': Gen<u32> | ||
1475 | [132; 141) 'Gen::make': fn make<u32>() -> Gen<T> | ||
1476 | [132; 143) 'Gen::make()': Gen<u32>"### | ||
1477 | ); | ||
1478 | } | ||
1479 | |||
1480 | #[test] | ||
1452 | fn infer_associated_method_generics_without_args() { | 1481 | fn infer_associated_method_generics_without_args() { |
1453 | assert_snapshot_matches!( | 1482 | assert_snapshot_matches!( |
1454 | infer(r#" | 1483 | infer(r#" |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 7de04c044..e6c78c0d4 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -4,6 +4,7 @@ use std::sync::{Arc, Mutex}; | |||
4 | use rustc_hash::FxHashSet; | 4 | use rustc_hash::FxHashSet; |
5 | use log::debug; | 5 | use log::debug; |
6 | use chalk_ir::cast::Cast; | 6 | use chalk_ir::cast::Cast; |
7 | use ra_prof::profile; | ||
7 | 8 | ||
8 | use crate::{Crate, Trait, db::HirDatabase, ImplBlock}; | 9 | use crate::{Crate, Trait, db::HirDatabase, ImplBlock}; |
9 | use super::{TraitRef, Ty, Canonical}; | 10 | use super::{TraitRef, Ty, Canonical}; |
@@ -25,7 +26,7 @@ struct ChalkContext<'a, DB> { | |||
25 | krate: Crate, | 26 | krate: Crate, |
26 | } | 27 | } |
27 | 28 | ||
28 | pub(crate) fn solver(_db: &impl HirDatabase, _krate: Crate) -> Arc<Mutex<Solver>> { | 29 | pub(crate) fn solver_query(_db: &impl HirDatabase, _krate: Crate) -> Arc<Mutex<Solver>> { |
29 | // krate parameter is just so we cache a unique solver per crate | 30 | // krate parameter is just so we cache a unique solver per crate |
30 | let solver_choice = chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE }; | 31 | let solver_choice = chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE }; |
31 | debug!("Creating new solver for crate {:?}", _krate); | 32 | debug!("Creating new solver for crate {:?}", _krate); |
@@ -33,7 +34,7 @@ pub(crate) fn solver(_db: &impl HirDatabase, _krate: Crate) -> Arc<Mutex<Solver> | |||
33 | } | 34 | } |
34 | 35 | ||
35 | /// Collects impls for the given trait in the whole dependency tree of `krate`. | 36 | /// Collects impls for the given trait in the whole dependency tree of `krate`. |
36 | pub(crate) fn impls_for_trait( | 37 | pub(crate) fn impls_for_trait_query( |
37 | db: &impl HirDatabase, | 38 | db: &impl HirDatabase, |
38 | krate: Crate, | 39 | krate: Crate, |
39 | trait_: Trait, | 40 | trait_: Trait, |
@@ -60,7 +61,7 @@ fn solve( | |||
60 | let context = ChalkContext { db, krate }; | 61 | let context = ChalkContext { db, krate }; |
61 | let solver = db.solver(krate); | 62 | let solver = db.solver(krate); |
62 | debug!("solve goal: {:?}", goal); | 63 | debug!("solve goal: {:?}", goal); |
63 | let solution = solver.lock().unwrap().solve(&context, goal); | 64 | let solution = solver.lock().unwrap().solve_with_fuel(&context, goal, Some(1000)); |
64 | debug!("solve({:?}) => {:?}", goal, solution); | 65 | debug!("solve({:?}) => {:?}", goal, solution); |
65 | solution | 66 | solution |
66 | } | 67 | } |
@@ -76,11 +77,12 @@ pub enum Obligation { | |||
76 | } | 77 | } |
77 | 78 | ||
78 | /// Check using Chalk whether trait is implemented for given parameters including `Self` type. | 79 | /// Check using Chalk whether trait is implemented for given parameters including `Self` type. |
79 | pub(crate) fn implements( | 80 | pub(crate) fn implements_query( |
80 | db: &impl HirDatabase, | 81 | db: &impl HirDatabase, |
81 | krate: Crate, | 82 | krate: Crate, |
82 | trait_ref: Canonical<TraitRef>, | 83 | trait_ref: Canonical<TraitRef>, |
83 | ) -> Option<Solution> { | 84 | ) -> Option<Solution> { |
85 | let _p = profile("implements_query"); | ||
84 | let goal: chalk_ir::Goal = trait_ref.value.to_chalk(db).cast(); | 86 | let goal: chalk_ir::Goal = trait_ref.value.to_chalk(db).cast(); |
85 | debug!("goal: {:?}", goal); | 87 | debug!("goal: {:?}", goal); |
86 | let env = chalk_ir::Environment::new(); | 88 | let env = chalk_ir::Environment::new(); |