diff options
Diffstat (limited to 'crates/ra_hir_def/src/nameres')
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 84 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/globs.rs | 44 |
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] | ||
327 | fn 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 | } | ||