@@ -31,7 +31,7 @@ use smallvec::{smallvec, SmallVec};
3131
3232use rustc_span:: source_map:: { respan, Spanned } ;
3333use std:: collections:: { hash_map:: Entry , BTreeSet } ;
34- use std:: mem:: { replace, take} ;
34+ use std:: mem:: { replace, take, swap } ;
3535
3636mod diagnostics;
3737
@@ -3334,10 +3334,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
33343334 let ( mut err, candidates) =
33353335 this. smart_resolve_report_errors ( path, path_span, PathSource :: Type , None ) ;
33363336
3337- if candidates. is_empty ( ) {
3338- err. cancel ( ) ;
3339- return Some ( parent_err) ;
3340- }
33413337
33423338 // There are two different error messages user might receive at
33433339 // this point:
@@ -3348,37 +3344,62 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
33483344 // latter one - for paths in expression-position.
33493345 //
33503346 // Thus (since we're in expression-position at this point), not to
3351- // confuse the user, we want to keep the *message* from E0432 (so
3347+ // confuse the user, we want to keep the *message* from E0433 (so
33523348 // `parent_err`), but we want *hints* from E0412 (so `err`).
33533349 //
33543350 // And that's what happens below - we're just mixing both messages
33553351 // into a single one.
33563352 let mut parent_err = this. r . into_struct_error ( parent_err. span , parent_err. node ) ;
33573353
3354+ // overwrite all properties with the parent's error message
33583355 err. message = take ( & mut parent_err. message ) ;
33593356 err. code = take ( & mut parent_err. code ) ;
3357+ swap ( & mut err. span , & mut parent_err. span ) ;
33603358 err. children = take ( & mut parent_err. children ) ;
3359+ err. sort_span = parent_err. sort_span ;
3360+ err. is_lint = parent_err. is_lint ;
3361+
3362+ // merge the parent's suggestions with the typo suggestions
3363+ fn append_result < T , E > ( res1 : & mut Result < Vec < T > , E > , res2 : Result < Vec < T > , E > ) {
3364+ match res1 {
3365+ Ok ( vec1) => match res2 {
3366+ Ok ( mut vec2) => { vec1. append ( & mut vec2) ; } ,
3367+ Err ( e) => { * res1 = Err ( e) } ,
3368+ } ,
3369+ Err ( _) => ( ) ,
3370+ } ;
3371+ }
3372+ append_result ( & mut err. suggestions , parent_err. suggestions . clone ( ) ) ;
33613373
33623374 parent_err. cancel ( ) ;
33633375
33643376 let def_id = this. parent_scope . module . nearest_parent_mod ( ) ;
33653377
33663378 if this. should_report_errs ( ) {
3367- this. r . use_injections . push ( UseError {
3368- err,
3369- candidates,
3370- def_id,
3371- instead : false ,
3372- suggestion : None ,
3373- path : path. into ( ) ,
3374- is_call : source. is_call ( ) ,
3375- } ) ;
3379+ if candidates. is_empty ( ) {
3380+ // When there is no suggested imports, we can just emit the error
3381+ // and suggestions immediately. Note that we bypass the usually error
3382+ // reporting routine (ie via `self.r.report_error`) because we need
3383+ // to post-process the `ResolutionError` above.
3384+ err. emit ( ) ;
3385+ } else {
3386+ // If there are suggested imports, the error reporting is delayed
3387+ this. r . use_injections . push ( UseError {
3388+ err,
3389+ candidates,
3390+ def_id,
3391+ instead : false ,
3392+ suggestion : None ,
3393+ path : path. into ( ) ,
3394+ is_call : source. is_call ( ) ,
3395+ } ) ;
3396+ }
33763397 } else {
33773398 err. cancel ( ) ;
33783399 }
33793400
33803401 // We don't return `Some(parent_err)` here, because the error will
3381- // be already printed as part of the `use` injections
3402+ // be already printed either immediately or as part of the `use` injections
33823403 None
33833404 } ;
33843405
0 commit comments