@@ -95,12 +95,18 @@ impl MacroStackMonitor {
95
95
}
96
96
}
97
97
98
+ #[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
99
+ enum PartialResolvedImport {
100
+ Unresolved ,
101
+ Resolved ( PerNs ) ,
102
+ }
103
+
98
104
/// Walks the tree of module recursively
99
105
struct DefCollector < ' a , DB > {
100
106
db : & ' a DB ,
101
107
def_map : CrateDefMap ,
102
108
glob_imports : FxHashMap < LocalModuleId , Vec < ( LocalModuleId , LocalImportId ) > > ,
103
- unresolved_imports : Vec < ( LocalModuleId , LocalImportId , raw:: ImportData , ReachedFixedPoint ) > ,
109
+ unresolved_imports : Vec < ( LocalModuleId , LocalImportId , raw:: ImportData , PartialResolvedImport ) > ,
104
110
unexpanded_macros : Vec < ( LocalModuleId , AstId < ast:: MacroCall > , Path ) > ,
105
111
mod_dirs : FxHashMap < LocalModuleId , ModDir > ,
106
112
@@ -158,8 +164,8 @@ where
158
164
let unresolved_imports = std:: mem:: replace ( & mut self . unresolved_imports , Vec :: new ( ) ) ;
159
165
// show unresolved imports in completion, etc
160
166
for ( module_id, import, import_data, status) in unresolved_imports {
161
- if status == ReachedFixedPoint :: No {
162
- self . record_resolved_import ( module_id, PerNs :: none ( ) , import, & import_data)
167
+ if status == PartialResolvedImport :: Unresolved {
168
+ self . record_resolved_import ( module_id, PerNs :: none ( ) , import, & import_data, status )
163
169
}
164
170
}
165
171
}
@@ -267,13 +273,20 @@ where
267
273
let mut previous_resolved = 0 ;
268
274
269
275
imports. retain ( |( module_id, import, import_data, status) | {
270
- if * status == ReachedFixedPoint :: Yes {
276
+ if let PartialResolvedImport :: Resolved ( _ ) = status {
271
277
previous_resolved += 1 ;
272
278
}
273
279
274
- let ( def, fp) = self . resolve_import ( * module_id, import_data) ;
280
+ let ( def, fp, krate ) = self . resolve_import ( * module_id, import_data) ;
275
281
if fp == ReachedFixedPoint :: Yes {
276
- resolved. push ( ( * module_id, def, * import, import_data. clone ( ) ) )
282
+ resolved. push ( (
283
+ * module_id,
284
+ def,
285
+ * import,
286
+ import_data. clone ( ) ,
287
+ krate,
288
+ status. clone ( ) ,
289
+ ) )
277
290
}
278
291
fp == ReachedFixedPoint :: No
279
292
} ) ;
@@ -284,24 +297,39 @@ where
284
297
} else {
285
298
ReachedFixedPoint :: No
286
299
} ;
287
- for ( module_id, def, import, import_data) in resolved {
288
- self . record_resolved_import ( module_id, def, import, & import_data) ;
300
+ for ( module_id, def, import, import_data, krate, status) in resolved {
301
+ self . record_resolved_import ( module_id, def, import, & import_data, status) ;
302
+
303
+ // external crate graphs can't change in other crates.
304
+ if import_data. is_extern_crate {
305
+ continue ;
306
+ }
307
+ if let Some ( krate) = krate {
308
+ if krate != self . def_map . krate {
309
+ continue ;
310
+ }
311
+ }
289
312
290
313
// Reput resolved into unresolved_imports
291
314
// This is because other unresolved imports and macros will bring in another PerNSs,
292
315
// so we can only assume that it has been partially resolved.
293
316
// We must try to solve it again in the next round.
294
- self . unresolved_imports . push ( ( module_id, import, import_data, ReachedFixedPoint :: Yes ) ) ;
317
+ self . unresolved_imports . push ( (
318
+ module_id,
319
+ import,
320
+ import_data,
321
+ PartialResolvedImport :: Resolved ( def) ,
322
+ ) ) ;
295
323
}
296
324
297
- result
325
+ return result;
298
326
}
299
327
300
328
fn resolve_import (
301
329
& self ,
302
330
module_id : LocalModuleId ,
303
331
import : & raw:: ImportData ,
304
- ) -> ( PerNs , ReachedFixedPoint ) {
332
+ ) -> ( PerNs , ReachedFixedPoint , Option < CrateId > ) {
305
333
log:: debug!( "resolving import: {:?} ({:?})" , import, self . def_map. edition) ;
306
334
if import. is_extern_crate {
307
335
let res = self . def_map . resolve_name_in_extern_prelude (
@@ -310,7 +338,7 @@ where
310
338
. as_ident ( )
311
339
. expect ( "extern crate should have been desugared to one-element path" ) ,
312
340
) ;
313
- ( res, ReachedFixedPoint :: Yes )
341
+ ( res, ReachedFixedPoint :: Yes , None )
314
342
} else {
315
343
let res = self . def_map . resolve_path_fp_with_macro (
316
344
self . db ,
@@ -320,7 +348,7 @@ where
320
348
BuiltinShadowMode :: Module ,
321
349
) ;
322
350
323
- ( res. resolved_def , res. reached_fixedpoint )
351
+ ( res. resolved_def , res. reached_fixedpoint , res . krate )
324
352
}
325
353
}
326
354
@@ -330,7 +358,15 @@ where
330
358
def : PerNs ,
331
359
import_id : LocalImportId ,
332
360
import : & raw:: ImportData ,
361
+ status : PartialResolvedImport ,
333
362
) {
363
+ // record import if it was changed
364
+ if let PartialResolvedImport :: Resolved ( ns) = status {
365
+ if ns == def {
366
+ return ;
367
+ }
368
+ }
369
+
334
370
if import. is_glob {
335
371
log:: debug!( "glob import: {:?}" , import) ;
336
372
match def. take_types ( ) {
@@ -606,7 +642,7 @@ where
606
642
self . module_id ,
607
643
import_id,
608
644
self . raw_items [ import_id] . clone ( ) ,
609
- ReachedFixedPoint :: No ,
645
+ PartialResolvedImport :: Unresolved ,
610
646
) )
611
647
}
612
648
raw:: RawItemKind :: Def ( def) => self . define_def ( & self . raw_items [ def] ) ,
0 commit comments