1111use self :: ImportDirectiveSubclass :: * ;
1212
1313use DefModifiers ;
14+ use DefOrModule ;
1415use Module ;
1516use Namespace :: { self , TypeNS , ValueNS } ;
1617use NameBinding ;
@@ -50,7 +51,7 @@ pub enum Shadowable {
5051}
5152
5253/// One import directive.
53- #[ derive( Debug ) ]
54+ #[ derive( Debug , Clone ) ]
5455pub struct ImportDirective {
5556 pub module_path : Vec < Name > ,
5657 pub subclass : ImportDirectiveSubclass ,
@@ -140,9 +141,11 @@ impl<'a> ImportResolution<'a> {
140141 }
141142}
142143
143- struct ImportResolvingError {
144+ struct ImportResolvingError < ' a > {
145+ /// Module where the error happened
146+ source_module : Module < ' a > ,
147+ import_directive : ImportDirective ,
144148 span : Span ,
145- path : String ,
146149 help : String ,
147150}
148151
@@ -181,9 +184,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
181184 // resolving failed
182185 if errors. len ( ) > 0 {
183186 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)
187188 }
188189 } else {
189190 // 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> {
200201 }
201202 }
202203
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+
203248 /// Attempts to resolve imports for the given module and all of its
204249 /// submodules.
205250 fn resolve_imports_for_module_subtree ( & mut self ,
206251 module_ : Module < ' b > )
207- -> Vec < ImportResolvingError > {
252+ -> Vec < ImportResolvingError < ' b > > {
208253 let mut errors = Vec :: new ( ) ;
209254 debug ! ( "(resolving imports for module subtree) resolving {}" ,
210255 module_to_string( & * module_) ) ;
@@ -232,7 +277,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
232277 }
233278
234279 /// 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 > > {
236281 let mut errors = Vec :: new ( ) ;
237282
238283 if module. all_imports_resolved ( ) {
@@ -254,9 +299,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
254299 None => ( import_directive. span , String :: new ( ) ) ,
255300 } ;
256301 errors. push ( ImportResolvingError {
302+ source_module : module,
303+ import_directive : import_directive. clone ( ) ,
257304 span : span,
258- path : import_path_to_string ( & import_directive. module_path ,
259- import_directive. subclass ) ,
260305 help : help,
261306 } ) ;
262307 }
@@ -784,7 +829,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
784829 namespace_name,
785830 name) ;
786831 span_err ! ( self . resolver. session, import_directive. span, E0251 , "{}" , msg) ;
787- } else {
832+ } else {
788833 let target = Target :: new ( containing_module,
789834 name_binding. clone ( ) ,
790835 import_directive. shadowable ) ;
0 commit comments