|
3 | 3 | //! `DefCollector::collect` contains the fixed-point iteration loop which
|
4 | 4 | //! resolves imports and expands macros.
|
5 | 5 |
|
6 |
| -use std::{iter, mem}; |
| 6 | +use std::{cmp::Ordering, iter, mem}; |
7 | 7 |
|
8 | 8 | use base_db::{CrateId, Dependency, Edition, FileId};
|
9 | 9 | use cfg::{CfgExpr, CfgOptions};
|
@@ -1928,9 +1928,13 @@ impl ModCollector<'_, '_> {
|
1928 | 1928 | let modules = &mut def_map.modules;
|
1929 | 1929 | let res = modules.alloc(ModuleData::new(origin, vis));
|
1930 | 1930 | modules[res].parent = Some(self.module_id);
|
1931 |
| - for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() { |
1932 |
| - for &mac in &mac { |
1933 |
| - modules[res].scope.define_legacy_macro(name.clone(), mac); |
| 1931 | + |
| 1932 | + if let Some((target, source)) = Self::borrow_modules(modules.as_mut(), res, self.module_id) |
| 1933 | + { |
| 1934 | + for (name, macs) in source.scope.legacy_macros() { |
| 1935 | + for &mac in macs { |
| 1936 | + target.scope.define_legacy_macro(name.clone(), mac); |
| 1937 | + } |
1934 | 1938 | }
|
1935 | 1939 | }
|
1936 | 1940 | modules[self.module_id].children.insert(name.clone(), res);
|
@@ -2226,14 +2230,40 @@ impl ModCollector<'_, '_> {
|
2226 | 2230 | }
|
2227 | 2231 |
|
2228 | 2232 | fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
|
2229 |
| - let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros(); |
2230 |
| - for (name, macs) in macros { |
| 2233 | + let Some((source, target)) = Self::borrow_modules(self.def_collector.def_map.modules.as_mut(), module_id, self.module_id) else { |
| 2234 | + return |
| 2235 | + }; |
| 2236 | + |
| 2237 | + for (name, macs) in source.scope.legacy_macros() { |
2231 | 2238 | macs.last().map(|&mac| {
|
2232 |
| - self.def_collector.define_legacy_macro(self.module_id, name.clone(), mac) |
| 2239 | + target.scope.define_legacy_macro(name.clone(), mac); |
2233 | 2240 | });
|
2234 | 2241 | }
|
2235 | 2242 | }
|
2236 | 2243 |
|
| 2244 | + /// Mutably borrow two modules at once, retu |
| 2245 | + fn borrow_modules( |
| 2246 | + modules: &mut [ModuleData], |
| 2247 | + a: LocalModuleId, |
| 2248 | + b: LocalModuleId, |
| 2249 | + ) -> Option<(&mut ModuleData, &mut ModuleData)> { |
| 2250 | + let a = a.into_raw().into_u32() as usize; |
| 2251 | + let b = b.into_raw().into_u32() as usize; |
| 2252 | + |
| 2253 | + let (a, b) = match a.cmp(&b) { |
| 2254 | + Ordering::Equal => return None, |
| 2255 | + Ordering::Less => { |
| 2256 | + let (prefix, b) = modules.split_at_mut(b); |
| 2257 | + (&mut prefix[a], &mut b[0]) |
| 2258 | + } |
| 2259 | + Ordering::Greater => { |
| 2260 | + let (prefix, a) = modules.split_at_mut(a); |
| 2261 | + (&mut a[0], &mut prefix[b]) |
| 2262 | + } |
| 2263 | + }; |
| 2264 | + Some((a, b)) |
| 2265 | + } |
| 2266 | + |
2237 | 2267 | fn is_cfg_enabled(&self, cfg: &CfgExpr) -> bool {
|
2238 | 2268 | self.def_collector.cfg_options.check(cfg) != Some(false)
|
2239 | 2269 | }
|
|
0 commit comments