aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/nameres')
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs84
-rw-r--r--crates/ra_hir_def/src/nameres/tests/globs.rs44
2 files changed, 93 insertions, 35 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 665dd106c..93f58e2c7 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -305,6 +305,7 @@ impl DefCollector<'_> {
305 self.def_map.root, 305 self.def_map.root,
306 &[(name, PerNs::macros(macro_, Visibility::Public))], 306 &[(name, PerNs::macros(macro_, Visibility::Public))],
307 Visibility::Public, 307 Visibility::Public,
308 false,
308 ); 309 );
309 } 310 }
310 } 311 }
@@ -330,6 +331,7 @@ impl DefCollector<'_> {
330 self.def_map.root, 331 self.def_map.root,
331 &[(name, PerNs::macros(macro_, Visibility::Public))], 332 &[(name, PerNs::macros(macro_, Visibility::Public))],
332 Visibility::Public, 333 Visibility::Public,
334 false,
333 ); 335 );
334 } 336 }
335 337
@@ -380,35 +382,25 @@ impl DefCollector<'_> {
380 382
381 while self.unresolved_imports.len() < n_previous_unresolved { 383 while self.unresolved_imports.len() < n_previous_unresolved {
382 n_previous_unresolved = self.unresolved_imports.len(); 384 n_previous_unresolved = self.unresolved_imports.len();
383 let mut imports = std::mem::replace(&mut self.unresolved_imports, Vec::new()); 385 let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
384 for mut directive in &mut imports { 386 for mut directive in imports {
385 directive.status = self.resolve_import(directive.module_id, &directive.import); 387 directive.status = self.resolve_import(directive.module_id, &directive.import);
386 } 388 match directive.status {
387 389 PartialResolvedImport::Indeterminate(_) => {
388 let (glob_imports, non_glob_imports): (Vec<_>, Vec<_>) = 390 self.record_resolved_import(&directive);
389 imports.into_iter().partition(|directive| directive.import.is_glob); 391 // FIXME: For avoid performance regression,
390 let mut record = |imports: Vec<ImportDirective>| { 392 // we consider an imported resolved if it is indeterminate (i.e not all namespace resolved)
391 for directive in imports { 393 self.resolved_imports.push(directive)
392 match directive.status { 394 }
393 PartialResolvedImport::Indeterminate(_) => { 395 PartialResolvedImport::Resolved(_) => {
394 self.record_resolved_import(&directive); 396 self.record_resolved_import(&directive);
395 // FIXME: For avoid performance regression, 397 self.resolved_imports.push(directive)
396 // we consider an imported resolved if it is indeterminate (i.e not all namespace resolved) 398 }
397 self.resolved_imports.push(directive) 399 PartialResolvedImport::Unresolved => {
398 } 400 self.unresolved_imports.push(directive);
399 PartialResolvedImport::Resolved(_) => {
400 self.record_resolved_import(&directive);
401 self.resolved_imports.push(directive)
402 }
403 PartialResolvedImport::Unresolved => {
404 self.unresolved_imports.push(directive);
405 }
406 } 401 }
407 } 402 }
408 }; 403 }
409
410 record(glob_imports);
411 record(non_glob_imports);
412 } 404 }
413 } 405 }
414 406
@@ -486,7 +478,7 @@ impl DefCollector<'_> {
486 .filter(|(_, res)| !res.is_none()) 478 .filter(|(_, res)| !res.is_none())
487 .collect::<Vec<_>>(); 479 .collect::<Vec<_>>();
488 480
489 self.update(module_id, &items, vis); 481 self.update(module_id, &items, vis, true);
490 } else { 482 } else {
491 // glob import from same crate => we do an initial 483 // glob import from same crate => we do an initial
492 // import, and then need to propagate any further 484 // import, and then need to propagate any further
@@ -508,7 +500,7 @@ impl DefCollector<'_> {
508 .filter(|(_, res)| !res.is_none()) 500 .filter(|(_, res)| !res.is_none())
509 .collect::<Vec<_>>(); 501 .collect::<Vec<_>>();
510 502
511 self.update(module_id, &items, vis); 503 self.update(module_id, &items, vis, true);
512 // record the glob import in case we add further items 504 // record the glob import in case we add further items
513 let glob = self.glob_imports.entry(m.local_id).or_default(); 505 let glob = self.glob_imports.entry(m.local_id).or_default();
514 if !glob.iter().any(|(mid, _)| *mid == module_id) { 506 if !glob.iter().any(|(mid, _)| *mid == module_id) {
@@ -538,7 +530,7 @@ impl DefCollector<'_> {
538 (name, res) 530 (name, res)
539 }) 531 })
540 .collect::<Vec<_>>(); 532 .collect::<Vec<_>>();
541 self.update(module_id, &resolutions, vis); 533 self.update(module_id, &resolutions, vis, true);
542 } 534 }
543 Some(d) => { 535 Some(d) => {
544 log::debug!("glob import {:?} from non-module/enum {:?}", import, d); 536 log::debug!("glob import {:?} from non-module/enum {:?}", import, d);
@@ -564,15 +556,21 @@ impl DefCollector<'_> {
564 } 556 }
565 } 557 }
566 558
567 self.update(module_id, &[(name, def)], vis); 559 self.update(module_id, &[(name, def)], vis, false);
568 } 560 }
569 None => mark::hit!(bogus_paths), 561 None => mark::hit!(bogus_paths),
570 } 562 }
571 } 563 }
572 } 564 }
573 565
574 fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, PerNs)], vis: Visibility) { 566 fn update(
575 self.update_recursive(module_id, resolutions, vis, 0) 567 &mut self,
568 module_id: LocalModuleId,
569 resolutions: &[(Name, PerNs)],
570 vis: Visibility,
571 is_from_glob: bool,
572 ) {
573 self.update_recursive(module_id, resolutions, vis, is_from_glob, 0)
576 } 574 }
577 575
578 fn update_recursive( 576 fn update_recursive(
@@ -582,6 +580,9 @@ impl DefCollector<'_> {
582 // All resolutions are imported with this visibility; the visibilies in 580 // All resolutions are imported with this visibility; the visibilies in
583 // the `PerNs` values are ignored and overwritten 581 // the `PerNs` values are ignored and overwritten
584 vis: Visibility, 582 vis: Visibility,
583 // All resolutions are imported with this glob status; the glob status
584 // in the `PerNs` values are ignored and overwritten
585 is_from_glob: bool,
585 depth: usize, 586 depth: usize,
586 ) { 587 ) {
587 if depth > 100 { 588 if depth > 100 {
@@ -591,7 +592,8 @@ impl DefCollector<'_> {
591 let scope = &mut self.def_map.modules[module_id].scope; 592 let scope = &mut self.def_map.modules[module_id].scope;
592 let mut changed = false; 593 let mut changed = false;
593 for (name, res) in resolutions { 594 for (name, res) in resolutions {
594 changed |= scope.push_res(name.clone(), res.with_visibility(vis)); 595 changed |=
596 scope.push_res(name.clone(), res.with_visibility(vis).from_glob(is_from_glob));
595 } 597 }
596 598
597 if !changed { 599 if !changed {
@@ -610,7 +612,13 @@ impl DefCollector<'_> {
610 if !vis.is_visible_from_def_map(&self.def_map, glob_importing_module) { 612 if !vis.is_visible_from_def_map(&self.def_map, glob_importing_module) {
611 continue; 613 continue;
612 } 614 }
613 self.update_recursive(glob_importing_module, resolutions, glob_import_vis, depth + 1); 615 self.update_recursive(
616 glob_importing_module,
617 resolutions,
618 glob_import_vis,
619 true,
620 depth + 1,
621 );
614 } 622 }
615 } 623 }
616 624
@@ -932,6 +940,7 @@ impl ModCollector<'_, '_> {
932 self.module_id, 940 self.module_id,
933 &[(name.clone(), PerNs::from_def(id, vis, has_constructor))], 941 &[(name.clone(), PerNs::from_def(id, vis, has_constructor))],
934 vis, 942 vis,
943 false,
935 ) 944 )
936 } 945 }
937 } 946 }
@@ -1034,7 +1043,12 @@ impl ModCollector<'_, '_> {
1034 let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; 1043 let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res };
1035 let def: ModuleDefId = module.into(); 1044 let def: ModuleDefId = module.into();
1036 self.def_collector.def_map.modules[self.module_id].scope.define_def(def); 1045 self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
1037 self.def_collector.update(self.module_id, &[(name, PerNs::from_def(def, vis, false))], vis); 1046 self.def_collector.update(
1047 self.module_id,
1048 &[(name, PerNs::from_def(def, vis, false))],
1049 vis,
1050 false,
1051 );
1038 res 1052 res
1039 } 1053 }
1040 1054
diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs
index d5a02137c..7f3d7509c 100644
--- a/crates/ra_hir_def/src/nameres/tests/globs.rs
+++ b/crates/ra_hir_def/src/nameres/tests/globs.rs
@@ -322,3 +322,47 @@ fn glob_shadowed_def_reversed() {
322 "### 322 "###
323 ); 323 );
324} 324}
325
326#[test]
327fn glob_shadowed_def_dependencies() {
328 let map = def_map(
329 r###"
330 //- /lib.rs
331 mod a { pub mod foo { pub struct X; } }
332 mod b { pub use super::a::foo; }
333 mod c { pub mod foo { pub struct Y; } }
334 mod d {
335 use super::c::foo;
336 use super::b::*;
337 use foo::Y;
338 }
339 "###,
340 );
341 assert_snapshot!(map, @r###"
342 ⋮crate
343 ⋮a: t
344 ⋮b: t
345 ⋮c: t
346 ⋮d: t
347
348 ⋮crate::d
349 ⋮Y: t v
350 ⋮foo: t
351
352 ⋮crate::c
353 ⋮foo: t
354
355 ⋮crate::c::foo
356 ⋮Y: t v
357
358 ⋮crate::b
359 ⋮foo: t
360
361 ⋮crate::a
362 ⋮foo: t
363
364 ⋮crate::a::foo
365 ⋮X: t v
366 "###
367 );
368}