Skip to content

Commit

Permalink
Auto merge of #22093 - petrochenkov:builtin, r=pnkfelix
Browse files Browse the repository at this point in the history
Names of structs, enums, traits, type aliases and type parameters (i.e. all identifiers that can be used as full paths in type position) are not allowed to match the names of primitive types.
See #20427 for more information.

This is a minor [breaking-change]
  • Loading branch information
bors committed Feb 13, 2015
2 parents ba2efe9 + 8ed58d8 commit cf636c2
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 2 deletions.
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 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
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 @@ -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, 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 @@ -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
Expand All @@ -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,
Expand All @@ -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);

Expand Down Expand Up @@ -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[]);
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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);
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,
}
}

0 comments on commit cf636c2

Please sign in to comment.