Skip to content

Commit e424545

Browse files
committed
Rudimentary name resolution for local items
1 parent 7c405c0 commit e424545

File tree

6 files changed

+145
-49
lines changed

6 files changed

+145
-49
lines changed

crates/ra_hir_def/src/body/lower.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -494,45 +494,57 @@ where
494494
fn collect_block_items(&mut self, block: &ast::Block) {
495495
let container = ContainerId::DefWithBodyId(self.def);
496496
for item in block.items() {
497-
let def: ModuleDefId = match item {
497+
let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
498498
ast::ModuleItem::FnDef(def) => {
499499
let ast_id = self.expander.ast_id(&def);
500-
FunctionLoc { container: container.into(), ast_id }.intern(self.db).into()
500+
(
501+
FunctionLoc { container: container.into(), ast_id }.intern(self.db).into(),
502+
def.name(),
503+
)
501504
}
502505
ast::ModuleItem::TypeAliasDef(def) => {
503506
let ast_id = self.expander.ast_id(&def);
504-
TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into()
507+
(
508+
TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into(),
509+
def.name(),
510+
)
505511
}
506512
ast::ModuleItem::ConstDef(def) => {
507513
let ast_id = self.expander.ast_id(&def);
508-
ConstLoc { container: container.into(), ast_id }.intern(self.db).into()
514+
(
515+
ConstLoc { container: container.into(), ast_id }.intern(self.db).into(),
516+
def.name(),
517+
)
509518
}
510519
ast::ModuleItem::StaticDef(def) => {
511520
let ast_id = self.expander.ast_id(&def);
512-
StaticLoc { container, ast_id }.intern(self.db).into()
521+
(StaticLoc { container, ast_id }.intern(self.db).into(), def.name())
513522
}
514523
ast::ModuleItem::StructDef(def) => {
515524
let ast_id = self.expander.ast_id(&def);
516-
StructLoc { container, ast_id }.intern(self.db).into()
525+
(StructLoc { container, ast_id }.intern(self.db).into(), def.name())
517526
}
518527
ast::ModuleItem::EnumDef(def) => {
519528
let ast_id = self.expander.ast_id(&def);
520-
EnumLoc { container, ast_id }.intern(self.db).into()
529+
(EnumLoc { container, ast_id }.intern(self.db).into(), def.name())
521530
}
522531
ast::ModuleItem::UnionDef(def) => {
523532
let ast_id = self.expander.ast_id(&def);
524-
UnionLoc { container, ast_id }.intern(self.db).into()
533+
(UnionLoc { container, ast_id }.intern(self.db).into(), def.name())
525534
}
526535
ast::ModuleItem::TraitDef(def) => {
527536
let ast_id = self.expander.ast_id(&def);
528-
TraitLoc { container, ast_id }.intern(self.db).into()
537+
(TraitLoc { container, ast_id }.intern(self.db).into(), def.name())
529538
}
530539
ast::ModuleItem::ImplBlock(_)
531540
| ast::ModuleItem::UseItem(_)
532541
| ast::ModuleItem::ExternCrateItem(_)
533542
| ast::ModuleItem::Module(_) => continue,
534543
};
535-
self.body.item_scope.define_def(def)
544+
self.body.item_scope.define_def(def);
545+
if let Some(name) = name {
546+
self.body.item_scope.push_res(name.as_name(), def.into());
547+
}
536548
}
537549
}
538550

crates/ra_hir_def/src/item_scope.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ impl ItemScope {
5151
self.visible.iter().chain(BUILTIN_SCOPE.iter()).map(|(n, def)| (n, *def))
5252
}
5353

54+
pub fn entries_without_primitives<'a>(
55+
&'a self,
56+
) -> impl Iterator<Item = (&'a Name, PerNs)> + 'a {
57+
self.visible.iter().map(|(n, def)| (n, *def))
58+
}
59+
5460
pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
5561
self.defs.iter().copied()
5662
}
@@ -118,7 +124,7 @@ impl ItemScope {
118124
self.legacy_macros.insert(name, mac);
119125
}
120126

121-
pub(crate) fn push_res(&mut self, name: Name, def: &PerNs) -> bool {
127+
pub(crate) fn push_res(&mut self, name: Name, def: PerNs) -> bool {
122128
let mut changed = false;
123129
let existing = self.visible.entry(name.clone()).or_default();
124130

crates/ra_hir_def/src/nameres/collector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ where
446446
let scope = &mut self.def_map.modules[module_id].scope;
447447
let mut changed = false;
448448
for (name, res) in resolutions {
449-
changed |= scope.push_res(name.clone(), res);
449+
changed |= scope.push_res(name.clone(), *res);
450450
}
451451

452452
if !changed {

crates/ra_hir_def/src/resolver.rs

Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hash::FxHashSet;
1010

1111
use crate::{
1212
body::scope::{ExprScopes, ScopeId},
13+
body::Body,
1314
builtin_type::BuiltinType,
1415
db::DefDatabase,
1516
expr::{ExprId, PatId},
@@ -55,6 +56,8 @@ enum Scope {
5556
AdtScope(AdtId),
5657
/// Local bindings
5758
ExprScope(ExprScope),
59+
/// Temporary hack to support local items.
60+
LocalItemsScope(Arc<Body>),
5861
}
5962

6063
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -149,7 +152,13 @@ impl Resolver {
149152
for scope in self.scopes.iter().rev() {
150153
match scope {
151154
Scope::ExprScope(_) => continue,
152-
Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue,
155+
Scope::GenericParams { .. }
156+
| Scope::ImplBlockScope(_)
157+
| Scope::LocalItemsScope(_)
158+
if skip_to_mod =>
159+
{
160+
continue
161+
}
153162

154163
Scope::GenericParams { params, def } => {
155164
if let Some(local_id) = params.find_by_name(first_name) {
@@ -179,25 +188,35 @@ impl Resolver {
179188
&path,
180189
BuiltinShadowMode::Other,
181190
);
182-
let res = match module_def.take_types()? {
183-
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
184-
ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
185-
186-
ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
187-
ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
188-
189-
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
190-
191-
ModuleDefId::FunctionId(_)
192-
| ModuleDefId::ConstId(_)
193-
| ModuleDefId::StaticId(_)
194-
| ModuleDefId::ModuleId(_) => return None,
195-
};
191+
let res = to_type_ns(module_def)?;
196192
return Some((res, idx));
197193
}
194+
Scope::LocalItemsScope(body) => {
195+
let def = body.item_scope.get(first_name, BuiltinShadowMode::Other);
196+
if let Some(res) = to_type_ns(def) {
197+
return Some((res, None));
198+
}
199+
}
198200
}
199201
}
200-
None
202+
return None;
203+
fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
204+
let res = match per_ns.take_types()? {
205+
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
206+
ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
207+
208+
ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
209+
ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
210+
211+
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
212+
213+
ModuleDefId::FunctionId(_)
214+
| ModuleDefId::ConstId(_)
215+
| ModuleDefId::StaticId(_)
216+
| ModuleDefId::ModuleId(_) => return None,
217+
};
218+
Some(res)
219+
}
201220
}
202221

203222
pub fn resolve_path_in_type_ns_fully(
@@ -227,6 +246,7 @@ impl Resolver {
227246
| Scope::ExprScope(_)
228247
| Scope::GenericParams { .. }
229248
| Scope::ImplBlockScope(_)
249+
| Scope::LocalItemsScope(_)
230250
if skip_to_mod =>
231251
{
232252
continue
@@ -276,20 +296,7 @@ impl Resolver {
276296
);
277297
return match idx {
278298
None => {
279-
let value = match module_def.take_values()? {
280-
ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
281-
ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
282-
ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
283-
ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
284-
ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
285-
286-
ModuleDefId::AdtId(AdtId::EnumId(_))
287-
| ModuleDefId::AdtId(AdtId::UnionId(_))
288-
| ModuleDefId::TraitId(_)
289-
| ModuleDefId::TypeAliasId(_)
290-
| ModuleDefId::BuiltinType(_)
291-
| ModuleDefId::ModuleId(_) => return None,
292-
};
299+
let value = to_value_ns(module_def)?;
293300
Some(ResolveValueResult::ValueNs(value))
294301
}
295302
Some(idx) => {
@@ -309,9 +316,33 @@ impl Resolver {
309316
}
310317
};
311318
}
319+
Scope::LocalItemsScope(body) => {
320+
let def = body.item_scope.get(first_name, BuiltinShadowMode::Other);
321+
if let Some(res) = to_value_ns(def) {
322+
return Some(ResolveValueResult::ValueNs(res));
323+
}
324+
}
312325
}
313326
}
314-
None
327+
return None;
328+
329+
fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
330+
let res = match per_ns.take_values()? {
331+
ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
332+
ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
333+
ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
334+
ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
335+
ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
336+
337+
ModuleDefId::AdtId(AdtId::EnumId(_))
338+
| ModuleDefId::AdtId(AdtId::UnionId(_))
339+
| ModuleDefId::TraitId(_)
340+
| ModuleDefId::TypeAliasId(_)
341+
| ModuleDefId::BuiltinType(_)
342+
| ModuleDefId::ModuleId(_) => return None,
343+
};
344+
Some(res)
345+
}
315346
}
316347

317348
pub fn resolve_path_in_value_ns_fully(
@@ -429,6 +460,11 @@ impl Scope {
429460
});
430461
}
431462
}
463+
Scope::LocalItemsScope(body) => {
464+
body.item_scope.entries_without_primitives().for_each(|(name, def)| {
465+
f(name.clone(), ScopeDef::PerNs(def));
466+
})
467+
}
432468
Scope::GenericParams { params, def } => {
433469
for (local_id, param) in params.types.iter() {
434470
f(
@@ -464,6 +500,7 @@ pub fn resolver_for_scope(
464500
scope_id: Option<ScopeId>,
465501
) -> Resolver {
466502
let mut r = owner.resolver(db);
503+
r = r.push_local_items_scope(db.body(owner));
467504
let scopes = db.expr_scopes(owner);
468505
let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
469506
for scope in scope_chain.into_iter().rev() {
@@ -499,6 +536,10 @@ impl Resolver {
499536
self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
500537
}
501538

539+
fn push_local_items_scope(self, body: Arc<Body>) -> Resolver {
540+
self.push_scope(Scope::LocalItemsScope(body))
541+
}
542+
502543
fn push_expr_scope(
503544
self,
504545
owner: DefWithBodyId,

crates/ra_hir_ty/src/tests/simple.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,8 +1512,8 @@ fn test() {
15121512
[49; 50) '0': u32
15131513
[80; 83) '101': u32
15141514
[95; 213) '{ ...NST; }': ()
1515-
[138; 139) 'x': {unknown}
1516-
[142; 153) 'LOCAL_CONST': {unknown}
1515+
[138; 139) 'x': u32
1516+
[142; 153) 'LOCAL_CONST': u32
15171517
[163; 164) 'z': u32
15181518
[167; 179) 'GLOBAL_CONST': u32
15191519
[189; 191) 'id': u32
@@ -1541,10 +1541,10 @@ fn test() {
15411541
[29; 32) '101': u32
15421542
[70; 73) '101': u32
15431543
[85; 280) '{ ...MUT; }': ()
1544-
[173; 174) 'x': {unknown}
1545-
[177; 189) 'LOCAL_STATIC': {unknown}
1546-
[199; 200) 'y': {unknown}
1547-
[203; 219) 'LOCAL_...IC_MUT': {unknown}
1544+
[173; 174) 'x': u32
1545+
[177; 189) 'LOCAL_STATIC': u32
1546+
[199; 200) 'y': u32
1547+
[203; 219) 'LOCAL_...IC_MUT': u32
15481548
[229; 230) 'z': u32
15491549
[233; 246) 'GLOBAL_STATIC': u32
15501550
[256; 257) 'w': u32

crates/ra_ide/src/completion/complete_scope.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,4 +873,41 @@ mod tests {
873873
"###
874874
);
875875
}
876+
877+
#[test]
878+
fn completes_local_item() {
879+
assert_debug_snapshot!(
880+
do_reference_completion(
881+
"
882+
//- /main.rs
883+
fn main() {
884+
return f<|>;
885+
fn frobnicate() {}
886+
}
887+
"
888+
),
889+
@r###"
890+
[
891+
CompletionItem {
892+
label: "frobnicate()",
893+
source_range: [23; 24),
894+
delete: [23; 24),
895+
insert: "frobnicate()$0",
896+
kind: Function,
897+
lookup: "frobnicate",
898+
detail: "fn frobnicate()",
899+
},
900+
CompletionItem {
901+
label: "main()",
902+
source_range: [23; 24),
903+
delete: [23; 24),
904+
insert: "main()$0",
905+
kind: Function,
906+
lookup: "main",
907+
detail: "fn main()",
908+
},
909+
]
910+
"###
911+
)
912+
}
876913
}

0 commit comments

Comments
 (0)