aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-05-19 17:56:00 +0100
committerJonas Schievink <[email protected]>2021-05-19 17:56:00 +0100
commitaebb60de5c92c7a7be1c152c7294861a51212dcf (patch)
treef02a52eeaf7cccd186fe23b039eeffcf7ee348d4
parent3e186d47786899f7b4052f9d2cf060dbfe19e6f9 (diff)
Restructure nameres loop to be a bit clearer
-rw-r--r--crates/hir_def/src/nameres/collector.rs79
1 files changed, 41 insertions, 38 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index c314b5309..24ba7dbe9 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -296,19 +296,26 @@ impl DefCollector<'_> {
296 fn collect(&mut self) { 296 fn collect(&mut self) {
297 // main name resolution fixed-point loop. 297 // main name resolution fixed-point loop.
298 let mut i = 0; 298 let mut i = 0;
299 loop { 299 'outer: loop {
300 self.db.check_canceled(); 300 loop {
301 self.resolve_imports(); 301 self.db.check_canceled();
302 302 loop {
303 match self.resolve_macros() { 303 if self.resolve_imports() == ReachedFixedPoint::Yes {
304 ReachedFixedPoint::Yes => match self.reseed_with_unresolved_attributes() { 304 break;
305 ReachedFixedPoint::Yes => break, 305 }
306 ReachedFixedPoint::No => i += 1, 306 }
307 }, 307 if self.resolve_macros() == ReachedFixedPoint::Yes {
308 ReachedFixedPoint::No => i += 1, 308 break;
309 }
310
311 i += 1;
312 if i == FIXED_POINT_LIMIT {
313 log::error!("name resolution is stuck");
314 break 'outer;
315 }
309 } 316 }
310 if i == FIXED_POINT_LIMIT { 317
311 log::error!("name resolution is stuck"); 318 if self.reseed_with_unresolved_attributes() == ReachedFixedPoint::Yes {
312 break; 319 break;
313 } 320 }
314 } 321 }
@@ -550,35 +557,31 @@ impl DefCollector<'_> {
550 } 557 }
551 } 558 }
552 559
553 /// Import resolution 560 /// Tries to resolve every currently unresolved import.
554 /// 561 fn resolve_imports(&mut self) -> ReachedFixedPoint {
555 /// This is a fix point algorithm. We resolve imports until no forward 562 let mut res = ReachedFixedPoint::Yes;
556 /// progress in resolving imports is made 563 let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
557 fn resolve_imports(&mut self) { 564 for mut directive in imports {
558 let mut n_previous_unresolved = self.unresolved_imports.len() + 1; 565 directive.status = self.resolve_import(directive.module_id, &directive.import);
559 566 match directive.status {
560 while self.unresolved_imports.len() < n_previous_unresolved { 567 PartialResolvedImport::Indeterminate(_) => {
561 n_previous_unresolved = self.unresolved_imports.len(); 568 self.record_resolved_import(&directive);
562 let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new()); 569 // FIXME: For avoid performance regression,
563 for mut directive in imports { 570 // we consider an imported resolved if it is indeterminate (i.e not all namespace resolved)
564 directive.status = self.resolve_import(directive.module_id, &directive.import); 571 self.resolved_imports.push(directive);
565 match directive.status { 572 res = ReachedFixedPoint::No;
566 PartialResolvedImport::Indeterminate(_) => { 573 }
567 self.record_resolved_import(&directive); 574 PartialResolvedImport::Resolved(_) => {
568 // FIXME: For avoid performance regression, 575 self.record_resolved_import(&directive);
569 // we consider an imported resolved if it is indeterminate (i.e not all namespace resolved) 576 self.resolved_imports.push(directive);
570 self.resolved_imports.push(directive) 577 res = ReachedFixedPoint::No;
571 } 578 }
572 PartialResolvedImport::Resolved(_) => { 579 PartialResolvedImport::Unresolved => {
573 self.record_resolved_import(&directive); 580 self.unresolved_imports.push(directive);
574 self.resolved_imports.push(directive)
575 }
576 PartialResolvedImport::Unresolved => {
577 self.unresolved_imports.push(directive);
578 }
579 } 581 }
580 } 582 }
581 } 583 }
584 res
582 } 585 }
583 586
584 fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport { 587 fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport {