11
11
use self :: ImportDirectiveSubclass :: * ;
12
12
13
13
use DefModifiers ;
14
+ use DefOrModule ;
14
15
use Module ;
15
16
use Namespace :: { self , TypeNS , ValueNS } ;
16
17
use NameBinding ;
@@ -50,7 +51,7 @@ pub enum Shadowable {
50
51
}
51
52
52
53
/// One import directive.
53
- #[ derive( Debug ) ]
54
+ #[ derive( Debug , Clone ) ]
54
55
pub struct ImportDirective {
55
56
pub module_path : Vec < Name > ,
56
57
pub subclass : ImportDirectiveSubclass ,
@@ -140,9 +141,11 @@ impl<'a> ImportResolution<'a> {
140
141
}
141
142
}
142
143
143
- struct ImportResolvingError {
144
+ struct ImportResolvingError < ' a > {
145
+ /// Module where the error happened
146
+ source_module : Module < ' a > ,
147
+ import_directive : ImportDirective ,
144
148
span : Span ,
145
- path : String ,
146
149
help : String ,
147
150
}
148
151
@@ -181,9 +184,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
181
184
// resolving failed
182
185
if errors. len ( ) > 0 {
183
186
for e in errors {
184
- resolve_error ( self . resolver ,
185
- e. span ,
186
- ResolutionError :: UnresolvedImport ( Some ( ( & e. path , & e. help ) ) ) ) ;
187
+ self . import_resolving_error ( e)
187
188
}
188
189
} else {
189
190
// Report unresolved imports only if no hard error was already reported
@@ -200,11 +201,55 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
200
201
}
201
202
}
202
203
204
+ /// Resolves an `ImportResolvingError` into the correct enum discriminant
205
+ /// and passes that on to `resolve_error`.
206
+ fn import_resolving_error ( & self , e : ImportResolvingError ) {
207
+ // If it's a single failed import then create a "fake" import
208
+ // resolution for it so that later resolve stages won't complain.
209
+ if let SingleImport ( target, _) = e. import_directive . subclass {
210
+ let mut import_resolutions = e. source_module . import_resolutions . borrow_mut ( ) ;
211
+
212
+ let resolution = import_resolutions. entry ( ( target, ValueNS ) ) . or_insert_with ( || {
213
+ debug ! ( "(resolving import error) adding import resolution for `{}`" ,
214
+ target) ;
215
+
216
+ ImportResolution :: new ( e. import_directive . id ,
217
+ e. import_directive . is_public )
218
+ } ) ;
219
+
220
+ if resolution. target . is_none ( ) {
221
+ debug ! ( "(resolving import error) adding fake target to import resolution of `{}`" ,
222
+ target) ;
223
+
224
+ let name_binding = NameBinding {
225
+ modifiers : DefModifiers :: IMPORTABLE ,
226
+ def_or_module : DefOrModule :: Def ( Def :: Err ) ,
227
+ span : None ,
228
+ } ;
229
+
230
+ // Create a fake target pointing to a fake name binding in our
231
+ // own module
232
+ let target = Target :: new ( e. source_module ,
233
+ name_binding,
234
+ Shadowable :: Always ) ;
235
+
236
+ resolution. target = Some ( target) ;
237
+ }
238
+ }
239
+
240
+ let path = import_path_to_string ( & e. import_directive . module_path ,
241
+ e. import_directive . subclass ) ;
242
+
243
+ resolve_error ( self . resolver ,
244
+ e. span ,
245
+ ResolutionError :: UnresolvedImport ( Some ( ( & path, & e. help ) ) ) ) ;
246
+ }
247
+
203
248
/// Attempts to resolve imports for the given module and all of its
204
249
/// submodules.
205
250
fn resolve_imports_for_module_subtree ( & mut self ,
206
251
module_ : Module < ' b > )
207
- -> Vec < ImportResolvingError > {
252
+ -> Vec < ImportResolvingError < ' b > > {
208
253
let mut errors = Vec :: new ( ) ;
209
254
debug ! ( "(resolving imports for module subtree) resolving {}" ,
210
255
module_to_string( & * module_) ) ;
@@ -232,7 +277,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
232
277
}
233
278
234
279
/// Attempts to resolve imports for the given module only.
235
- fn resolve_imports_for_module ( & mut self , module : Module < ' b > ) -> Vec < ImportResolvingError > {
280
+ fn resolve_imports_for_module ( & mut self , module : Module < ' b > ) -> Vec < ImportResolvingError < ' b > > {
236
281
let mut errors = Vec :: new ( ) ;
237
282
238
283
if module. all_imports_resolved ( ) {
@@ -254,9 +299,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
254
299
None => ( import_directive. span , String :: new ( ) ) ,
255
300
} ;
256
301
errors. push ( ImportResolvingError {
302
+ source_module : module,
303
+ import_directive : import_directive. clone ( ) ,
257
304
span : span,
258
- path : import_path_to_string ( & import_directive. module_path ,
259
- import_directive. subclass ) ,
260
305
help : help,
261
306
} ) ;
262
307
}
@@ -784,7 +829,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
784
829
namespace_name,
785
830
name) ;
786
831
span_err ! ( self . resolver. session, import_directive. span, E0251 , "{}" , msg) ;
787
- } else {
832
+ } else {
788
833
let target = Target :: new ( containing_module,
789
834
name_binding. clone ( ) ,
790
835
import_directive. shadowable ) ;
0 commit comments