diff options
author | Jonas Schievink <[email protected]> | 2021-05-19 17:56:00 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2021-05-19 17:56:00 +0100 |
commit | aebb60de5c92c7a7be1c152c7294861a51212dcf (patch) | |
tree | f02a52eeaf7cccd186fe23b039eeffcf7ee348d4 | |
parent | 3e186d47786899f7b4052f9d2cf060dbfe19e6f9 (diff) |
Restructure nameres loop to be a bit clearer
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 79 |
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 { |