Rollup merge of #36868 - petrochenkov:adtstab, r=nikomatsakis

Partially stabilize RFC 1506 "Clarify relationships between ADTs"

Lifted restrictions on tuple structs/variants are stabilized, i.e. `S{..}` can be used with any structs and empty tuple structs are permitted without feature gate.
Numeric fields in struct expressions/patterns `S { 0: a, 1: b }` are **NOT** stabilized.
This was implemented 1.5 months ago in Rust 1.12, but this is a tiny technical change that could probably go even without RFC/stabilization period.

cc https://github.com/rust-lang/rust/issues/35626 https://github.com/rust-lang/rust/pull/36871
r? @nikomatsakis
This commit is contained in:
Eduard-Mihai Burtescu 2016-11-09 20:51:15 +02:00 committed by GitHub
commit f433209248
19 changed files with 23 additions and 115 deletions

View File

@ -3261,13 +3261,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
if let Some((variant, did, substs)) = variant {
if variant.ctor_kind == CtorKind::Fn &&
!self.tcx.sess.features.borrow().relaxed_adts {
emit_feature_err(&self.tcx.sess.parse_sess,
"relaxed_adts", path.span, GateIssue::Language,
"tuple structs and variants in struct patterns are unstable");
}
// Check bounds on type arguments used in the path.
let type_predicates = self.tcx.lookup_predicates(did);
let bounds = self.instantiate_bounds(path.span, substs, &type_predicates);

View File

@ -271,7 +271,6 @@ declare_features! (
// Allows `impl Trait` in function return types.
(active, conservative_impl_trait, "1.12.0", Some(34511)),
// Allows tuple structs and variants in more contexts,
// Permits numeric fields in struct expressions and patterns.
(active, relaxed_adts, "1.12.0", Some(35626)),
@ -996,6 +995,10 @@ fn contains_novel_literal(item: &ast::MetaItem) -> bool {
}
}
fn starts_with_digit(s: &str) -> bool {
s.as_bytes().first().cloned().map_or(false, |b| b >= b'0' && b <= b'9')
}
impl<'a> Visitor for PostExpansionVisitor<'a> {
fn visit_attribute(&mut self, attr: &ast::Attribute) {
if !self.context.cm.span_allows_unstable(attr.span) {
@ -1175,6 +1178,11 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
gate_feature_post!(&self, field_init_shorthand, field.span,
"struct field shorthands are unstable");
}
if starts_with_digit(&field.ident.node.name.as_str()) {
gate_feature_post!(&self, relaxed_adts,
field.span,
"numeric fields in struct expressions are unstable");
}
}
}
_ => {}
@ -1201,10 +1209,14 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
pattern.span,
"box pattern syntax is experimental");
}
PatKind::TupleStruct(_, ref fields, ddpos)
if ddpos.is_none() && fields.is_empty() => {
gate_feature_post!(&self, relaxed_adts, pattern.span,
"empty tuple structs patterns are unstable");
PatKind::Struct(_, ref fields, _) => {
for field in fields {
if starts_with_digit(&field.node.ident.name.as_str()) {
gate_feature_post!(&self, relaxed_adts,
field.span,
"numeric fields in struct patterns are unstable");
}
}
}
_ => {}
}
@ -1287,19 +1299,6 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
visit::walk_impl_item(self, ii);
}
fn visit_variant_data(&mut self, vdata: &ast::VariantData, _: ast::Ident,
_: &ast::Generics, _: NodeId, span: Span) {
if vdata.fields().is_empty() {
if vdata.is_tuple() {
gate_feature_post!(&self, relaxed_adts, span,
"empty tuple structs and enum variants are unstable, \
use unit structs and enum variants instead");
}
}
visit::walk_struct_def(self, vdata)
}
fn visit_vis(&mut self, vis: &ast::Visibility) {
let span = match *vis {
ast::Visibility::Crate(span) => span,

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(relaxed_adts)]
pub struct XEmpty1 {}
pub struct XEmpty2;
pub struct XEmpty6();

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(item_like_imports, relaxed_adts)]
#![feature(item_like_imports)]
pub mod c {
pub struct S {}

View File

@ -10,8 +10,6 @@
// FIXME: Remove when `item_like_imports` is stabilized.
#![feature(relaxed_adts)]
pub mod c {
pub struct S {}
pub struct TS();

View File

@ -12,8 +12,6 @@
// aux-build:empty-struct.rs
#![feature(relaxed_adts)]
extern crate empty_struct;
use empty_struct::*;

View File

@ -12,8 +12,6 @@
// aux-build:empty-struct.rs
#![feature(relaxed_adts)]
extern crate empty_struct;
use empty_struct::*;

View File

@ -12,8 +12,6 @@
// aux-build:empty-struct.rs
#![feature(relaxed_adts)]
extern crate empty_struct;
use empty_struct::*;

View File

@ -12,8 +12,6 @@
// aux-build:empty-struct.rs
#![feature(relaxed_adts)]
extern crate empty_struct;
use empty_struct::*;

View File

@ -1,27 +0,0 @@
// Copyright 2016 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.
struct Z(u8, u8);
enum E {
U(u8, u8),
}
fn main() {
match Z(0, 1) {
Z{..} => {} //~ ERROR tuple structs and variants in struct patterns are unstable
}
match E::U(0, 1) {
E::U{..} => {} //~ ERROR tuple structs and variants in struct patterns are unstable
}
let z1 = Z(0, 1);
let z2 = Z { ..z1 }; //~ ERROR tuple structs and variants in struct patterns are unstable
}

View File

@ -1,26 +0,0 @@
// 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.
struct TS ( //~ ERROR empty tuple structs and enum variants are unstable
#[cfg(untrue)]
i32,
);
enum E {
TV ( //~ ERROR empty tuple structs and enum variants are unstable
#[cfg(untrue)]
i32,
)
}
fn main() {
let s = TS;
let tv = E::TV;
}

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(relaxed_adts)]
enum MyOption<T> {
MySome(T),
MyNone,

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(relaxed_adts)]
struct NonCopyable(());
fn main() {

View File

@ -10,7 +10,7 @@
// aux-build:namespace-mix-new.rs
#![feature(item_like_imports, relaxed_adts)]
#![feature(item_like_imports)]
extern crate namespace_mix_new;
use namespace_mix_new::*;

View File

@ -12,8 +12,6 @@
// aux-build:namespace-mix-old.rs
#![feature(relaxed_adts)]
extern crate namespace_mix_old;
use namespace_mix_old::{xm1, xm2, xm3, xm4, xm5, xm6, xm7, xm8, xm9, xmA, xmB, xmC};

View File

@ -8,19 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
struct S(); //~ ERROR empty tuple structs and enum variants are unstable
struct Z(u8, u8);
enum E {
V(), //~ ERROR empty tuple structs and enum variants are unstable
U(u8, u8),
}
struct S(u8);
fn main() {
match S() {
S() => {} //~ ERROR empty tuple structs patterns are unstable
}
match E::V() {
E::V() => {} //~ ERROR empty tuple structs patterns are unstable
let s = S{0: 10}; //~ ERROR numeric fields in struct expressions are unstable
match s {
S{0: a, ..} => {} //~ ERROR numeric fields in struct patterns are unstable
}
}

View File

@ -10,7 +10,6 @@
// `#[derive(Trait)]` works for empty structs/variants with braces or parens.
#![feature(relaxed_adts)]
#![feature(rustc_private)]
extern crate serialize as rustc_serialize;

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(relaxed_adts)]
pub struct XEmpty1 {}
pub struct XEmpty2;
pub struct XEmpty7();

View File

@ -13,8 +13,6 @@
// aux-build:empty-struct.rs
#![feature(relaxed_adts)]
extern crate empty_struct;
use empty_struct::*;