Auto merge of #30882 - petrochenkov:varnamesp, r=nrc
Tuple and unit variants from other crates weren't put into type namespace. Now variant namespacing is aligned with struct namespacing and is not affected by the variant's crate of origin (struct -> type, tuple/unit -> type/value). Additionally, struct variants from other crates are put into value namespace (struct variants from local crate were already in it). This is not a necessity, but a future proofing measure. This fix can result in some new shadowing errors in cross-crate scenarios, crater reports [three regressions](https://github.com/rust-lang/rust/pull/30882#issuecomment-172369883). [breaking-change]
This commit is contained in:
commit
54475e950c
6 changed files with 85 additions and 23 deletions
|
@ -510,9 +510,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
|||
self.structs.insert(variant_def_id, Vec::new());
|
||||
}
|
||||
|
||||
// Variants are always treated as importable to allow them to be glob used.
|
||||
// All variants are defined in both type and value namespaces as future-proofing.
|
||||
let child = self.add_child(name, parent, ForbidDuplicateTypesAndValues, variant.span);
|
||||
// variants are always treated as importable to allow them to be glob
|
||||
// used
|
||||
child.define_value(Def::Variant(item_id, self.ast_map.local_def_id(variant.node.data.id())),
|
||||
variant.span,
|
||||
DefModifiers::PUBLIC | DefModifiers::IMPORTABLE | variant_modifiers);
|
||||
|
@ -618,15 +618,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
|||
Def::Variant(_, variant_id) => {
|
||||
debug!("(building reduced graph for external crate) building variant {}",
|
||||
final_ident);
|
||||
// variants are always treated as importable to allow them to be
|
||||
// glob used
|
||||
// Variants are always treated as importable to allow them to be glob used.
|
||||
// All variants are defined in both type and value namespaces as future-proofing.
|
||||
let modifiers = DefModifiers::PUBLIC | DefModifiers::IMPORTABLE;
|
||||
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
|
||||
child_name_bindings.define_value(def, DUMMY_SP, modifiers);
|
||||
if self.session.cstore.variant_kind(variant_id) == Some(VariantKind::Struct) {
|
||||
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
|
||||
// Not adding fields for variants as they are not accessed with a self receiver
|
||||
self.structs.insert(variant_id, Vec::new());
|
||||
} else {
|
||||
child_name_bindings.define_value(def, DUMMY_SP, modifiers);
|
||||
}
|
||||
}
|
||||
Def::Fn(..) |
|
||||
|
|
15
src/test/auxiliary/variant-namespacing.rs
Normal file
15
src/test/auxiliary/variant-namespacing.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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.
|
||||
|
||||
pub enum XE {
|
||||
XStruct { a: u8 },
|
||||
XTuple(u8),
|
||||
XUnit,
|
||||
}
|
|
@ -39,6 +39,6 @@ fn main() {
|
|||
XEmpty1 => () // Not an error, `XEmpty1` is interpreted as a new binding
|
||||
}
|
||||
match xe3 {
|
||||
XE::XEmpty3 => () //~ ERROR no associated item named `XEmpty3` found for type
|
||||
XE::XEmpty3 => () //~ ERROR `XE::XEmpty3` does not name a tuple variant or a tuple struct
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,6 @@ fn main() {
|
|||
E::Empty3(..) => () //~ ERROR `E::Empty3` does not name a tuple variant or a tuple struct
|
||||
}
|
||||
match xe3 {
|
||||
XE::XEmpty3(..) => () //~ ERROR no associated item named `XEmpty3` found for type
|
||||
XE::XEmpty3(..) => () //~ ERROR `XE::XEmpty3` does not name a tuple variant or a tuple
|
||||
}
|
||||
}
|
||||
|
|
49
src/test/compile-fail/variant-namespacing.rs
Normal file
49
src/test/compile-fail/variant-namespacing.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
// 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:variant-namespacing.rs
|
||||
|
||||
extern crate variant_namespacing;
|
||||
pub use variant_namespacing::XE::*;
|
||||
//~^ ERROR import `XStruct` conflicts with type in this module
|
||||
//~| ERROR import `XStruct` conflicts with value in this module
|
||||
//~| ERROR import `XTuple` conflicts with type in this module
|
||||
//~| ERROR import `XTuple` conflicts with value in this module
|
||||
//~| ERROR import `XUnit` conflicts with type in this module
|
||||
//~| ERROR import `XUnit` conflicts with value in this module
|
||||
pub use E::*;
|
||||
//~^ ERROR import `Struct` conflicts with type in this module
|
||||
//~| ERROR import `Struct` conflicts with value in this module
|
||||
//~| ERROR import `Tuple` conflicts with type in this module
|
||||
//~| ERROR import `Tuple` conflicts with value in this module
|
||||
//~| ERROR import `Unit` conflicts with type in this module
|
||||
//~| ERROR import `Unit` conflicts with value in this module
|
||||
|
||||
enum E {
|
||||
Struct { a: u8 },
|
||||
Tuple(u8),
|
||||
Unit,
|
||||
}
|
||||
|
||||
type Struct = u8;
|
||||
type Tuple = u8;
|
||||
type Unit = u8;
|
||||
type XStruct = u8;
|
||||
type XTuple = u8;
|
||||
type XUnit = u8;
|
||||
|
||||
const Struct: u8 = 0;
|
||||
const Tuple: u8 = 0;
|
||||
const Unit: u8 = 0;
|
||||
const XStruct: u8 = 0;
|
||||
const XTuple: u8 = 0;
|
||||
const XUnit: u8 = 0;
|
||||
|
||||
fn main() {}
|
|
@ -95,8 +95,7 @@ fn xcrate() {
|
|||
let e2: XEmpty2 = XEmpty2 {};
|
||||
let e2: XEmpty2 = XEmpty2;
|
||||
let e3: XE = XE::XEmpty3 {};
|
||||
// FIXME: Commented out tests are waiting for PR 30882 (fixes for variant namespaces)
|
||||
// let e4: XE = XE::XEmpty4 {};
|
||||
let e4: XE = XE::XEmpty4 {};
|
||||
let e4: XE = XE::XEmpty4;
|
||||
|
||||
match e1 {
|
||||
|
@ -109,10 +108,10 @@ fn xcrate() {
|
|||
XE::XEmpty3 {} => {}
|
||||
_ => {}
|
||||
}
|
||||
// match e4 {
|
||||
// XE::XEmpty4 {} => {}
|
||||
// _ => {}
|
||||
// }
|
||||
match e4 {
|
||||
XE::XEmpty4 {} => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match e1 {
|
||||
XEmpty1 { .. } => {}
|
||||
|
@ -124,18 +123,18 @@ fn xcrate() {
|
|||
XE::XEmpty3 { .. } => {}
|
||||
_ => {}
|
||||
}
|
||||
// match e4 {
|
||||
// XE::XEmpty4 { .. } => {}
|
||||
// _ => {}
|
||||
// }
|
||||
match e4 {
|
||||
XE::XEmpty4 { .. } => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match e2 {
|
||||
XEmpty2 => {}
|
||||
}
|
||||
// match e4 {
|
||||
// XE::XEmpty4 => {}
|
||||
// _ => {}
|
||||
// }
|
||||
match e4 {
|
||||
XE::XEmpty4 => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let e11: XEmpty1 = XEmpty1 { ..e1 };
|
||||
let e22: XEmpty2 = XEmpty2 { ..e2 };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue