@@ -4,6 +4,7 @@ use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseS
44use crate :: { errors, path_names_to_string} ;
55use crate :: { Module , ModuleKind , ModuleOrUniformRoot } ;
66use crate :: { PathResult , PathSource , Segment } ;
7+ use rustc_hir:: def:: Namespace :: { self , * } ;
78
89use rustc_ast:: visit:: { FnCtxt , FnKind , LifetimeCtxt } ;
910use rustc_ast:: {
@@ -17,7 +18,6 @@ use rustc_errors::{
1718 MultiSpan ,
1819} ;
1920use rustc_hir as hir;
20- use rustc_hir:: def:: Namespace :: { self , * } ;
2121use rustc_hir:: def:: { self , CtorKind , CtorOf , DefKind } ;
2222use rustc_hir:: def_id:: { DefId , CRATE_DEF_ID } ;
2323use rustc_hir:: PrimTy ;
@@ -221,10 +221,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
221221 let suggestion = if self . current_trait_ref . is_none ( )
222222 && let Some ( ( fn_kind, _) ) = self . diagnostic_metadata . current_function
223223 && let Some ( FnCtxt :: Assoc ( _) ) = fn_kind. ctxt ( )
224+ && let FnKind :: Fn ( _, _, sig, ..) = fn_kind
224225 && let Some ( items) = self . diagnostic_metadata . current_impl_items
225226 && let Some ( item) = items. iter ( ) . find ( |i| {
226227 if let AssocItemKind :: Fn ( ..) | AssocItemKind :: Const ( ..) = & i. kind
227228 && i. ident . name == item_str. name
229+ // don't suggest if the item is in Fn signature arguments
230+ // issue #112590
231+ && !sig. span . contains ( item_span)
228232 {
229233 debug ! ( ?item_str. name) ;
230234 return true
@@ -318,11 +322,56 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
318322 }
319323 }
320324
325+ /// Try to suggest for a module path that cannot be resolved.
326+ /// Such as `fmt::Debug` where `fmt` is not resolved without importing,
327+ /// here we search with `lookup_import_candidates` for a module named `fmt`
328+ /// with `TypeNS` as namespace.
329+ ///
330+ /// We need a separate function here because we won't suggest for a path with single segment
331+ /// and we won't change `SourcePath` api `is_expected` to match `Type` with `DefKind::Mod`
332+ pub ( crate ) fn smart_resolve_partial_mod_path_errors (
333+ & mut self ,
334+ prefix_path : & [ Segment ] ,
335+ path : & [ Segment ] ,
336+ ) -> Vec < ImportSuggestion > {
337+ let next_seg = if path. len ( ) >= prefix_path. len ( ) + 1 && prefix_path. len ( ) == 1 {
338+ path. get ( prefix_path. len ( ) )
339+ } else {
340+ None
341+ } ;
342+ if let Some ( segment) = prefix_path. last ( ) &&
343+ let Some ( next_seg) = next_seg {
344+ let candidates = self . r . lookup_import_candidates (
345+ segment. ident ,
346+ Namespace :: TypeNS ,
347+ & self . parent_scope ,
348+ & |res : Res | matches ! ( res, Res :: Def ( DefKind :: Mod , _) ) ,
349+ ) ;
350+ // double check next seg is valid
351+ candidates
352+ . into_iter ( )
353+ . filter ( |candidate| {
354+ if let Some ( def_id) = candidate. did &&
355+ let Some ( module) = self . r . get_module ( def_id) {
356+ self . r . resolutions ( module) . borrow ( ) . iter ( ) . any ( |( key, _r) | {
357+ key. ident . name == next_seg. ident . name
358+ } )
359+ } else {
360+ false
361+ }
362+ } )
363+ . collect :: < Vec < _ > > ( )
364+ } else {
365+ Vec :: new ( )
366+ }
367+ }
368+
321369 /// Handles error reporting for `smart_resolve_path_fragment` function.
322370 /// Creates base error and amends it with one short label and possibly some longer helps/notes.
323371 pub ( crate ) fn smart_resolve_report_errors (
324372 & mut self ,
325373 path : & [ Segment ] ,
374+ full_path : & [ Segment ] ,
326375 span : Span ,
327376 source : PathSource < ' _ > ,
328377 res : Option < Res > ,
@@ -364,7 +413,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
364413 }
365414
366415 let ( found, candidates) =
367- self . try_lookup_name_relaxed ( & mut err, source, path, span, res, & base_error) ;
416+ self . try_lookup_name_relaxed ( & mut err, source, path, full_path , span, res, & base_error) ;
368417 if found {
369418 return ( err, candidates) ;
370419 }
@@ -470,6 +519,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
470519 err : & mut Diagnostic ,
471520 source : PathSource < ' _ > ,
472521 path : & [ Segment ] ,
522+ full_path : & [ Segment ] ,
473523 span : Span ,
474524 res : Option < Res > ,
475525 base_error : & BaseError ,
@@ -639,6 +689,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
639689 }
640690 }
641691
692+ if candidates. is_empty ( ) {
693+ candidates = self . smart_resolve_partial_mod_path_errors ( path, full_path) ;
694+ }
695+
642696 return ( false , candidates) ;
643697 }
644698
0 commit comments