aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/semantics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/semantics.rs')
-rw-r--r--crates/ra_hir/src/semantics.rs381
1 files changed, 282 insertions, 99 deletions
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 6a49c424a..6f3b3dc9a 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -6,7 +6,7 @@ use std::{cell::RefCell, fmt, iter::successors};
6 6
7use hir_def::{ 7use hir_def::{
8 resolver::{self, HasResolver, Resolver}, 8 resolver::{self, HasResolver, Resolver},
9 AsMacroCall, TraitId, VariantId, 9 AsMacroCall, FunctionId, TraitId, VariantId,
10}; 10};
11use hir_expand::{diagnostics::AstDiagnostic, hygiene::Hygiene, ExpansionInfo}; 11use hir_expand::{diagnostics::AstDiagnostic, hygiene::Hygiene, ExpansionInfo};
12use hir_ty::associated_type_shorthand_candidates; 12use hir_ty::associated_type_shorthand_candidates;
@@ -24,8 +24,8 @@ use crate::{
24 diagnostics::Diagnostic, 24 diagnostics::Diagnostic,
25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
26 source_analyzer::{resolve_hir_path, resolve_hir_path_qualifier, SourceAnalyzer}, 26 source_analyzer::{resolve_hir_path, resolve_hir_path_qualifier, SourceAnalyzer},
27 AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef, 27 AssocItem, Callable, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module,
28 Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, 28 ModuleDef, Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef,
29}; 29};
30use resolver::TypeNs; 30use resolver::TypeNs;
31 31
@@ -83,7 +83,13 @@ impl PathResolution {
83/// Primary API to get semantic information, like types, from syntax trees. 83/// Primary API to get semantic information, like types, from syntax trees.
84pub struct Semantics<'db, DB> { 84pub struct Semantics<'db, DB> {
85 pub db: &'db DB, 85 pub db: &'db DB,
86 imp: SemanticsImpl<'db>,
87}
88
89pub struct SemanticsImpl<'db> {
90 pub db: &'db dyn HirDatabase,
86 s2d_cache: RefCell<SourceToDefCache>, 91 s2d_cache: RefCell<SourceToDefCache>,
92 expansion_info_cache: RefCell<FxHashMap<HirFileId, Option<ExpansionInfo>>>,
87 cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>, 93 cache: RefCell<FxHashMap<SyntaxNode, HirFileId>>,
88} 94}
89 95
@@ -95,23 +101,199 @@ impl<DB> fmt::Debug for Semantics<'_, DB> {
95 101
96impl<'db, DB: HirDatabase> Semantics<'db, DB> { 102impl<'db, DB: HirDatabase> Semantics<'db, DB> {
97 pub fn new(db: &DB) -> Semantics<DB> { 103 pub fn new(db: &DB) -> Semantics<DB> {
98 Semantics { db, s2d_cache: Default::default(), cache: Default::default() } 104 let impl_ = SemanticsImpl::new(db);
105 Semantics { db, imp: impl_ }
99 } 106 }
100 107
101 pub fn parse(&self, file_id: FileId) -> ast::SourceFile { 108 pub fn parse(&self, file_id: FileId) -> ast::SourceFile {
102 let tree = self.db.parse(file_id).tree(); 109 self.imp.parse(file_id)
103 self.cache(tree.syntax().clone(), file_id.into());
104 tree
105 } 110 }
106 111
107 pub fn ast<T: AstDiagnostic + Diagnostic>(&self, d: &T) -> <T as AstDiagnostic>::AST { 112 pub fn ast<T: AstDiagnostic + Diagnostic>(&self, d: &T) -> <T as AstDiagnostic>::AST {
108 let file_id = d.source().file_id; 113 let file_id = d.source().file_id;
109 let root = self.db.parse_or_expand(file_id).unwrap(); 114 let root = self.db.parse_or_expand(file_id).unwrap();
110 self.cache(root, file_id); 115 self.imp.cache(root, file_id);
111 d.ast(self.db) 116 d.ast(self.db.upcast())
112 } 117 }
113 118
114 pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> { 119 pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
120 self.imp.expand(macro_call)
121 }
122
123 pub fn expand_hypothetical(
124 &self,
125 actual_macro_call: &ast::MacroCall,
126 hypothetical_args: &ast::TokenTree,
127 token_to_map: SyntaxToken,
128 ) -> Option<(SyntaxNode, SyntaxToken)> {
129 self.imp.expand_hypothetical(actual_macro_call, hypothetical_args, token_to_map)
130 }
131
132 pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken {
133 self.imp.descend_into_macros(token)
134 }
135
136 pub fn descend_node_at_offset<N: ast::AstNode>(
137 &self,
138 node: &SyntaxNode,
139 offset: TextSize,
140 ) -> Option<N> {
141 self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
142 }
143
144 pub fn original_range(&self, node: &SyntaxNode) -> FileRange {
145 self.imp.original_range(node)
146 }
147
148 pub fn diagnostics_range(&self, diagnostics: &dyn Diagnostic) -> FileRange {
149 self.imp.diagnostics_range(diagnostics)
150 }
151
152 pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
153 self.imp.ancestors_with_macros(node)
154 }
155
156 pub fn ancestors_at_offset_with_macros(
157 &self,
158 node: &SyntaxNode,
159 offset: TextSize,
160 ) -> impl Iterator<Item = SyntaxNode> + '_ {
161 self.imp.ancestors_at_offset_with_macros(node, offset)
162 }
163
164 /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*,
165 /// search up until it is of the target AstNode type
166 pub fn find_node_at_offset_with_macros<N: AstNode>(
167 &self,
168 node: &SyntaxNode,
169 offset: TextSize,
170 ) -> Option<N> {
171 self.imp.ancestors_at_offset_with_macros(node, offset).find_map(N::cast)
172 }
173
174 /// Find a AstNode by offset inside SyntaxNode, if it is inside *MacroCall*,
175 /// descend it and find again
176 pub fn find_node_at_offset_with_descend<N: AstNode>(
177 &self,
178 node: &SyntaxNode,
179 offset: TextSize,
180 ) -> Option<N> {
181 if let Some(it) = find_node_at_offset(&node, offset) {
182 return Some(it);
183 }
184
185 self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
186 }
187
188 pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
189 self.imp.type_of_expr(expr)
190 }
191
192 pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
193 self.imp.type_of_pat(pat)
194 }
195
196 pub fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
197 self.imp.type_of_self(param)
198 }
199
200 pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
201 self.imp.resolve_method_call(call).map(Function::from)
202 }
203
204 pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
205 self.imp.resolve_method_call_as_callable(call)
206 }
207
208 pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> {
209 self.imp.resolve_field(field)
210 }
211
212 pub fn resolve_record_field(
213 &self,
214 field: &ast::RecordExprField,
215 ) -> Option<(Field, Option<Local>)> {
216 self.imp.resolve_record_field(field)
217 }
218
219 pub fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> {
220 self.imp.resolve_record_field_pat(field)
221 }
222
223 pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> {
224 self.imp.resolve_macro_call(macro_call)
225 }
226
227 pub fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
228 self.imp.resolve_path(path)
229 }
230
231 pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantDef> {
232 self.imp.resolve_variant(record_lit).map(VariantDef::from)
233 }
234
235 pub fn lower_path(&self, path: &ast::Path) -> Option<Path> {
236 self.imp.lower_path(path)
237 }
238
239 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> {
240 self.imp.resolve_bind_pat_to_const(pat)
241 }
242
243 // FIXME: use this instead?
244 // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
245
246 pub fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> {
247 self.imp.record_literal_missing_fields(literal)
248 }
249
250 pub fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> {
251 self.imp.record_pattern_missing_fields(pattern)
252 }
253
254 pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
255 let src = self.imp.find_file(src.syntax().clone()).with_value(src).cloned();
256 T::to_def(&self.imp, src)
257 }
258
259 pub fn to_module_def(&self, file: FileId) -> Option<Module> {
260 self.imp.to_module_def(file)
261 }
262
263 pub fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
264 self.imp.scope(node)
265 }
266
267 pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> {
268 self.imp.scope_at_offset(node, offset)
269 }
270
271 pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
272 self.imp.scope_for_def(def)
273 }
274
275 pub fn assert_contains_node(&self, node: &SyntaxNode) {
276 self.imp.assert_contains_node(node)
277 }
278}
279
280impl<'db> SemanticsImpl<'db> {
281 fn new(db: &'db dyn HirDatabase) -> Self {
282 SemanticsImpl {
283 db,
284 s2d_cache: Default::default(),
285 cache: Default::default(),
286 expansion_info_cache: Default::default(),
287 }
288 }
289
290 fn parse(&self, file_id: FileId) -> ast::SourceFile {
291 let tree = self.db.parse(file_id).tree();
292 self.cache(tree.syntax().clone(), file_id.into());
293 tree
294 }
295
296 fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
115 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); 297 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call);
116 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); 298 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None);
117 let file_id = sa.expand(self.db, macro_call)?; 299 let file_id = sa.expand(self.db, macro_call)?;
@@ -120,7 +302,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
120 Some(node) 302 Some(node)
121 } 303 }
122 304
123 pub fn expand_hypothetical( 305 fn expand_hypothetical(
124 &self, 306 &self,
125 actual_macro_call: &ast::MacroCall, 307 actual_macro_call: &ast::MacroCall,
126 hypothetical_args: &ast::TokenTree, 308 hypothetical_args: &ast::TokenTree,
@@ -130,24 +312,38 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
130 self.find_file(actual_macro_call.syntax().clone()).with_value(actual_macro_call); 312 self.find_file(actual_macro_call.syntax().clone()).with_value(actual_macro_call);
131 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); 313 let sa = self.analyze2(macro_call.map(|it| it.syntax()), None);
132 let krate = sa.resolver.krate()?; 314 let krate = sa.resolver.krate()?;
133 let macro_call_id = macro_call 315 let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
134 .as_call_id(self.db, krate, |path| sa.resolver.resolve_path_as_macro(self.db, &path))?; 316 sa.resolver.resolve_path_as_macro(self.db.upcast(), &path)
135 hir_expand::db::expand_hypothetical(self.db, macro_call_id, hypothetical_args, token_to_map) 317 })?;
136 } 318 hir_expand::db::expand_hypothetical(
137 319 self.db.upcast(),
138 pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { 320 macro_call_id,
321 hypothetical_args,
322 token_to_map,
323 )
324 }
325
326 fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken {
327 let _p = profile("descend_into_macros");
139 let parent = token.parent(); 328 let parent = token.parent();
140 let parent = self.find_file(parent); 329 let parent = self.find_file(parent);
141 let sa = self.analyze2(parent.as_ref(), None); 330 let sa = self.analyze2(parent.as_ref(), None);
142 331
143 let token = successors(Some(parent.with_value(token)), |token| { 332 let token = successors(Some(parent.with_value(token)), |token| {
333 self.db.check_canceled();
144 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; 334 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
145 let tt = macro_call.token_tree()?; 335 let tt = macro_call.token_tree()?;
146 if !tt.syntax().text_range().contains_range(token.value.text_range()) { 336 if !tt.syntax().text_range().contains_range(token.value.text_range()) {
147 return None; 337 return None;
148 } 338 }
149 let file_id = sa.expand(self.db, token.with_value(&macro_call))?; 339 let file_id = sa.expand(self.db, token.with_value(&macro_call))?;
150 let token = file_id.expansion_info(self.db)?.map_token_down(token.as_ref())?; 340 let token = self
341 .expansion_info_cache
342 .borrow_mut()
343 .entry(file_id)
344 .or_insert_with(|| file_id.expansion_info(self.db.upcast()))
345 .as_ref()?
346 .map_token_down(token.as_ref())?;
151 347
152 self.cache(find_root(&token.value.parent()), token.file_id); 348 self.cache(find_root(&token.value.parent()), token.file_id);
153 349
@@ -159,35 +355,36 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
159 token.value 355 token.value
160 } 356 }
161 357
162 pub fn descend_node_at_offset<N: ast::AstNode>( 358 fn descend_node_at_offset(
163 &self, 359 &self,
164 node: &SyntaxNode, 360 node: &SyntaxNode,
165 offset: TextSize, 361 offset: TextSize,
166 ) -> Option<N> { 362 ) -> impl Iterator<Item = SyntaxNode> + '_ {
167 // Handle macro token cases 363 // Handle macro token cases
168 node.token_at_offset(offset) 364 node.token_at_offset(offset)
169 .map(|token| self.descend_into_macros(token)) 365 .map(|token| self.descend_into_macros(token))
170 .find_map(|it| self.ancestors_with_macros(it.parent()).find_map(N::cast)) 366 .map(|it| self.ancestors_with_macros(it.parent()))
367 .flatten()
171 } 368 }
172 369
173 pub fn original_range(&self, node: &SyntaxNode) -> FileRange { 370 fn original_range(&self, node: &SyntaxNode) -> FileRange {
174 let node = self.find_file(node.clone()); 371 let node = self.find_file(node.clone());
175 original_range(self.db, node.as_ref()) 372 original_range(self.db, node.as_ref())
176 } 373 }
177 374
178 pub fn diagnostics_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { 375 fn diagnostics_range(&self, diagnostics: &dyn Diagnostic) -> FileRange {
179 let src = diagnostics.source(); 376 let src = diagnostics.source();
180 let root = self.db.parse_or_expand(src.file_id).unwrap(); 377 let root = self.db.parse_or_expand(src.file_id).unwrap();
181 let node = src.value.to_node(&root); 378 let node = src.value.to_node(&root);
182 original_range(self.db, src.with_value(&node)) 379 original_range(self.db, src.with_value(&node))
183 } 380 }
184 381
185 pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { 382 fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ {
186 let node = self.find_file(node); 383 let node = self.find_file(node);
187 node.ancestors_with_macros(self.db).map(|it| it.value) 384 node.ancestors_with_macros(self.db.upcast()).map(|it| it.value)
188 } 385 }
189 386
190 pub fn ancestors_at_offset_with_macros( 387 fn ancestors_at_offset_with_macros(
191 &self, 388 &self,
192 node: &SyntaxNode, 389 node: &SyntaxNode,
193 offset: TextSize, 390 offset: TextSize,
@@ -197,120 +394,104 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
197 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) 394 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
198 } 395 }
199 396
200 /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*, 397 fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
201 /// search up until it is of the target AstNode type 398 self.analyze(expr.syntax()).type_of_expr(self.db, &expr)
202 pub fn find_node_at_offset_with_macros<N: AstNode>(
203 &self,
204 node: &SyntaxNode,
205 offset: TextSize,
206 ) -> Option<N> {
207 self.ancestors_at_offset_with_macros(node, offset).find_map(N::cast)
208 } 399 }
209 400
210 /// Find a AstNode by offset inside SyntaxNode, if it is inside *MacroCall*, 401 fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
211 /// descend it and find again 402 self.analyze(pat.syntax()).type_of_pat(self.db, &pat)
212 pub fn find_node_at_offset_with_descend<N: AstNode>(
213 &self,
214 node: &SyntaxNode,
215 offset: TextSize,
216 ) -> Option<N> {
217 if let Some(it) = find_node_at_offset(&node, offset) {
218 return Some(it);
219 }
220 self.descend_node_at_offset(&node, offset)
221 } 403 }
222 404
223 pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { 405 fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
224 self.analyze(expr.syntax()).type_of(self.db, &expr) 406 self.analyze(param.syntax()).type_of_self(self.db, &param)
225 } 407 }
226 408
227 pub fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { 409 fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> {
228 self.analyze(pat.syntax()).type_of_pat(self.db, &pat) 410 self.analyze(call.syntax()).resolve_method_call(self.db, call)
229 } 411 }
230 412
231 pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { 413 fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
232 self.analyze(call.syntax()).resolve_method_call(self.db, call) 414 // FIXME: this erases Substs
415 let func = self.resolve_method_call(call)?;
416 let ty = self.db.value_ty(func.into());
417 let resolver = self.analyze(call.syntax()).resolver;
418 let ty = Type::new_with_resolver(self.db, &resolver, ty.value)?;
419 let mut res = ty.as_callable(self.db)?;
420 res.is_bound_method = true;
421 Some(res)
233 } 422 }
234 423
235 pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> { 424 fn resolve_field(&self, field: &ast::FieldExpr) -> Option<Field> {
236 self.analyze(field.syntax()).resolve_field(self.db, field) 425 self.analyze(field.syntax()).resolve_field(self.db, field)
237 } 426 }
238 427
239 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<(Field, Option<Local>)> { 428 fn resolve_record_field(&self, field: &ast::RecordExprField) -> Option<(Field, Option<Local>)> {
240 self.analyze(field.syntax()).resolve_record_field(self.db, field) 429 self.analyze(field.syntax()).resolve_record_field(self.db, field)
241 } 430 }
242 431
243 pub fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> { 432 fn resolve_record_field_pat(&self, field: &ast::RecordFieldPat) -> Option<Field> {
244 self.analyze(field.syntax()).resolve_record_field_pat(self.db, field) 433 self.analyze(field.syntax()).resolve_record_field_pat(self.db, field)
245 } 434 }
246 435
247 pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> { 436 fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> {
248 let sa = self.analyze(macro_call.syntax()); 437 let sa = self.analyze(macro_call.syntax());
249 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); 438 let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call);
250 sa.resolve_macro_call(self.db, macro_call) 439 sa.resolve_macro_call(self.db, macro_call)
251 } 440 }
252 441
253 pub fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> { 442 fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
254 self.analyze(path.syntax()).resolve_path(self.db, path) 443 self.analyze(path.syntax()).resolve_path(self.db, path)
255 } 444 }
256 445
257 pub fn resolve_variant(&self, record_lit: ast::RecordLit) -> Option<VariantId> { 446 fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> {
258 self.analyze(record_lit.syntax()).resolve_variant(self.db, record_lit) 447 self.analyze(record_lit.syntax()).resolve_variant(self.db, record_lit)
259 } 448 }
260 449
261 pub fn lower_path(&self, path: &ast::Path) -> Option<Path> { 450 fn lower_path(&self, path: &ast::Path) -> Option<Path> {
262 let src = self.find_file(path.syntax().clone()); 451 let src = self.find_file(path.syntax().clone());
263 Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into())) 452 Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into()))
264 } 453 }
265 454
266 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { 455 fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> {
267 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) 456 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat)
268 } 457 }
269 458
270 // FIXME: use this instead? 459 fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> {
271 // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
272
273 pub fn record_literal_missing_fields(&self, literal: &ast::RecordLit) -> Vec<(Field, Type)> {
274 self.analyze(literal.syntax()) 460 self.analyze(literal.syntax())
275 .record_literal_missing_fields(self.db, literal) 461 .record_literal_missing_fields(self.db, literal)
276 .unwrap_or_default() 462 .unwrap_or_default()
277 } 463 }
278 464
279 pub fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> { 465 fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> {
280 self.analyze(pattern.syntax()) 466 self.analyze(pattern.syntax())
281 .record_pattern_missing_fields(self.db, pattern) 467 .record_pattern_missing_fields(self.db, pattern)
282 .unwrap_or_default() 468 .unwrap_or_default()
283 } 469 }
284 470
285 pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
286 let src = self.find_file(src.syntax().clone()).with_value(src).cloned();
287 T::to_def(self, src)
288 }
289
290 fn with_ctx<F: FnOnce(&mut SourceToDefCtx) -> T, T>(&self, f: F) -> T { 471 fn with_ctx<F: FnOnce(&mut SourceToDefCtx) -> T, T>(&self, f: F) -> T {
291 let mut cache = self.s2d_cache.borrow_mut(); 472 let mut cache = self.s2d_cache.borrow_mut();
292 let mut ctx = SourceToDefCtx { db: self.db, cache: &mut *cache }; 473 let mut ctx = SourceToDefCtx { db: self.db, cache: &mut *cache };
293 f(&mut ctx) 474 f(&mut ctx)
294 } 475 }
295 476
296 pub fn to_module_def(&self, file: FileId) -> Option<Module> { 477 fn to_module_def(&self, file: FileId) -> Option<Module> {
297 self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from) 478 self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from)
298 } 479 }
299 480
300 pub fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db, DB> { 481 fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
301 let node = self.find_file(node.clone()); 482 let node = self.find_file(node.clone());
302 let resolver = self.analyze2(node.as_ref(), None).resolver; 483 let resolver = self.analyze2(node.as_ref(), None).resolver;
303 SemanticsScope { db: self.db, resolver } 484 SemanticsScope { db: self.db, resolver }
304 } 485 }
305 486
306 pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db, DB> { 487 fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> {
307 let node = self.find_file(node.clone()); 488 let node = self.find_file(node.clone());
308 let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver; 489 let resolver = self.analyze2(node.as_ref(), Some(offset)).resolver;
309 SemanticsScope { db: self.db, resolver } 490 SemanticsScope { db: self.db, resolver }
310 } 491 }
311 492
312 pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db, DB> { 493 fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
313 let resolver = def.id.resolver(self.db); 494 let resolver = def.id.resolver(self.db.upcast());
314 SemanticsScope { db: self.db, resolver } 495 SemanticsScope { db: self.db, resolver }
315 } 496 }
316 497
@@ -331,12 +512,13 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
331 ChildContainer::DefWithBodyId(def) => { 512 ChildContainer::DefWithBodyId(def) => {
332 return SourceAnalyzer::new_for_body(self.db, def, src, offset) 513 return SourceAnalyzer::new_for_body(self.db, def, src, offset)
333 } 514 }
334 ChildContainer::TraitId(it) => it.resolver(self.db), 515 ChildContainer::TraitId(it) => it.resolver(self.db.upcast()),
335 ChildContainer::ImplId(it) => it.resolver(self.db), 516 ChildContainer::ImplId(it) => it.resolver(self.db.upcast()),
336 ChildContainer::ModuleId(it) => it.resolver(self.db), 517 ChildContainer::ModuleId(it) => it.resolver(self.db.upcast()),
337 ChildContainer::EnumId(it) => it.resolver(self.db), 518 ChildContainer::EnumId(it) => it.resolver(self.db.upcast()),
338 ChildContainer::VariantId(it) => it.resolver(self.db), 519 ChildContainer::VariantId(it) => it.resolver(self.db.upcast()),
339 ChildContainer::GenericDefId(it) => it.resolver(self.db), 520 ChildContainer::TypeAliasId(it) => it.resolver(self.db.upcast()),
521 ChildContainer::GenericDefId(it) => it.resolver(self.db.upcast()),
340 }; 522 };
341 SourceAnalyzer::new_for_resolver(resolver, src) 523 SourceAnalyzer::new_for_resolver(resolver, src)
342 } 524 }
@@ -348,7 +530,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
348 assert!(prev == None || prev == Some(file_id)) 530 assert!(prev == None || prev == Some(file_id))
349 } 531 }
350 532
351 pub fn assert_contains_node(&self, node: &SyntaxNode) { 533 fn assert_contains_node(&self, node: &SyntaxNode) {
352 self.find_file(node.clone()); 534 self.find_file(node.clone());
353 } 535 }
354 536
@@ -382,14 +564,14 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
382pub trait ToDef: AstNode + Clone { 564pub trait ToDef: AstNode + Clone {
383 type Def; 565 type Def;
384 566
385 fn to_def<DB: HirDatabase>(sema: &Semantics<DB>, src: InFile<Self>) -> Option<Self::Def>; 567 fn to_def(sema: &SemanticsImpl, src: InFile<Self>) -> Option<Self::Def>;
386} 568}
387 569
388macro_rules! to_def_impls { 570macro_rules! to_def_impls {
389 ($(($def:path, $ast:path, $meth:ident)),* ,) => {$( 571 ($(($def:path, $ast:path, $meth:ident)),* ,) => {$(
390 impl ToDef for $ast { 572 impl ToDef for $ast {
391 type Def = $def; 573 type Def = $def;
392 fn to_def<DB: HirDatabase>(sema: &Semantics<DB>, src: InFile<Self>) -> Option<Self::Def> { 574 fn to_def(sema: &SemanticsImpl, src: InFile<Self>) -> Option<Self::Def> {
393 sema.with_ctx(|ctx| ctx.$meth(src)).map(<$def>::from) 575 sema.with_ctx(|ctx| ctx.$meth(src)).map(<$def>::from)
394 } 576 }
395 } 577 }
@@ -398,18 +580,18 @@ macro_rules! to_def_impls {
398 580
399to_def_impls![ 581to_def_impls![
400 (crate::Module, ast::Module, module_to_def), 582 (crate::Module, ast::Module, module_to_def),
401 (crate::Struct, ast::StructDef, struct_to_def), 583 (crate::Struct, ast::Struct, struct_to_def),
402 (crate::Enum, ast::EnumDef, enum_to_def), 584 (crate::Enum, ast::Enum, enum_to_def),
403 (crate::Union, ast::UnionDef, union_to_def), 585 (crate::Union, ast::Union, union_to_def),
404 (crate::Trait, ast::TraitDef, trait_to_def), 586 (crate::Trait, ast::Trait, trait_to_def),
405 (crate::ImplDef, ast::ImplDef, impl_to_def), 587 (crate::ImplDef, ast::Impl, impl_to_def),
406 (crate::TypeAlias, ast::TypeAliasDef, type_alias_to_def), 588 (crate::TypeAlias, ast::TypeAlias, type_alias_to_def),
407 (crate::Const, ast::ConstDef, const_to_def), 589 (crate::Const, ast::Const, const_to_def),
408 (crate::Static, ast::StaticDef, static_to_def), 590 (crate::Static, ast::Static, static_to_def),
409 (crate::Function, ast::FnDef, fn_to_def), 591 (crate::Function, ast::Fn, fn_to_def),
410 (crate::Field, ast::RecordFieldDef, record_field_to_def), 592 (crate::Field, ast::RecordField, record_field_to_def),
411 (crate::Field, ast::TupleFieldDef, tuple_field_to_def), 593 (crate::Field, ast::TupleField, tuple_field_to_def),
412 (crate::EnumVariant, ast::EnumVariant, enum_variant_to_def), 594 (crate::EnumVariant, ast::Variant, enum_variant_to_def),
413 (crate::TypeParam, ast::TypeParam, type_param_to_def), 595 (crate::TypeParam, ast::TypeParam, type_param_to_def),
414 (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros 596 (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros
415 (crate::Local, ast::BindPat, bind_pat_to_def), 597 (crate::Local, ast::BindPat, bind_pat_to_def),
@@ -419,12 +601,13 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode {
419 node.ancestors().last().unwrap() 601 node.ancestors().last().unwrap()
420} 602}
421 603
422pub struct SemanticsScope<'a, DB> { 604#[derive(Debug)]
423 pub db: &'a DB, 605pub struct SemanticsScope<'a> {
606 pub db: &'a dyn HirDatabase,
424 resolver: Resolver, 607 resolver: Resolver,
425} 608}
426 609
427impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> { 610impl<'a> SemanticsScope<'a> {
428 pub fn module(&self) -> Option<Module> { 611 pub fn module(&self) -> Option<Module> {
429 Some(Module { id: self.resolver.module()? }) 612 Some(Module { id: self.resolver.module()? })
430 } 613 }
@@ -433,13 +616,13 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
433 // FIXME: rename to visible_traits to not repeat scope? 616 // FIXME: rename to visible_traits to not repeat scope?
434 pub fn traits_in_scope(&self) -> FxHashSet<TraitId> { 617 pub fn traits_in_scope(&self) -> FxHashSet<TraitId> {
435 let resolver = &self.resolver; 618 let resolver = &self.resolver;
436 resolver.traits_in_scope(self.db) 619 resolver.traits_in_scope(self.db.upcast())
437 } 620 }
438 621
439 pub fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) { 622 pub fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
440 let resolver = &self.resolver; 623 let resolver = &self.resolver;
441 624
442 resolver.process_all_names(self.db, &mut |name, def| { 625 resolver.process_all_names(self.db.upcast(), &mut |name, def| {
443 let def = match def { 626 let def = match def {
444 resolver::ScopeDef::PerNs(it) => { 627 resolver::ScopeDef::PerNs(it) => {
445 let items = ScopeDef::all_items(it); 628 let items = ScopeDef::all_items(it);