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:
commit
f433209248
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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 {}
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
// FIXME: Remove when `item_like_imports` is stabilized.
|
||||
|
||||
#![feature(relaxed_adts)]
|
||||
|
||||
pub mod c {
|
||||
pub struct S {}
|
||||
pub struct TS();
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
// aux-build:empty-struct.rs
|
||||
|
||||
#![feature(relaxed_adts)]
|
||||
|
||||
extern crate empty_struct;
|
||||
use empty_struct::*;
|
||||
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
// aux-build:empty-struct.rs
|
||||
|
||||
#![feature(relaxed_adts)]
|
||||
|
||||
extern crate empty_struct;
|
||||
use empty_struct::*;
|
||||
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
// aux-build:empty-struct.rs
|
||||
|
||||
#![feature(relaxed_adts)]
|
||||
|
||||
extern crate empty_struct;
|
||||
use empty_struct::*;
|
||||
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
// aux-build:empty-struct.rs
|
||||
|
||||
#![feature(relaxed_adts)]
|
||||
|
||||
extern crate empty_struct;
|
||||
use empty_struct::*;
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -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;
|
||||
}
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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::*;
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -13,8 +13,6 @@
|
||||
|
||||
// aux-build:empty-struct.rs
|
||||
|
||||
#![feature(relaxed_adts)]
|
||||
|
||||
extern crate empty_struct;
|
||||
use empty_struct::*;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user