diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-03-08 21:40:13 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-03-25 00:41:09 +0300 |
| commit | 8d4b1d1cf38a51b92b91e020ecb22a5d442297be (patch) | |
| tree | 05500947573c3adf63b5f051f3e7aa90817ab098 | |
| parent | dcfb8d72e99425686376298fd793715f35b5d512 (diff) | |
Introduce name resolution fallback for primitive types
| -rw-r--r-- | src/librustc_resolve/lib.rs | 49 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-20427.rs | 1 |
2 files changed, 38 insertions, 12 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index af8c9d81687..8efac52158e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2654,15 +2654,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Try to find a path to an item in a module. let last_ident = segments.last().unwrap().identifier; - if segments.len() <= 1 { - let unqualified_def = self.resolve_identifier(last_ident, namespace, true); + if segments.len() == 1 { + // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we + // don't report an error right away, but try to fallback to a primitive type. + // So, we are still able to successfully resolve something like + // + // use std::u8; // bring module u8 in scope + // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8 + // u8::MAX // OK, resolves to associated constant <u8>::MAX, + // // not to non-existent std::u8::MAX + // } + // + // Such behavior is required for backward compatibility. + // The same fallback is used when `a` resolves to nothing. + let unqualified_def = self.resolve_identifier_with_fallback(last_ident, namespace, true); return unqualified_def.and_then(|def| self.adjust_local_def(def, span)) .map(|def| { PathResolution::new(def, path_depth) }); } - let unqualified_def = self.resolve_identifier(last_ident, namespace, false); + let unqualified_def = self.resolve_identifier_with_fallback(last_ident, namespace, false); let def = self.resolve_module_relative_path(span, segments, namespace); match (def, unqualified_def) { (Some(d), Some(ref ud)) if d == ud.def => { @@ -2678,6 +2690,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { def.map(mk_res) } + // Resolve a single identifier with fallback to primitive types + fn resolve_identifier_with_fallback(&mut self, + identifier: hir::Ident, + namespace: Namespace, + check_ribs: bool, + record_used: bool) + -> Option<LocalDef> { + let def = self.resolve_identifier(identifier, namespace, check_ribs, record_used); + match def { + None | Some(LocalDef{def: Def::Mod(..), ..}) => { + if let Some(&prim_ty) = self.primitive_type_table + .primitive_types + .get(&identifier.unhygienic_name) { + Some(LocalDef::from_def(Def::PrimTy(prim_ty))) + } else { + def + } + } + _ => def + } + } + // Resolve a single identifier fn resolve_identifier(&mut self, identifier: hir::Ident, @@ -2688,15 +2722,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return Some(LocalDef::from_def(Def::Err)); } - // First, check to see whether the name is a primitive type. - if namespace == TypeNS { - if let Some(&prim_ty) = self.primitive_type_table - .primitive_types - .get(&identifier.unhygienic_name) { - return Some(LocalDef::from_def(Def::PrimTy(prim_ty))); - } - } - self.resolve_identifier_in_local_ribs(identifier, namespace, record_used) } diff --git a/src/test/compile-fail/issue-20427.rs b/src/test/compile-fail/issue-20427.rs index 99dd22a888c..7dedb9593e1 100644 --- a/src/test/compile-fail/issue-20427.rs +++ b/src/test/compile-fail/issue-20427.rs @@ -17,6 +17,7 @@ fn u8(f32: f32) {} fn f<f64>(f64: f64) {} //~^ ERROR user-defined types or type parameters cannot shadow the primitive types type u16 = u16; //~ ERROR user-defined types or type parameters cannot shadow the primitive types +//~^ ERROR unsupported cyclic reference between types/traits detected enum u32 {} //~ ERROR user-defined types or type parameters cannot shadow the primitive types struct u64; //~ ERROR user-defined types or type parameters cannot shadow the primitive types trait bool {} //~ ERROR user-defined types or type parameters cannot shadow the primitive types |
