Skip to content

Fix issue #20427 #22093

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
E0317 // user-defined types or type parameters cannot shadow the primitive types
}

__build_diagnostic_array! { DIAGNOSTICS }
30 changes: 29 additions & 1 deletion src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, E0317,
"user-defined types or type parameters cannot shadow the primitive types");
}
}

fn resolve_item(&mut self, item: &Item) {
let name = item.ident.name;

Expand All @@ -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
Expand All @@ -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,
Expand All @@ -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);

Expand Down Expand Up @@ -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[]);
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions src/test/auxiliary/i8.rs
Original file line number Diff line number Diff line change
@@ -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;
66 changes: 66 additions & 0 deletions src/test/compile-fail/issue-20427.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}