Skip to content

Commit 8d4b1d1

Browse files
committed
Introduce name resolution fallback for primitive types
1 parent dcfb8d7 commit 8d4b1d1

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

src/librustc_resolve/lib.rs

+37-12
Original file line numberDiff line numberDiff line change
@@ -2654,15 +2654,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26542654

26552655
// Try to find a path to an item in a module.
26562656
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);
26592671
return unqualified_def.and_then(|def| self.adjust_local_def(def, span))
26602672
.map(|def| {
26612673
PathResolution::new(def, path_depth)
26622674
});
26632675
}
26642676

2665-
let unqualified_def = self.resolve_identifier(last_ident, namespace, false);
2677+
let unqualified_def = self.resolve_identifier_with_fallback(last_ident, namespace, false);
26662678
let def = self.resolve_module_relative_path(span, segments, namespace);
26672679
match (def, unqualified_def) {
26682680
(Some(d), Some(ref ud)) if d == ud.def => {
@@ -2678,6 +2690,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26782690
def.map(mk_res)
26792691
}
26802692

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+
26812715
// Resolve a single identifier
26822716
fn resolve_identifier(&mut self,
26832717
identifier: hir::Ident,
@@ -2688,15 +2722,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26882722
return Some(LocalDef::from_def(Def::Err));
26892723
}
26902724

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-
27002725
self.resolve_identifier_in_local_ribs(identifier, namespace, record_used)
27012726
}
27022727

src/test/compile-fail/issue-20427.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn u8(f32: f32) {}
1717
fn f<f64>(f64: f64) {}
1818
//~^ ERROR user-defined types or type parameters cannot shadow the primitive types
1919
type u16 = u16; //~ ERROR user-defined types or type parameters cannot shadow the primitive types
20+
//~^ ERROR unsupported cyclic reference between types/traits detected
2021
enum u32 {} //~ ERROR user-defined types or type parameters cannot shadow the primitive types
2122
struct u64; //~ ERROR user-defined types or type parameters cannot shadow the primitive types
2223
trait bool {} //~ ERROR user-defined types or type parameters cannot shadow the primitive types

0 commit comments

Comments
 (0)