@@ -28,7 +28,7 @@ use rustc_span::{BytePos, Span};
2828use tracing:: debug;
2929
3030use crate :: imports:: { Import , ImportKind , ImportResolver } ;
31- use crate :: late:: { PatternSource , Rib } ;
31+ use crate :: late:: { PatternSource , Rib , RibKind } ;
3232use crate :: path_names_to_string;
3333use crate :: { AmbiguityError , AmbiguityErrorMisc , AmbiguityKind , BindingError , Finalize } ;
3434use crate :: { HasGenericParams , MacroRulesScope , Module , ModuleKind , ModuleOrUniformRoot } ;
@@ -1825,6 +1825,75 @@ impl<'a> Resolver<'a> {
18251825 }
18261826 }
18271827
1828+ fn find_similarly_named_type (
1829+ & mut self ,
1830+ ident : Symbol ,
1831+ ribs : Option < & PerNS < Vec < Rib < ' a > > > > ,
1832+ ) -> Option < Symbol > {
1833+ fn is_type_candidate ( res : Res ) -> bool {
1834+ matches ! (
1835+ res,
1836+ Res :: Def (
1837+ DefKind :: Struct
1838+ | DefKind :: Union
1839+ | DefKind :: Enum
1840+ | DefKind :: Trait
1841+ | DefKind :: TraitAlias
1842+ | DefKind :: TyAlias
1843+ | DefKind :: AssocTy
1844+ | DefKind :: TyParam
1845+ | DefKind :: OpaqueTy
1846+ | DefKind :: ForeignTy ,
1847+ _
1848+ ) | Res :: PrimTy ( ..)
1849+ | Res :: SelfTy { .. }
1850+ )
1851+ }
1852+
1853+ let mut names = Vec :: new ( ) ;
1854+ if let Some ( ribs) = ribs {
1855+ // Search in lexical scope.
1856+ // Walk backwards up the ribs in scope and collect candidates.
1857+ for rib in ribs[ TypeNS ] . iter ( ) . rev ( ) {
1858+ for ( ident, res) in & rib. bindings {
1859+ if is_type_candidate ( * res) {
1860+ names. push ( TypoSuggestion :: typo_from_res ( ident. name , * res) ) ;
1861+ }
1862+ }
1863+ // Items in scope
1864+ if let RibKind :: ModuleRibKind ( module) = rib. kind {
1865+ // Items from this module
1866+ self . add_module_candidates ( module, & mut names, & is_type_candidate) ;
1867+
1868+ if let ModuleKind :: Block ( ..) = module. kind {
1869+ // We can through blocks
1870+ } else {
1871+ // Items from the prelude
1872+ if !module. no_implicit_prelude {
1873+ if let Some ( prelude) = self . prelude {
1874+ self . add_module_candidates ( prelude, & mut names, & is_type_candidate) ;
1875+ }
1876+ }
1877+ break ;
1878+ }
1879+ }
1880+ }
1881+ // Add primitive types
1882+ names. extend ( PrimTy :: ALL . iter ( ) . map ( |prim_ty| {
1883+ TypoSuggestion :: typo_from_res ( prim_ty. name ( ) , Res :: PrimTy ( * prim_ty) )
1884+ } ) )
1885+ }
1886+
1887+ let mut names = names. iter ( ) . map ( |sugg| sugg. candidate ) . collect :: < Vec < Symbol > > ( ) ;
1888+ names. sort ( ) ;
1889+ names. dedup ( ) ;
1890+
1891+ match find_best_match_for_name ( & names, ident, None ) {
1892+ Some ( sugg) if sugg == ident => None ,
1893+ sugg => sugg,
1894+ }
1895+ }
1896+
18281897 pub ( crate ) fn report_path_resolution_error (
18291898 & mut self ,
18301899 path : & [ Segment ] ,
@@ -2001,16 +2070,22 @@ impl<'a> Resolver<'a> {
20012070 String :: from ( "add `extern crate alloc` to use the `alloc` crate" ) ,
20022071 Applicability :: MaybeIncorrect ,
20032072 ) )
2073+ } else if let Some ( sugg) =
2074+ self . find_similarly_named_module_or_crate ( ident. name , & parent_scope. module )
2075+ {
2076+ Some ( (
2077+ vec ! [ ( ident. span, sugg. to_string( ) ) ] ,
2078+ String :: from ( "there is a crate or module with a similar name" ) ,
2079+ Applicability :: MaybeIncorrect ,
2080+ ) )
20042081 } else {
2005- self . find_similarly_named_module_or_crate ( ident. name , & parent_scope. module ) . map (
2006- |sugg| {
2007- (
2008- vec ! [ ( ident. span, sugg. to_string( ) ) ] ,
2009- String :: from ( "there is a crate or module with a similar name" ) ,
2010- Applicability :: MaybeIncorrect ,
2011- )
2012- } ,
2013- )
2082+ self . find_similarly_named_type ( ident. name , ribs) . map ( |sugg| {
2083+ (
2084+ vec ! [ ( ident. span, sugg. to_string( ) ) ] ,
2085+ String :: from ( "there is a type with a similar name" ) ,
2086+ Applicability :: MaybeIncorrect ,
2087+ )
2088+ } )
20142089 } ;
20152090 ( format ! ( "use of undeclared crate or module `{}`" , ident) , suggestion)
20162091 }
0 commit comments