@@ -2654,15 +2654,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2654
2654
2655
2655
// Try to find a path to an item in a module.
2656
2656
let last_ident = segments. last ( ) . unwrap ( ) . identifier ;
2657
- if segments. len ( ) <= 1 {
2658
- let unqualified_def = self . resolve_identifier ( last_ident, namespace, true ) ;
2657
+ if segments. len ( ) == 1 {
2658
+ // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
2659
+ // don't report an error right away, but try to fallback to a primitive type.
2660
+ // So, we are still able to successfully resolve something like
2661
+ //
2662
+ // use std::u8; // bring module u8 in scope
2663
+ // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
2664
+ // u8::MAX // OK, resolves to associated constant <u8>::MAX,
2665
+ // // not to non-existent std::u8::MAX
2666
+ // }
2667
+ //
2668
+ // Such behavior is required for backward compatibility.
2669
+ // The same fallback is used when `a` resolves to nothing.
2670
+ let unqualified_def = self . resolve_identifier_with_fallback ( last_ident, namespace, true ) ;
2659
2671
return unqualified_def. and_then ( |def| self . adjust_local_def ( def, span) )
2660
2672
. map ( |def| {
2661
2673
PathResolution :: new ( def, path_depth)
2662
2674
} ) ;
2663
2675
}
2664
2676
2665
- let unqualified_def = self . resolve_identifier ( last_ident, namespace, false ) ;
2677
+ let unqualified_def = self . resolve_identifier_with_fallback ( last_ident, namespace, false ) ;
2666
2678
let def = self . resolve_module_relative_path ( span, segments, namespace) ;
2667
2679
match ( def, unqualified_def) {
2668
2680
( Some ( d) , Some ( ref ud) ) if d == ud. def => {
@@ -2678,6 +2690,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2678
2690
def. map ( mk_res)
2679
2691
}
2680
2692
2693
+ // Resolve a single identifier with fallback to primitive types
2694
+ fn resolve_identifier_with_fallback ( & mut self ,
2695
+ identifier : hir:: Ident ,
2696
+ namespace : Namespace ,
2697
+ check_ribs : bool ,
2698
+ record_used : bool )
2699
+ -> Option < LocalDef > {
2700
+ let def = self . resolve_identifier ( identifier, namespace, check_ribs, record_used) ;
2701
+ match def {
2702
+ None | Some ( LocalDef { def : Def :: Mod ( ..) , ..} ) => {
2703
+ if let Some ( & prim_ty) = self . primitive_type_table
2704
+ . primitive_types
2705
+ . get ( & identifier. unhygienic_name ) {
2706
+ Some ( LocalDef :: from_def ( Def :: PrimTy ( prim_ty) ) )
2707
+ } else {
2708
+ def
2709
+ }
2710
+ }
2711
+ _ => def
2712
+ }
2713
+ }
2714
+
2681
2715
// Resolve a single identifier
2682
2716
fn resolve_identifier ( & mut self ,
2683
2717
identifier : hir:: Ident ,
@@ -2688,15 +2722,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2688
2722
return Some ( LocalDef :: from_def ( Def :: Err ) ) ;
2689
2723
}
2690
2724
2691
- // First, check to see whether the name is a primitive type.
2692
- if namespace == TypeNS {
2693
- if let Some ( & prim_ty) = self . primitive_type_table
2694
- . primitive_types
2695
- . get ( & identifier. unhygienic_name ) {
2696
- return Some ( LocalDef :: from_def ( Def :: PrimTy ( prim_ty) ) ) ;
2697
- }
2698
- }
2699
-
2700
2725
self . resolve_identifier_in_local_ribs ( identifier, namespace, record_used)
2701
2726
}
2702
2727
0 commit comments