Auto merge of #22093 - petrochenkov:builtin, r=pnkfelix
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]
This commit is contained in:
commit
cf636c233d
4 changed files with 110 additions and 2 deletions
|
@ -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 }
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
|
13
src/test/auxiliary/i8.rs
Normal file
13
src/test/auxiliary/i8.rs
Normal file
|
@ -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
src/test/compile-fail/issue-20427.rs
Normal file
66
src/test/compile-fail/issue-20427.rs
Normal file
|
@ -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,
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue