aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/db.rs13
-rw-r--r--crates/ra_hir/src/expr/validation.rs77
-rw-r--r--crates/ra_hir/src/generics.rs17
-rw-r--r--crates/ra_hir/src/mock.rs6
-rw-r--r--crates/ra_hir/src/name.rs2
-rw-r--r--crates/ra_hir/src/nameres/tests.rs286
-rw-r--r--crates/ra_hir/src/nameres/tests/globs.rs76
-rw-r--r--crates/ra_hir/src/nameres/tests/macros.rs54
-rw-r--r--crates/ra_hir/src/ty.rs4
-rw-r--r--crates/ra_hir/src/ty/infer.rs4
-rw-r--r--crates/ra_hir/src/ty/infer/unify.rs7
-rw-r--r--crates/ra_hir/src/ty/lower.rs86
-rw-r--r--crates/ra_hir/src/ty/tests.rs29
-rw-r--r--crates/ra_hir/src/ty/traits.rs10
14 files changed, 369 insertions, 302 deletions
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
6use crate::{ 6use 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};
16use super::{Expr, StructLitField, ExprId}; 14use 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
6use std::sync::Arc; 6use std::sync::Arc;
7 7
8use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner}; 8use ra_syntax::ast::{self, NameOwner, TypeParamsOwner, TypeBoundsOwner, DefaultTypeParamOwner};
9 9
10use crate::{ 10use 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
193pub trait HasGenericParams { 200pub 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
197impl<T> HasGenericParams for T 204impl<T> HasGenericParams for T
198where 205where
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)]
239pub struct CrateGraphFixture(pub FxHashMap<String, (String, Edition, Vec<String>)>); 239pub struct CrateGraphFixture(pub Vec<(String, (String, Edition, Vec<String>))>);
240 240
241#[macro_export] 241#[macro_export]
242macro_rules! crate_graph { 242macro_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)]
9pub struct Name { 9pub 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;
8use test_utils::covers; 8use test_utils::covers;
9use insta::assert_snapshot_matches; 9use insta::assert_snapshot_matches;
10 10
11use crate::{Crate, mock::{MockDatabase, CrateGraphFixture}, nameres::Resolution}; 11use crate::{
12 Crate,
13 mock::{MockDatabase, CrateGraphFixture},
14 nameres::Resolution,
15};
12 16
13use super::*; 17use super::*;
14 18
@@ -25,12 +29,15 @@ fn compute_crate_def_map(fixture: &str, graph: Option<CrateGraphFixture>) -> Arc
25fn render_crate_def_map(map: &CrateDefMap) -> String { 29fn 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
57fn def_map_with_crate_graph(fixtute: &str, graph: CrateGraphFixture) -> String { 64fn 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###"
82crate 89 â‹®crate
83V: t v 90 â‹®E: t
84E: t 91 â‹®S: t v
85foo: t 92 â‹®V: t v
86S: t v 93 â‹®foo: t
87 94 â‹®
88crate::foo 95 â‹®crate::foo
89bar: t 96 â‹®bar: t
90f: v 97 â‹®f: v
91 98 â‹®
92crate::foo::bar 99 â‹®crate::foo::bar
93Baz: t v 100 â‹®Baz: t v
94E: 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###"
116crate 122 â‹®crate
117foo: t 123 â‹®S: t v
118S: t v 124 â‹®foo: t
119 125 â‹®
120crate::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###"
140crate 146 â‹®crate
141Foo: t v 147 â‹®Foo: t v
142foo: t 148 â‹®foo: t
143 149 â‹®
144crate::foo 150 â‹®crate::foo
145Baz: 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
169crate 175 â‹®Baz: t v
170Quux: t 176 â‹®Quux: t
171Baz: t v 177 â‹®foo: t
172foo: t 178 â‹®
173 179 â‹®crate::foo
174crate::foo 180 â‹®bar: t
175bar: t 181 â‹®
176 182 â‹®crate::foo::bar
177crate::foo::bar 183 â‹®Baz: t v
178Quux: t 184 â‹®Quux: t
179Baz: 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
204crate 208 â‹®Baz: t v
205Baz: t v 209 â‹®foo: t
206foo: t 210 â‹®
207 211 â‹®crate::foo
208crate::foo 212 â‹®Baz: t v
209bar: t 213 â‹®bar: t
210Baz: t v 214 â‹®
211 215 â‹®crate::foo::bar
212crate::foo::bar 216 â‹®Baz: t v
213Baz: 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###"
240crate 242 â‹®crate
241Bar: t v 243 â‹®Bar: t v
242Baz: 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###"
257crate 259 â‹®crate
258V: t v 260 â‹®E: t
259E: 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
290crate 292 â‹®bar: t
291bar: t 293 â‹®foo: t
292foo: t 294 â‹®
293 295 â‹®crate::bar
294crate::bar 296 â‹®Bar: t v
295Bar: t v 297 â‹®
296 298 â‹®crate::foo
297crate::foo 299 â‹®Bar: t v
298FromLib: t v 300 â‹®FromLib: t v
299Bar: 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
322crate 322 â‹®Bar: t v
323Bar: t v 323 â‹®foo: t
324foo: t 324 â‹®
325 325 â‹®crate::foo
326crate::foo 326 â‹®Bar: t v
327Bar: 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
353crate 351 â‹®Baz: _
354Baz: _ 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
374crate 370 â‹®Baz: t v
375Baz: t v 371 â‹®foo: t
376foo: t 372 â‹®
377 373 â‹®crate::foo
378crate::foo 374 â‹®bar: t
379bar: t 375 â‹®
380 376 â‹®crate::foo::bar
381crate::foo::bar 377 â‹®Baz: t v
382Baz: 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
405crate 399 â‹®Baz: t v
406Baz: 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
435crate 427 â‹®alloc_crate: t
436Arc: 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###"
465crate 459 â‹®crate
466Arc: 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
495crate 493 â‹®C: t v
496C: 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
524crate 520 â‹®Baz: t v
525Baz: 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
549crate 543 â‹®Bar: t v
550Bar: t v 544 â‹®foo: v
551foo: 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###"
21crate 21 â‹®crate
22bar: t 22 â‹®Baz: t v
23Foo: t v 23 â‹®Foo: t v
24Baz: t v 24 â‹®bar: t
25foo: t 25 â‹®foo: t
26 26 â‹®
27crate::foo 27 â‹®crate::foo
28bar: t 28 â‹®Baz: t v
29Foo: t v 29 â‹®Foo: t v
30Baz: t v 30 â‹®bar: t
31 31 â‹®
32crate::foo::bar 32 â‹®crate::foo::bar
33Baz: 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###"
57crate 57 â‹®crate
58bar: t 58 â‹®Baz: t v
59Foo: t v 59 â‹®Foo: t v
60Baz: t v 60 â‹®bar: t
61foo: t 61 â‹®foo: t
62 62 â‹®
63crate::foo 63 â‹®crate::foo
64bar: t 64 â‹®Baz: t v
65Foo: t v 65 â‹®Foo: t v
66Baz: t v 66 â‹®bar: t
67 67 â‹®
68crate::foo::bar 68 â‹®crate::foo::bar
69bar: t 69 â‹®Baz: t v
70Foo: t v 70 â‹®Foo: t v
71Baz: 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###"
93crate 93 â‹®crate
94Baz: 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###"
112crate 112 â‹®crate
113Foo: t 113 â‹®Bar: t v
114Bar: t v 114 â‹®Baz: t v
115Baz: 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###"
21crate 21 â‹®crate
22nested: t 22 â‹®Foo: t v
23Foo: t v 23 â‹®nested: t
24 24 â‹®
25crate::nested 25 â‹®crate::nested
26Bar: t v 26 â‹®Bar: t v
27Baz: 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###"
48crate 48 â‹®crate
49n1: t 49 â‹®n1: t
50 50 â‹®
51crate::n1 51 â‹®crate::n1
52n2: t 52 â‹®n2: t
53 53 â‹®
54crate::n1::n2 54 â‹®crate::n1::n2
55X: 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###"
84crate 84 â‹®crate
85bar: t 85 â‹®Bar: t v
86Foo: t v 86 â‹®Foo: t v
87Bar: t v 87 â‹®bar: t
88 88 â‹®
89crate::bar 89 â‹®crate::bar
90bar: t 90 â‹®Bar: t v
91Foo: t v 91 â‹®Foo: t v
92Bar: 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};
19use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams}; 19use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase, Trait, GenericParams};
20use display::{HirDisplay, HirFormatter}; 20use display::{HirDisplay, HirFormatter};
21 21
22pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig, generic_predicates}; 22pub(crate) use lower::{TypableDef, type_for_def, type_for_field, callable_item_sig, generic_predicates, generic_defaults};
23pub(crate) use infer::{infer, InferenceResult, InferTy}; 23pub(crate) use infer::{infer_query, InferenceResult, InferTy};
24pub use lower::CallableDef; 24pub 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};
23use rustc_hash::FxHashMap; 23use rustc_hash::FxHashMap;
24 24
25use ra_arena::map::ArenaMap; 25use ra_arena::map::ArenaMap;
26use ra_prof::profile;
26use test_utils::tested_by; 27use test_utils::tested_by;
27 28
28use crate::{ 29use crate::{
@@ -51,7 +52,8 @@ use super::{
51mod unify; 52mod unify;
52 53
53/// The entry point of type inference. 54/// The entry point of type inference.
54pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { 55pub 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;
9use std::iter; 9use std::iter;
10 10
11use crate::{ 11use 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};
24use super::{Ty, primitive, FnSig, Substs, TypeCtor, TraitRef, GenericPredicate}; 25use 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 {
274pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace) -> Ty { 289pub(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
350pub(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
334fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 365fn 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 {
383fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { 414fn 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)
411fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { 442fn 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
421fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { 452fn 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
426fn 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
431fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 457fn 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]
1452fn infer_associated_method_generics_with_default_param() {
1453 assert_snapshot_matches!(
1454 infer(r#"
1455struct Gen<T=u32> {
1456 val: T
1457}
1458
1459impl<T> Gen<T> {
1460 pub fn make() -> Gen<T> {
1461 loop { }
1462 }
1463}
1464
1465fn 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]
1452fn infer_associated_method_generics_without_args() { 1481fn 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};
4use rustc_hash::FxHashSet; 4use rustc_hash::FxHashSet;
5use log::debug; 5use log::debug;
6use chalk_ir::cast::Cast; 6use chalk_ir::cast::Cast;
7use ra_prof::profile;
7 8
8use crate::{Crate, Trait, db::HirDatabase, ImplBlock}; 9use crate::{Crate, Trait, db::HirDatabase, ImplBlock};
9use super::{TraitRef, Ty, Canonical}; 10use super::{TraitRef, Ty, Canonical};
@@ -25,7 +26,7 @@ struct ChalkContext<'a, DB> {
25 krate: Crate, 26 krate: Crate,
26} 27}
27 28
28pub(crate) fn solver(_db: &impl HirDatabase, _krate: Crate) -> Arc<Mutex<Solver>> { 29pub(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`.
36pub(crate) fn impls_for_trait( 37pub(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.
79pub(crate) fn implements( 80pub(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();