@@ -884,6 +884,10 @@ pub struct Resolver<'a> {
884884 /// "self-confirming" import resolutions during import validation.
885885 unusable_binding : Option < & ' a NameBinding < ' a > > ,
886886
887+ // Spans for local variables found during resolution
888+ // Used for suggestions during error reporting
889+ local_span_map : NodeMap < Span > ,
890+
887891 /// Resolutions for nodes that have a single resolution.
888892 partial_res_map : NodeMap < PartialRes > ,
889893 /// Resolutions for import nodes, which have multiple resolutions in different namespaces.
@@ -1262,6 +1266,7 @@ impl<'a> Resolver<'a> {
12621266 last_import_segment : false ,
12631267 unusable_binding : None ,
12641268
1269+ local_span_map : Default :: default ( ) ,
12651270 partial_res_map : Default :: default ( ) ,
12661271 import_res_map : Default :: default ( ) ,
12671272 label_res_map : Default :: default ( ) ,
@@ -1879,7 +1884,6 @@ impl<'a> Resolver<'a> {
18791884 ribs,
18801885 ) ) ) ;
18811886 }
1882-
18831887 module = match ribs[ i] . kind {
18841888 ModuleRibKind ( module) => module,
18851889 MacroDefinition ( def) if def == self . macro_def ( ident. span . ctxt ( ) ) => {
@@ -1890,7 +1894,6 @@ impl<'a> Resolver<'a> {
18901894 }
18911895 _ => continue ,
18921896 } ;
1893-
18941897 match module. kind {
18951898 ModuleKind :: Block ( ..) => { } // We can see through blocks
18961899 _ => break ,
@@ -1909,17 +1912,19 @@ impl<'a> Resolver<'a> {
19091912 return Some ( LexicalScopeBinding :: Item ( binding) ) ;
19101913 }
19111914 }
1915+ let returned_item = self
1916+ . early_resolve_ident_in_lexical_scope (
1917+ orig_ident,
1918+ ScopeSet :: Late ( ns, module, record_used_id) ,
1919+ parent_scope,
1920+ record_used,
1921+ record_used,
1922+ path_span,
1923+ )
1924+ . ok ( )
1925+ . map ( LexicalScopeBinding :: Item ) ;
19121926
1913- self . early_resolve_ident_in_lexical_scope (
1914- orig_ident,
1915- ScopeSet :: Late ( ns, module, record_used_id) ,
1916- parent_scope,
1917- record_used,
1918- record_used,
1919- path_span,
1920- )
1921- . ok ( )
1922- . map ( LexicalScopeBinding :: Item )
1927+ returned_item
19231928 }
19241929
19251930 fn hygienic_lexical_parent (
@@ -2386,7 +2391,40 @@ impl<'a> Resolver<'a> {
23862391 . next ( )
23872392 . map_or ( false , |c| c. is_ascii_uppercase ( ) )
23882393 {
2389- ( format ! ( "use of undeclared type `{}`" , ident) , None )
2394+ // Add check case for similarly named item in alternative namespace
2395+ let mut suggestion = None ;
2396+
2397+ if ribs. is_some ( ) {
2398+ if let Some ( res) = self . resolve_ident_in_lexical_scope (
2399+ ident,
2400+ ValueNS ,
2401+ parent_scope,
2402+ None ,
2403+ path_span,
2404+ & ribs. unwrap ( ) [ ValueNS ] ,
2405+ ) {
2406+ let mut match_span: Option < Span > = None ;
2407+ match res {
2408+ LexicalScopeBinding :: Res ( Res :: Local ( id) ) => {
2409+ match_span =
2410+ Some ( * self . local_span_map . get ( & id) . unwrap ( ) ) ;
2411+ }
2412+ LexicalScopeBinding :: Item ( name_binding) => {
2413+ match_span = Some ( name_binding. span ) ;
2414+ }
2415+ _ => ( ) ,
2416+ } ;
2417+ if let Some ( span) = match_span {
2418+ suggestion = Some ( (
2419+ vec ! [ ( span, String :: from( "" ) ) ] ,
2420+ format ! ( "{} is defined here, but is not a type" , ident) ,
2421+ Applicability :: MaybeIncorrect ,
2422+ ) ) ;
2423+ }
2424+ }
2425+ }
2426+
2427+ ( format ! ( "use of undeclared type `{}`" , ident) , suggestion)
23902428 } else {
23912429 ( format ! ( "use of undeclared crate or module `{}`" , ident) , None )
23922430 }
@@ -2797,6 +2835,11 @@ impl<'a> Resolver<'a> {
27972835 }
27982836 }
27992837
2838+ fn record_local_span ( & mut self , node : NodeId , span : Span ) {
2839+ debug ! ( "(recording local) recording {:?} for {:?}" , node, span) ;
2840+ self . local_span_map . insert ( node, span) ;
2841+ }
2842+
28002843 fn is_accessible_from ( & self , vis : ty:: Visibility , module : Module < ' a > ) -> bool {
28012844 vis. is_accessible_from ( module. nearest_parent_mod , self )
28022845 }
0 commit comments