@@ -32,7 +32,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
3232use rustc_span:: edition:: Edition ;
3333use rustc_span:: hygiene:: MacroKind ;
3434use rustc_span:: source_map:: { SourceMap , Spanned } ;
35- use rustc_span:: { BytePos , Ident , Span , Symbol , SyntaxContext , kw, sym} ;
35+ use rustc_span:: { BytePos , Ident , RemapPathScopeComponents , Span , Symbol , SyntaxContext , kw, sym} ;
3636use thin_vec:: { ThinVec , thin_vec} ;
3737use tracing:: { debug, instrument} ;
3838
@@ -899,26 +899,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
899899 ResolutionError :: SelfImportOnlyInImportListWithNonEmptyPrefix => {
900900 self . dcx ( ) . create_err ( errs:: SelfImportOnlyInImportListWithNonEmptyPrefix { span } )
901901 }
902- ResolutionError :: FailedToResolve { segment, label, suggestion, module } => {
903- let mut err =
904- struct_span_code_err ! ( self . dcx( ) , span, E0433 , "failed to resolve: {label}" ) ;
902+ ResolutionError :: FailedToResolve { segment, label, suggestion, module, message } => {
903+ let mut err = struct_span_code_err ! ( self . dcx( ) , span, E0433 , "{message}" ) ;
905904 err. span_label ( span, label) ;
906905
907906 if let Some ( ( suggestions, msg, applicability) ) = suggestion {
908907 if suggestions. is_empty ( ) {
909908 err. help ( msg) ;
910909 return err;
911910 }
912- err. multipart_suggestion ( msg, suggestions, applicability) ;
911+ err. multipart_suggestion_verbose ( msg, suggestions, applicability) ;
913912 }
914913
915- if let Some ( segment) = segment {
916- let module = match module {
917- Some ( ModuleOrUniformRoot :: Module ( m) ) if let Some ( id) = m. opt_def_id ( ) => id,
918- _ => CRATE_DEF_ID . to_def_id ( ) ,
919- } ;
920- self . find_cfg_stripped ( & mut err, & segment, module) ;
921- }
914+ let module = match module {
915+ Some ( ModuleOrUniformRoot :: Module ( m) ) if let Some ( id) = m. opt_def_id ( ) => id,
916+ _ => CRATE_DEF_ID . to_def_id ( ) ,
917+ } ;
918+ self . find_cfg_stripped ( & mut err, & segment, module) ;
922919
923920 err
924921 }
@@ -1108,10 +1105,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11081105 VisResolutionError :: AncestorOnly ( span) => {
11091106 self . dcx ( ) . create_err ( errs:: AncestorOnly ( span) )
11101107 }
1111- VisResolutionError :: FailedToResolve ( span, label, suggestion) => self . into_struct_error (
1112- span,
1113- ResolutionError :: FailedToResolve { segment : None , label, suggestion, module : None } ,
1114- ) ,
1108+ VisResolutionError :: FailedToResolve ( span, segment, label, suggestion, message) => self
1109+ . into_struct_error (
1110+ span,
1111+ ResolutionError :: FailedToResolve {
1112+ segment,
1113+ label,
1114+ suggestion,
1115+ module : None ,
1116+ message,
1117+ } ,
1118+ ) ,
11151119 VisResolutionError :: ExpectedFound ( span, path_str, res) => {
11161120 self . dcx ( ) . create_err ( errs:: ExpectedModuleFound { span, res, path_str } )
11171121 }
@@ -2438,13 +2442,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24382442 failed_segment_idx : usize ,
24392443 ident : Ident ,
24402444 diag_metadata : Option < & DiagMetadata < ' _ > > ,
2441- ) -> ( String , Option < Suggestion > ) {
2445+ ) -> ( String , String , Option < Suggestion > ) {
24422446 let is_last = failed_segment_idx == path. len ( ) - 1 ;
24432447 let ns = if is_last { opt_ns. unwrap_or ( TypeNS ) } else { TypeNS } ;
24442448 let module_res = match module {
24452449 Some ( ModuleOrUniformRoot :: Module ( module) ) => module. res ( ) ,
24462450 _ => None ,
24472451 } ;
2452+ let scope = match & path[ ..failed_segment_idx] {
2453+ [ .., prev] => {
2454+ if prev. ident . name == kw:: PathRoot {
2455+ format ! ( "the crate root" )
2456+ } else {
2457+ format ! ( "`{}`" , prev. ident)
2458+ }
2459+ }
2460+ _ => format ! ( "this scope" ) ,
2461+ } ;
2462+ let message = format ! ( "cannot find `{ident}` in {scope}" ) ;
2463+
24482464 if module_res == self . graph_root . res ( ) {
24492465 let is_mod = |res| matches ! ( res, Res :: Def ( DefKind :: Mod , _) ) ;
24502466 let mut candidates = self . lookup_import_candidates ( ident, TypeNS , parent_scope, is_mod) ;
@@ -2462,6 +2478,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24622478 Path { segments, span : Span :: default ( ) , tokens : None }
24632479 } ;
24642480 (
2481+ message,
24652482 String :: from ( "unresolved import" ) ,
24662483 Some ( (
24672484 vec ! [ ( ident. span, pprust:: path_to_string( & path) ) ] ,
@@ -2471,6 +2488,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24712488 )
24722489 } else if ident. name == sym:: core {
24732490 (
2491+ message,
24742492 format ! ( "you might be missing crate `{ident}`" ) ,
24752493 Some ( (
24762494 vec ! [ ( ident. span, "std" . to_string( ) ) ] ,
@@ -2479,9 +2497,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24792497 ) ) ,
24802498 )
24812499 } else if ident. name == kw:: Underscore {
2482- ( format ! ( "`_` is not a valid crate or module name" ) , None )
2500+ (
2501+ "invalid crate or module name `_`" . to_string ( ) ,
2502+ "`_` is not a valid crate or module name" . to_string ( ) ,
2503+ None ,
2504+ )
24832505 } else if self . tcx . sess . is_rust_2015 ( ) {
24842506 (
2507+ format ! ( "cannot find module or crate `{ident}` in {scope}" ) ,
24852508 format ! ( "use of unresolved module or unlinked crate `{ident}`" ) ,
24862509 Some ( (
24872510 vec ! [ (
@@ -2490,8 +2513,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24902513 ) ] ,
24912514 if was_invoked_from_cargo ( ) {
24922515 format ! (
2493- "if you wanted to use a crate named `{ident}`, use `cargo add {ident}` \
2494- to add it to your `Cargo.toml` and import it in your code",
2516+ "if you wanted to use a crate named `{ident}`, use `cargo add \
2517+ {ident}` to add it to your `Cargo.toml` and import it in your \
2518+ code",
24952519 )
24962520 } else {
24972521 format ! (
@@ -2503,7 +2527,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
25032527 ) ) ,
25042528 )
25052529 } else {
2506- ( format ! ( "could not find `{ident}` in the crate root" ) , None )
2530+ ( message , format ! ( "could not find `{ident}` in the crate root" ) , None )
25072531 }
25082532 } else if failed_segment_idx > 0 {
25092533 let parent = path[ failed_segment_idx - 1 ] . ident . name ;
@@ -2569,15 +2593,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
25692593 ) ;
25702594 } ;
25712595 }
2572- ( msg, None )
2596+ ( message , msg, None )
25732597 } else if ident. name == kw:: SelfUpper {
25742598 // As mentioned above, `opt_ns` being `None` indicates a module path in import.
25752599 // We can use this to improve a confusing error for, e.g. `use Self::Variant` in an
25762600 // impl
25772601 if opt_ns. is_none ( ) {
2578- ( "`Self` cannot be used in imports" . to_string ( ) , None )
2602+ ( message , "`Self` cannot be used in imports" . to_string ( ) , None )
25792603 } else {
25802604 (
2605+ message,
25812606 "`Self` is only available in impls, traits, and type definitions" . to_string ( ) ,
25822607 None ,
25832608 )
@@ -2608,31 +2633,40 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
26082633 // }
26092634 // ```
26102635 Some ( LateDecl :: RibDef ( Res :: Local ( id) ) ) => {
2611- Some ( * self . pat_span_map . get ( & id) . unwrap ( ) )
2636+ Some ( ( * self . pat_span_map . get ( & id) . unwrap ( ) , "a" , "local binding" ) )
26122637 }
26132638 // Name matches item from a local name binding
26142639 // created by `use` declaration. For example:
26152640 // ```
2616- // pub Foo: &str = "";
2641+ // pub const Foo: &str = "";
26172642 //
26182643 // mod submod {
26192644 // use super::Foo;
26202645 // println!("{}", Foo::Bar); // Name refers to local
26212646 // // binding `Foo`.
26222647 // }
26232648 // ```
2624- Some ( LateDecl :: Decl ( name_binding) ) => Some ( name_binding. span ) ,
2649+ Some ( LateDecl :: Decl ( name_binding) ) => Some ( (
2650+ name_binding. span ,
2651+ name_binding. res ( ) . article ( ) ,
2652+ name_binding. res ( ) . descr ( ) ,
2653+ ) ) ,
26252654 _ => None ,
26262655 } ;
2627- let suggestion = match_span. map ( |span| {
2628- (
2629- vec ! [ ( span, String :: from( "" ) ) ] ,
2630- format ! ( "`{ident}` is defined here, but is not a type" ) ,
2631- Applicability :: MaybeIncorrect ,
2632- )
2633- } ) ;
26342656
2635- ( format ! ( "use of undeclared type `{ident}`" ) , suggestion)
2657+ let message = format ! ( "cannot find type `{ident}` in {scope}" ) ;
2658+ let label = if let Some ( ( span, article, descr) ) = match_span {
2659+ format ! (
2660+ "`{ident}` is declared as {article} {descr} at `{}`, not a type" ,
2661+ self . tcx
2662+ . sess
2663+ . source_map( )
2664+ . span_to_short_string( span, RemapPathScopeComponents :: DIAGNOSTICS )
2665+ )
2666+ } else {
2667+ format ! ( "use of undeclared type `{ident}`" )
2668+ } ;
2669+ ( message, label, None )
26362670 } else {
26372671 let mut suggestion = None ;
26382672 if ident. name == sym:: alloc {
@@ -2663,7 +2697,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
26632697 ignore_import,
26642698 ) {
26652699 let descr = binding. res ( ) . descr ( ) ;
2666- ( format ! ( "{descr} `{ident}` is not a crate or module" ) , suggestion)
2700+ let message = format ! ( "cannot find module or crate `{ident}` in {scope}" ) ;
2701+ ( message, format ! ( "{descr} `{ident}` is not a crate or module" ) , suggestion)
26672702 } else {
26682703 let suggestion = if suggestion. is_some ( ) {
26692704 suggestion
@@ -2685,7 +2720,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
26852720 Applicability :: MaybeIncorrect ,
26862721 ) )
26872722 } ;
2688- ( format ! ( "use of unresolved module or unlinked crate `{ident}`" ) , suggestion)
2723+ let message = format ! ( "cannot find module or crate `{ident}` in {scope}" ) ;
2724+ (
2725+ message,
2726+ format ! ( "use of unresolved module or unlinked crate `{ident}`" ) ,
2727+ suggestion,
2728+ )
26892729 }
26902730 }
26912731 }
0 commit comments