@@ -8,12 +8,13 @@ use rustc_errors::{
8
8
} ;
9
9
use rustc_feature:: BUILTIN_ATTRIBUTES ;
10
10
use rustc_hir:: def:: Namespace :: { self , * } ;
11
- use rustc_hir:: def:: { self , CtorKind , CtorOf , DefKind , NonMacroAttrKind } ;
11
+ use rustc_hir:: def:: { self , CtorKind , CtorOf , DefKind , NonMacroAttrKind , PerNS } ;
12
12
use rustc_hir:: def_id:: { DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
13
13
use rustc_hir:: PrimTy ;
14
14
use rustc_middle:: bug;
15
15
use rustc_middle:: ty:: DefIdTree ;
16
16
use rustc_session:: Session ;
17
+ use rustc_span:: edition:: Edition ;
17
18
use rustc_span:: hygiene:: MacroKind ;
18
19
use rustc_span:: lev_distance:: find_best_match_for_name;
19
20
use rustc_span:: source_map:: SourceMap ;
@@ -22,10 +23,11 @@ use rustc_span::{BytePos, Span};
22
23
use tracing:: debug;
23
24
24
25
use crate :: imports:: { Import , ImportKind , ImportResolver } ;
26
+ use crate :: late:: Rib ;
25
27
use crate :: path_names_to_string;
26
- use crate :: { AmbiguityError , AmbiguityErrorMisc , AmbiguityKind } ;
28
+ use crate :: { AmbiguityError , AmbiguityErrorMisc , AmbiguityKind , Finalize } ;
27
29
use crate :: { BindingError , HasGenericParams , MacroRulesScope , Module , ModuleOrUniformRoot } ;
28
- use crate :: { NameBinding , NameBindingKind , PrivacyError , VisResolutionError } ;
30
+ use crate :: { LexicalScopeBinding , NameBinding , NameBindingKind , PrivacyError , VisResolutionError } ;
29
31
use crate :: { ParentScope , PathResult , ResolutionError , Resolver , Scope , ScopeSet , Segment } ;
30
32
31
33
type Res = def:: Res < ast:: NodeId > ;
@@ -1377,6 +1379,196 @@ impl<'a> Resolver<'a> {
1377
1379
sugg => sugg,
1378
1380
}
1379
1381
}
1382
+
1383
+ crate fn report_path_resolution_error (
1384
+ & mut self ,
1385
+ path : & [ Segment ] ,
1386
+ opt_ns : Option < Namespace > , // `None` indicates a module path in import
1387
+ parent_scope : & ParentScope < ' a > ,
1388
+ finalize_full : Finalize ,
1389
+ ribs : Option < & PerNS < Vec < Rib < ' a > > > > ,
1390
+ unusable_binding : Option < & ' a NameBinding < ' a > > ,
1391
+ module : Option < ModuleOrUniformRoot < ' a > > ,
1392
+ i : usize ,
1393
+ ident : Ident ,
1394
+ ) -> ( String , Option < Suggestion > ) {
1395
+ let finalize = finalize_full. path_span ( ) ;
1396
+ let is_last = i == path. len ( ) - 1 ;
1397
+ let ns = if is_last { opt_ns. unwrap_or ( TypeNS ) } else { TypeNS } ;
1398
+ let module_res = match module {
1399
+ Some ( ModuleOrUniformRoot :: Module ( module) ) => module. res ( ) ,
1400
+ _ => None ,
1401
+ } ;
1402
+ if module_res == self . graph_root . res ( ) {
1403
+ let is_mod = |res| matches ! ( res, Res :: Def ( DefKind :: Mod , _) ) ;
1404
+ let mut candidates = self . lookup_import_candidates ( ident, TypeNS , parent_scope, is_mod) ;
1405
+ candidates
1406
+ . sort_by_cached_key ( |c| ( c. path . segments . len ( ) , pprust:: path_to_string ( & c. path ) ) ) ;
1407
+ if let Some ( candidate) = candidates. get ( 0 ) {
1408
+ (
1409
+ String :: from ( "unresolved import" ) ,
1410
+ Some ( (
1411
+ vec ! [ ( ident. span, pprust:: path_to_string( & candidate. path) ) ] ,
1412
+ String :: from ( "a similar path exists" ) ,
1413
+ Applicability :: MaybeIncorrect ,
1414
+ ) ) ,
1415
+ )
1416
+ } else if self . session . edition ( ) == Edition :: Edition2015 {
1417
+ ( format ! ( "maybe a missing crate `{}`?" , ident) , None )
1418
+ } else {
1419
+ ( format ! ( "could not find `{}` in the crate root" , ident) , None )
1420
+ }
1421
+ } else if i == 0 {
1422
+ if ident. name . as_str ( ) . chars ( ) . next ( ) . map_or ( false , |c| c. is_ascii_uppercase ( ) ) {
1423
+ // Check whether the name refers to an item in the value namespace.
1424
+ let suggestion = if ribs. is_some ( ) {
1425
+ let match_span = match self . resolve_ident_in_lexical_scope (
1426
+ ident,
1427
+ ValueNS ,
1428
+ parent_scope,
1429
+ Finalize :: No ,
1430
+ & ribs. unwrap ( ) [ ValueNS ] ,
1431
+ unusable_binding,
1432
+ ) {
1433
+ // Name matches a local variable. For example:
1434
+ // ```
1435
+ // fn f() {
1436
+ // let Foo: &str = "";
1437
+ // println!("{}", Foo::Bar); // Name refers to local
1438
+ // // variable `Foo`.
1439
+ // }
1440
+ // ```
1441
+ Some ( LexicalScopeBinding :: Res ( Res :: Local ( id) ) ) => {
1442
+ Some ( * self . pat_span_map . get ( & id) . unwrap ( ) )
1443
+ }
1444
+
1445
+ // Name matches item from a local name binding
1446
+ // created by `use` declaration. For example:
1447
+ // ```
1448
+ // pub Foo: &str = "";
1449
+ //
1450
+ // mod submod {
1451
+ // use super::Foo;
1452
+ // println!("{}", Foo::Bar); // Name refers to local
1453
+ // // binding `Foo`.
1454
+ // }
1455
+ // ```
1456
+ Some ( LexicalScopeBinding :: Item ( name_binding) ) => Some ( name_binding. span ) ,
1457
+ _ => None ,
1458
+ } ;
1459
+
1460
+ if let Some ( span) = match_span {
1461
+ Some ( (
1462
+ vec ! [ ( span, String :: from( "" ) ) ] ,
1463
+ format ! ( "`{}` is defined here, but is not a type" , ident) ,
1464
+ Applicability :: MaybeIncorrect ,
1465
+ ) )
1466
+ } else {
1467
+ None
1468
+ }
1469
+ } else {
1470
+ None
1471
+ } ;
1472
+
1473
+ ( format ! ( "use of undeclared type `{}`" , ident) , suggestion)
1474
+ } else {
1475
+ (
1476
+ format ! ( "use of undeclared crate or module `{}`" , ident) ,
1477
+ if ident. name == sym:: alloc {
1478
+ Some ( (
1479
+ vec ! [ ] ,
1480
+ String :: from ( "add `extern crate alloc` to use the `alloc` crate" ) ,
1481
+ Applicability :: MaybeIncorrect ,
1482
+ ) )
1483
+ } else {
1484
+ self . find_similarly_named_module_or_crate ( ident. name , & parent_scope. module )
1485
+ . map ( |sugg| {
1486
+ (
1487
+ vec ! [ ( ident. span, sugg. to_string( ) ) ] ,
1488
+ String :: from ( "there is a crate or module with a similar name" ) ,
1489
+ Applicability :: MaybeIncorrect ,
1490
+ )
1491
+ } )
1492
+ } ,
1493
+ )
1494
+ }
1495
+ } else {
1496
+ let parent = path[ i - 1 ] . ident . name ;
1497
+ let parent = match parent {
1498
+ // ::foo is mounted at the crate root for 2015, and is the extern
1499
+ // prelude for 2018+
1500
+ kw:: PathRoot if self . session . edition ( ) > Edition :: Edition2015 => {
1501
+ "the list of imported crates" . to_owned ( )
1502
+ }
1503
+ kw:: PathRoot | kw:: Crate => "the crate root" . to_owned ( ) ,
1504
+ _ => {
1505
+ format ! ( "`{}`" , parent)
1506
+ }
1507
+ } ;
1508
+
1509
+ let mut msg = format ! ( "could not find `{}` in {}" , ident, parent) ;
1510
+ if ns == TypeNS || ns == ValueNS {
1511
+ let ns_to_try = if ns == TypeNS { ValueNS } else { TypeNS } ;
1512
+ let binding = if let Some ( module) = module {
1513
+ self . resolve_ident_in_module (
1514
+ module,
1515
+ ident,
1516
+ ns_to_try,
1517
+ parent_scope,
1518
+ finalize,
1519
+ false ,
1520
+ unusable_binding,
1521
+ ) . ok ( )
1522
+ } else if let Some ( ribs) = ribs
1523
+ && let Some ( TypeNS | ValueNS ) = opt_ns
1524
+ {
1525
+ match self . resolve_ident_in_lexical_scope (
1526
+ ident,
1527
+ ns_to_try,
1528
+ parent_scope,
1529
+ finalize_full,
1530
+ & ribs[ ns_to_try] ,
1531
+ unusable_binding,
1532
+ ) {
1533
+ // we found a locally-imported or available item/module
1534
+ Some ( LexicalScopeBinding :: Item ( binding) ) => Some ( binding) ,
1535
+ _ => None ,
1536
+ }
1537
+ } else {
1538
+ let scopes = ScopeSet :: All ( ns_to_try, opt_ns. is_none ( ) ) ;
1539
+ self . early_resolve_ident_in_lexical_scope (
1540
+ ident,
1541
+ scopes,
1542
+ parent_scope,
1543
+ finalize,
1544
+ finalize. is_some ( ) ,
1545
+ false ,
1546
+ unusable_binding,
1547
+ ) . ok ( )
1548
+ } ;
1549
+ if let Some ( binding) = binding {
1550
+ let mut found = |what| {
1551
+ msg = format ! (
1552
+ "expected {}, found {} `{}` in {}" ,
1553
+ ns. descr( ) ,
1554
+ what,
1555
+ ident,
1556
+ parent
1557
+ )
1558
+ } ;
1559
+ if binding. module ( ) . is_some ( ) {
1560
+ found ( "module" )
1561
+ } else {
1562
+ match binding. res ( ) {
1563
+ Res :: Def ( kind, id) => found ( kind. descr ( id) ) ,
1564
+ _ => found ( ns_to_try. descr ( ) ) ,
1565
+ }
1566
+ }
1567
+ } ;
1568
+ }
1569
+ ( msg, None )
1570
+ }
1571
+ }
1380
1572
}
1381
1573
1382
1574
impl < ' a , ' b > ImportResolver < ' a , ' b > {
0 commit comments