about summary refs log tree commit diff
diff options
context:
space:
mode:
authorwe <vadim.petrochenkov@gmail.com>2015-02-08 19:29:47 +0300
committerwe <vadim.petrochenkov@gmail.com>2015-02-08 19:29:47 +0300
commit6457c9fce29814aefdb072a39f86ee1321615099 (patch)
tree97b3b742f499697cca1722c434a93daa42452b55
parentb75b21cb9b187a6f836da61769a8110354fd6dad (diff)
downloadrust-6457c9fce29814aefdb072a39f86ee1321615099.tar.gz
rust-6457c9fce29814aefdb072a39f86ee1321615099.zip
Fix issue #20427
-rw-r--r--src/librustc_resolve/diagnostics.rs3
-rw-r--r--src/librustc_resolve/lib.rs30
-rw-r--r--src/test/auxiliary/i8.rs13
-rw-r--r--src/test/compile-fail/issue-20427.rs66
4 files changed, 110 insertions, 2 deletions
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index dd9ccfbda7c..5361cf3a79a 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -23,7 +23,8 @@ register_diagnostics! {
     E0257, // inherent implementations are only allowen on types defined in the current module
     E0258, // import conflicts with existing submodule
     E0259, // an extern crate has already been imported into this module
-    E0260 // name conflicts with an external crate that has been imported into this module
+    E0260, // name conflicts with an external crate that has been imported into this module
+    E0316 // user-defined types or type parameters cannot shadow the primitive types
 }
 
 __build_diagnostic_array! { DIAGNOSTICS }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index ec1d300dbec..d4002e17236 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2784,6 +2784,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         visit::walk_crate(self, krate);
     }
 
+    fn check_if_primitive_type_name(&self, name: Name, span: Span) {
+        if let Some(_) = self.primitive_type_table.primitive_types.get(&name) {
+            span_err!(self.session, span, E0316,
+                "user-defined types or type parameters cannot shadow the primitive types");
+        }
+    }
+
     fn resolve_item(&mut self, item: &Item) {
         let name = item.ident.name;
 
@@ -2795,6 +2802,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             // enum item: resolve all the variants' discrs,
             // then resolve the ty params
             ItemEnum(ref enum_def, ref generics) => {
+                self.check_if_primitive_type_name(name, item.span);
+
                 for variant in &(*enum_def).variants {
                     if let Some(ref dis_expr) = variant.node.disr_expr {
                         // resolve the discriminator expr
@@ -2820,6 +2829,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
 
             ItemTy(_, ref generics) => {
+                self.check_if_primitive_type_name(name, item.span);
+
                 self.with_type_parameter_rib(HasTypeParameters(generics,
                                                                TypeSpace,
                                                                item.id,
@@ -2843,6 +2854,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
 
             ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
+                self.check_if_primitive_type_name(name, item.span);
+
                 // Create a new rib for the self type.
                 let mut self_type_rib = Rib::new(ItemRibKind);
 
@@ -2915,6 +2928,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
 
             ItemStruct(ref struct_def, ref generics) => {
+                self.check_if_primitive_type_name(name, item.span);
+
                 self.resolve_struct(item.id,
                                     generics,
                                     &struct_def.fields[]);
@@ -2968,7 +2983,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 });
             }
 
-            ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => {
+            ItemUse(ref view_path) => {
+                // check for imports shadowing primitive types
+                if let ast::ViewPathSimple(ident, _) = view_path.node {
+                    match self.def_map.borrow().get(&item.id) {
+                        Some(&DefTy(..)) | Some(&DefStruct(..)) | Some(&DefTrait(..)) | None => {
+                            self.check_if_primitive_type_name(ident.name, item.span);
+                        }
+                        _ => {}
+                    }
+                }
+            }
+
+            ItemExternCrate(_) | ItemMac(..) => {
                 // do nothing, these are just around to be encoded
             }
         }
@@ -3110,6 +3137,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn resolve_type_parameter(&mut self,
                               type_parameter: &TyParam) {
+        self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
         for bound in &*type_parameter.bounds {
             self.resolve_type_parameter_bound(type_parameter.id, bound,
                                               TraitBoundingTypeParameter);
diff --git a/src/test/auxiliary/i8.rs b/src/test/auxiliary/i8.rs
new file mode 100644
index 00000000000..44e62b99a96
--- /dev/null
+++ b/src/test/auxiliary/i8.rs
@@ -0,0 +1,13 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// A crate named after a built-in type.
+
+pub struct Test;
diff --git a/src/test/compile-fail/issue-20427.rs b/src/test/compile-fail/issue-20427.rs
new file mode 100644
index 00000000000..96d4fae8b03
--- /dev/null
+++ b/src/test/compile-fail/issue-20427.rs
@@ -0,0 +1,66 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:i8.rs
+extern crate i8;
+use std::string as i16;
+static i32: i32 = 0;
+const i64: i64 = 0;
+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
+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
+
+mod char {
+    extern crate i8;
+    static i32_: i32 = 0;
+    const i64_: i64 = 0;
+    fn u8_(f32: f32) {}
+    fn f_<f64_>(f64: f64_) {}
+    type u16_ = u16;
+    enum u32_ {}
+    struct u64_;
+    trait bool_ {}
+    mod char_ {}
+
+    mod str {
+        use super::i8 as i8;
+        use super::i32_ as i32;
+        use super::i64_ as i64;
+        use super::u8_ as u8;
+        use super::f_ as f64;
+        use super::u16_ as u16;
+        //~^ ERROR user-defined types or type parameters cannot shadow the primitive types
+        use super::u32_ as u32;
+        //~^ ERROR user-defined types or type parameters cannot shadow the primitive types
+        use super::u64_ as u64;
+        //~^ ERROR user-defined types or type parameters cannot shadow the primitive types
+        use super::bool_ as bool;
+        //~^ ERROR user-defined types or type parameters cannot shadow the primitive types
+        use super::char_ as char;
+    }
+}
+
+trait isize_ {
+    type isize; //~ ERROR user-defined types or type parameters cannot shadow the primitive types
+}
+
+fn usize<'usize>(usize: &'usize usize) -> &'usize usize { usize }
+
+fn main() {
+    let bool = true;
+    match bool {
+        str @ true => if str { i32 as i64 } else { 0 },
+        false => i64,
+    }
+}