Skip to content

Commit 6457c9f

Browse files
committed
Fix issue #20427
1 parent b75b21c commit 6457c9f

File tree

4 files changed

+110
-2
lines changed

4 files changed

+110
-2
lines changed

src/librustc_resolve/diagnostics.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ register_diagnostics! {
2323
E0257, // inherent implementations are only allowen on types defined in the current module
2424
E0258, // import conflicts with existing submodule
2525
E0259, // an extern crate has already been imported into this module
26-
E0260 // name conflicts with an external crate that has been imported into this module
26+
E0260, // name conflicts with an external crate that has been imported into this module
27+
E0316 // user-defined types or type parameters cannot shadow the primitive types
2728
}
2829

2930
__build_diagnostic_array! { DIAGNOSTICS }

src/librustc_resolve/lib.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -2784,6 +2784,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27842784
visit::walk_crate(self, krate);
27852785
}
27862786

2787+
fn check_if_primitive_type_name(&self, name: Name, span: Span) {
2788+
if let Some(_) = self.primitive_type_table.primitive_types.get(&name) {
2789+
span_err!(self.session, span, E0316,
2790+
"user-defined types or type parameters cannot shadow the primitive types");
2791+
}
2792+
}
2793+
27872794
fn resolve_item(&mut self, item: &Item) {
27882795
let name = item.ident.name;
27892796

@@ -2795,6 +2802,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27952802
// enum item: resolve all the variants' discrs,
27962803
// then resolve the ty params
27972804
ItemEnum(ref enum_def, ref generics) => {
2805+
self.check_if_primitive_type_name(name, item.span);
2806+
27982807
for variant in &(*enum_def).variants {
27992808
if let Some(ref dis_expr) = variant.node.disr_expr {
28002809
// resolve the discriminator expr
@@ -2820,6 +2829,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
28202829
}
28212830

28222831
ItemTy(_, ref generics) => {
2832+
self.check_if_primitive_type_name(name, item.span);
2833+
28232834
self.with_type_parameter_rib(HasTypeParameters(generics,
28242835
TypeSpace,
28252836
item.id,
@@ -2843,6 +2854,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
28432854
}
28442855

28452856
ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
2857+
self.check_if_primitive_type_name(name, item.span);
2858+
28462859
// Create a new rib for the self type.
28472860
let mut self_type_rib = Rib::new(ItemRibKind);
28482861

@@ -2915,6 +2928,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
29152928
}
29162929

29172930
ItemStruct(ref struct_def, ref generics) => {
2931+
self.check_if_primitive_type_name(name, item.span);
2932+
29182933
self.resolve_struct(item.id,
29192934
generics,
29202935
&struct_def.fields[]);
@@ -2968,7 +2983,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
29682983
});
29692984
}
29702985

2971-
ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => {
2986+
ItemUse(ref view_path) => {
2987+
// check for imports shadowing primitive types
2988+
if let ast::ViewPathSimple(ident, _) = view_path.node {
2989+
match self.def_map.borrow().get(&item.id) {
2990+
Some(&DefTy(..)) | Some(&DefStruct(..)) | Some(&DefTrait(..)) | None => {
2991+
self.check_if_primitive_type_name(ident.name, item.span);
2992+
}
2993+
_ => {}
2994+
}
2995+
}
2996+
}
2997+
2998+
ItemExternCrate(_) | ItemMac(..) => {
29722999
// do nothing, these are just around to be encoded
29733000
}
29743001
}
@@ -3110,6 +3137,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
31103137

31113138
fn resolve_type_parameter(&mut self,
31123139
type_parameter: &TyParam) {
3140+
self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
31133141
for bound in &*type_parameter.bounds {
31143142
self.resolve_type_parameter_bound(type_parameter.id, bound,
31153143
TraitBoundingTypeParameter);

src/test/auxiliary/i8.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// A crate named after a built-in type.
12+
13+
pub struct Test;

src/test/compile-fail/issue-20427.rs

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:i8.rs
12+
extern crate i8;
13+
use std::string as i16;
14+
static i32: i32 = 0;
15+
const i64: i64 = 0;
16+
fn u8(f32: f32) {}
17+
fn f<f64>(f64: f64) {}
18+
//~^ ERROR user-defined types or type parameters cannot shadow the primitive types
19+
type u16 = u16; //~ ERROR user-defined types or type parameters cannot shadow the primitive types
20+
enum u32 {} //~ ERROR user-defined types or type parameters cannot shadow the primitive types
21+
struct u64; //~ ERROR user-defined types or type parameters cannot shadow the primitive types
22+
trait bool {} //~ ERROR user-defined types or type parameters cannot shadow the primitive types
23+
24+
mod char {
25+
extern crate i8;
26+
static i32_: i32 = 0;
27+
const i64_: i64 = 0;
28+
fn u8_(f32: f32) {}
29+
fn f_<f64_>(f64: f64_) {}
30+
type u16_ = u16;
31+
enum u32_ {}
32+
struct u64_;
33+
trait bool_ {}
34+
mod char_ {}
35+
36+
mod str {
37+
use super::i8 as i8;
38+
use super::i32_ as i32;
39+
use super::i64_ as i64;
40+
use super::u8_ as u8;
41+
use super::f_ as f64;
42+
use super::u16_ as u16;
43+
//~^ ERROR user-defined types or type parameters cannot shadow the primitive types
44+
use super::u32_ as u32;
45+
//~^ ERROR user-defined types or type parameters cannot shadow the primitive types
46+
use super::u64_ as u64;
47+
//~^ ERROR user-defined types or type parameters cannot shadow the primitive types
48+
use super::bool_ as bool;
49+
//~^ ERROR user-defined types or type parameters cannot shadow the primitive types
50+
use super::char_ as char;
51+
}
52+
}
53+
54+
trait isize_ {
55+
type isize; //~ ERROR user-defined types or type parameters cannot shadow the primitive types
56+
}
57+
58+
fn usize<'usize>(usize: &'usize usize) -> &'usize usize { usize }
59+
60+
fn main() {
61+
let bool = true;
62+
match bool {
63+
str @ true => if str { i32 as i64 } else { 0 },
64+
false => i64,
65+
}
66+
}

0 commit comments

Comments
 (0)