diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 7b6ee3a729776..1fe49b64b98f7 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -23,7 +23,8 @@ register_diagnostics! { E0257, // inherent implementations are only allowed 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 dc1e91cd14bbd..f79995f95dfb9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2788,6 +2788,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; @@ -2799,6 +2806,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 @@ -2824,6 +2833,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, @@ -2847,6 +2858,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); @@ -2919,6 +2932,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[]); @@ -2972,7 +2987,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 } } @@ -3114,6 +3141,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 0000000000000..44e62b99a96d1 --- /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 or the MIT license +// , 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 0000000000000..96d4fae8b036d --- /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 or the MIT license +// , 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) {} +//~^ 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_) {} + 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, + } +}