1
Fork 0

Auto merge of #54497 - ralexstokes:stabilize_pattern_parentheses, r=nikomatsakis

Stabilize pattern_parentheses feature

Addresses #51087 .

Stabilizes the previously unstable feature `pattern_parentheses` which enables the use of `()` in match patterns.
This commit is contained in:
bors 2018-09-26 07:38:19 +00:00
commit a2b27c19da
7 changed files with 197 additions and 161 deletions

View file

@ -10,27 +10,27 @@
// The Rust abstract syntax tree. // The Rust abstract syntax tree.
pub use self::UnsafeSource::*;
pub use self::GenericArgs::*; pub use self::GenericArgs::*;
pub use self::UnsafeSource::*;
pub use symbol::{Ident, Symbol as Name}; pub use symbol::{Ident, Symbol as Name};
pub use util::parser::ExprPrecedence; pub use util::parser::ExprPrecedence;
use syntax_pos::{Span, DUMMY_SP};
use source_map::{dummy_spanned, respan, Spanned};
use rustc_target::spec::abi::Abi;
use ext::hygiene::{Mark, SyntaxContext}; use ext::hygiene::{Mark, SyntaxContext};
use print::pprust; use print::pprust;
use ptr::P; use ptr::P;
use rustc_data_structures::indexed_vec; use rustc_data_structures::indexed_vec;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use symbol::{Symbol, keywords}; use rustc_target::spec::abi::Abi;
use ThinVec; use source_map::{dummy_spanned, respan, Spanned};
use symbol::{keywords, Symbol};
use syntax_pos::{Span, DUMMY_SP};
use tokenstream::{ThinTokenStream, TokenStream}; use tokenstream::{ThinTokenStream, TokenStream};
use ThinVec;
use serialize::{self, Encoder, Decoder};
use std::fmt;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use serialize::{self, Decoder, Encoder};
use std::fmt;
use std::u32; use std::u32;
pub use rustc_target::abi::FloatTy; pub use rustc_target::abi::FloatTy;
@ -54,7 +54,12 @@ pub struct Lifetime {
impl fmt::Debug for Lifetime { impl fmt::Debug for Lifetime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "lifetime({}: {})", self.id, pprust::lifetime_to_string(self)) write!(
f,
"lifetime({}: {})",
self.id,
pprust::lifetime_to_string(self)
)
} }
} }
@ -94,7 +99,10 @@ impl Path {
// convert a span and an identifier to the corresponding // convert a span and an identifier to the corresponding
// 1-segment path // 1-segment path
pub fn from_ident(ident: Ident) -> Path { pub fn from_ident(ident: Ident) -> Path {
Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span } Path {
segments: vec![PathSegment::from_ident(ident)],
span: ident.span,
}
} }
// Make a "crate root" segment for this path unless it already has it // Make a "crate root" segment for this path unless it already has it
@ -284,7 +292,7 @@ pub enum TraitBoundModifier {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum GenericBound { pub enum GenericBound {
Trait(PolyTraitRef, TraitBoundModifier), Trait(PolyTraitRef, TraitBoundModifier),
Outlives(Lifetime) Outlives(Lifetime),
} }
impl GenericBound { impl GenericBound {
@ -304,7 +312,7 @@ pub enum GenericParamKind {
Lifetime, Lifetime,
Type { Type {
default: Option<P<Ty>>, default: Option<P<Ty>>,
} },
} }
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@ -328,7 +336,7 @@ pub struct Generics {
impl Default for Generics { impl Default for Generics {
/// Creates an instance of `Generics`. /// Creates an instance of `Generics`.
fn default() -> Generics { fn default() -> Generics {
Generics { Generics {
params: Vec::new(), params: Vec::new(),
where_clause: WhereClause { where_clause: WhereClause {
@ -458,7 +466,7 @@ pub enum MetaItemKind {
/// Name value meta item. /// Name value meta item.
/// ///
/// E.g. `feature = "foo"` as in `#[feature = "foo"]` /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
NameValue(Lit) NameValue(Lit),
} }
/// A Block (`{ .. }`). /// A Block (`{ .. }`).
@ -492,14 +500,17 @@ impl Pat {
pub(super) fn to_ty(&self) -> Option<P<Ty>> { pub(super) fn to_ty(&self) -> Option<P<Ty>> {
let node = match &self.node { let node = match &self.node {
PatKind::Wild => TyKind::Infer, PatKind::Wild => TyKind::Infer,
PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None) => PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None) => {
TyKind::Path(None, Path::from_ident(*ident)), TyKind::Path(None, Path::from_ident(*ident))
}
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
PatKind::Mac(mac) => TyKind::Mac(mac.clone()), PatKind::Mac(mac) => TyKind::Mac(mac.clone()),
PatKind::Ref(pat, mutbl) => PatKind::Ref(pat, mutbl) => pat
pat.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?, .to_ty()
PatKind::Slice(pats, None, _) if pats.len() == 1 => .map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?,
pats[0].to_ty().map(TyKind::Slice)?, PatKind::Slice(pats, None, _) if pats.len() == 1 => {
pats[0].to_ty().map(TyKind::Slice)?
}
PatKind::Tuple(pats, None) => { PatKind::Tuple(pats, None) => {
let mut tys = Vec::with_capacity(pats.len()); let mut tys = Vec::with_capacity(pats.len());
// FIXME(#48994) - could just be collected into an Option<Vec> // FIXME(#48994) - could just be collected into an Option<Vec>
@ -511,11 +522,16 @@ impl Pat {
_ => return None, _ => return None,
}; };
Some(P(Ty { node, id: self.id, span: self.span })) Some(P(Ty {
node,
id: self.id,
span: self.span,
}))
} }
pub fn walk<F>(&self, it: &mut F) -> bool pub fn walk<F>(&self, it: &mut F) -> bool
where F: FnMut(&Pat) -> bool where
F: FnMut(&Pat) -> bool,
{ {
if !it(self) { if !it(self) {
return false; return false;
@ -523,28 +539,22 @@ impl Pat {
match self.node { match self.node {
PatKind::Ident(_, _, Some(ref p)) => p.walk(it), PatKind::Ident(_, _, Some(ref p)) => p.walk(it),
PatKind::Struct(_, ref fields, _) => { PatKind::Struct(_, ref fields, _) => fields.iter().all(|field| field.node.pat.walk(it)),
fields.iter().all(|field| field.node.pat.walk(it))
}
PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => { PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => {
s.iter().all(|p| p.walk(it)) s.iter().all(|p| p.walk(it))
} }
PatKind::Box(ref s) | PatKind::Ref(ref s, _) | PatKind::Paren(ref s) => { PatKind::Box(ref s) | PatKind::Ref(ref s, _) | PatKind::Paren(ref s) => s.walk(it),
s.walk(it)
}
PatKind::Slice(ref before, ref slice, ref after) => { PatKind::Slice(ref before, ref slice, ref after) => {
before.iter().all(|p| p.walk(it)) && before.iter().all(|p| p.walk(it))
slice.iter().all(|p| p.walk(it)) && && slice.iter().all(|p| p.walk(it))
after.iter().all(|p| p.walk(it)) && after.iter().all(|p| p.walk(it))
}
PatKind::Wild |
PatKind::Lit(_) |
PatKind::Range(..) |
PatKind::Ident(..) |
PatKind::Path(..) |
PatKind::Mac(_) => {
true
} }
PatKind::Wild
| PatKind::Lit(_)
| PatKind::Range(..)
| PatKind::Ident(..)
| PatKind::Path(..)
| PatKind::Mac(_) => true,
} }
} }
} }
@ -623,13 +633,15 @@ pub enum PatKind {
/// `[a, b, ..i, y, z]` is represented as: /// `[a, b, ..i, y, z]` is represented as:
/// `PatKind::Slice(box [a, b], Some(i), box [y, z])` /// `PatKind::Slice(box [a, b], Some(i), box [y, z])`
Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>), Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
/// Parentheses in patters used for grouping, i.e. `(PAT)`. /// Parentheses in patterns used for grouping, i.e. `(PAT)`.
Paren(P<Pat>), Paren(P<Pat>),
/// A macro pattern; pre-expansion /// A macro pattern; pre-expansion
Mac(Mac), Mac(Mac),
} }
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug, Copy)] #[derive(
Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug, Copy,
)]
pub enum Mutability { pub enum Mutability {
Mutable, Mutable,
Immutable, Immutable,
@ -702,25 +714,22 @@ impl BinOpKind {
pub fn lazy(&self) -> bool { pub fn lazy(&self) -> bool {
match *self { match *self {
BinOpKind::And | BinOpKind::Or => true, BinOpKind::And | BinOpKind::Or => true,
_ => false _ => false,
} }
} }
pub fn is_shift(&self) -> bool { pub fn is_shift(&self) -> bool {
match *self { match *self {
BinOpKind::Shl | BinOpKind::Shr => true, BinOpKind::Shl | BinOpKind::Shr => true,
_ => false _ => false,
} }
} }
pub fn is_comparison(&self) -> bool { pub fn is_comparison(&self) -> bool {
use self::BinOpKind::*; use self::BinOpKind::*;
match *self { match *self {
Eq | Lt | Le | Ne | Gt | Ge => Eq | Lt | Le | Ne | Gt | Ge => true,
true, And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
And | Or | Add | Sub | Mul | Div | Rem |
BitXor | BitAnd | BitOr | Shl | Shr =>
false,
} }
} }
@ -772,9 +781,9 @@ impl Stmt {
pub fn add_trailing_semicolon(mut self) -> Self { pub fn add_trailing_semicolon(mut self) -> Self {
self.node = match self.node { self.node = match self.node {
StmtKind::Expr(expr) => StmtKind::Semi(expr), StmtKind::Expr(expr) => StmtKind::Semi(expr),
StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, _style, attrs)| { StmtKind::Mac(mac) => {
(mac, MacStmtStyle::Semicolon, attrs) StmtKind::Mac(mac.map(|(mac, _style, attrs)| (mac, MacStmtStyle::Semicolon, attrs)))
})), }
node => node, node => node,
}; };
self self
@ -797,11 +806,15 @@ impl Stmt {
impl fmt::Debug for Stmt { impl fmt::Debug for Stmt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "stmt({}: {})", self.id.to_string(), pprust::stmt_to_string(self)) write!(
f,
"stmt({}: {})",
self.id.to_string(),
pprust::stmt_to_string(self)
)
} }
} }
#[derive(Clone, RustcEncodable, RustcDecodable)] #[derive(Clone, RustcEncodable, RustcDecodable)]
pub enum StmtKind { pub enum StmtKind {
/// A local (let) binding. /// A local (let) binding.
@ -900,14 +913,13 @@ pub struct AnonConst {
pub value: P<Expr>, pub value: P<Expr>,
} }
/// An expression /// An expression
#[derive(Clone, RustcEncodable, RustcDecodable)] #[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct Expr { pub struct Expr {
pub id: NodeId, pub id: NodeId,
pub node: ExprKind, pub node: ExprKind,
pub span: Span, pub span: Span,
pub attrs: ThinVec<Attribute> pub attrs: ThinVec<Attribute>,
} }
impl Expr { impl Expr {
@ -937,9 +949,10 @@ impl Expr {
fn to_bound(&self) -> Option<GenericBound> { fn to_bound(&self) -> Option<GenericBound> {
match &self.node { match &self.node {
ExprKind::Path(None, path) => ExprKind::Path(None, path) => Some(GenericBound::Trait(
Some(GenericBound::Trait(PolyTraitRef::new(Vec::new(), path.clone(), self.span), PolyTraitRef::new(Vec::new(), path.clone(), self.span),
TraitBoundModifier::None)), TraitBoundModifier::None,
)),
_ => None, _ => None,
} }
} }
@ -949,26 +962,35 @@ impl Expr {
ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
ExprKind::Mac(mac) => TyKind::Mac(mac.clone()), ExprKind::Mac(mac) => TyKind::Mac(mac.clone()),
ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?, ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
ExprKind::AddrOf(mutbl, expr) => ExprKind::AddrOf(mutbl, expr) => expr
expr.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?, .to_ty()
ExprKind::Repeat(expr, expr_len) => .map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?,
expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?, ExprKind::Repeat(expr, expr_len) => {
ExprKind::Array(exprs) if exprs.len() == 1 => expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
exprs[0].to_ty().map(TyKind::Slice)?, }
ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?,
ExprKind::Tup(exprs) => { ExprKind::Tup(exprs) => {
let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<Vec<_>>>()?; let tys = exprs
.iter()
.map(|expr| expr.to_ty())
.collect::<Option<Vec<_>>>()?;
TyKind::Tup(tys) TyKind::Tup(tys)
} }
ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) { if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None) TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
} else { } else {
return None; return None;
} }
}
_ => return None, _ => return None,
}; };
Some(P(Ty { node, id: self.id, span: self.span })) Some(P(Ty {
node,
id: self.id,
span: self.span,
}))
} }
pub fn precedence(&self) -> ExprPrecedence { pub fn precedence(&self) -> ExprPrecedence {
@ -1195,7 +1217,7 @@ pub struct QSelf {
/// a::b::Trait>::AssociatedItem`; in the case where `position == /// a::b::Trait>::AssociatedItem`; in the case where `position ==
/// 0`, this is an empty span. /// 0`, this is an empty span.
pub path_span: Span, pub path_span: Span,
pub position: usize pub position: usize,
} }
/// A capture clause /// A capture clause
@ -1259,7 +1281,7 @@ pub enum StrStyle {
/// A raw string, like `r##"foo"##` /// A raw string, like `r##"foo"##`
/// ///
/// The value is the number of `#` symbols used. /// The value is the number of `#` symbols used.
Raw(u16) Raw(u16),
} }
/// A literal /// A literal
@ -1307,9 +1329,7 @@ impl LitKind {
/// Returns true if this is a numeric literal. /// Returns true if this is a numeric literal.
pub fn is_numeric(&self) -> bool { pub fn is_numeric(&self) -> bool {
match *self { match *self {
LitKind::Int(..) | LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => true,
LitKind::Float(..) |
LitKind::FloatUnsuffixed(..) => true,
_ => false, _ => false,
} }
} }
@ -1319,17 +1339,17 @@ impl LitKind {
pub fn is_unsuffixed(&self) -> bool { pub fn is_unsuffixed(&self) -> bool {
match *self { match *self {
// unsuffixed variants // unsuffixed variants
LitKind::Str(..) | LitKind::Str(..)
LitKind::ByteStr(..) | | LitKind::ByteStr(..)
LitKind::Byte(..) | | LitKind::Byte(..)
LitKind::Char(..) | | LitKind::Char(..)
LitKind::Int(_, LitIntType::Unsuffixed) | | LitKind::Int(_, LitIntType::Unsuffixed)
LitKind::FloatUnsuffixed(..) | | LitKind::FloatUnsuffixed(..)
LitKind::Bool(..) => true, | LitKind::Bool(..) => true,
// suffixed variants // suffixed variants
LitKind::Int(_, LitIntType::Signed(..)) | LitKind::Int(_, LitIntType::Signed(..))
LitKind::Int(_, LitIntType::Unsigned(..)) | | LitKind::Int(_, LitIntType::Unsigned(..))
LitKind::Float(..) => false, | LitKind::Float(..) => false,
} }
} }
@ -1532,7 +1552,7 @@ pub struct BareFnTy {
pub unsafety: Unsafety, pub unsafety: Unsafety,
pub abi: Abi, pub abi: Abi,
pub generic_params: Vec<GenericParam>, pub generic_params: Vec<GenericParam>,
pub decl: P<FnDecl> pub decl: P<FnDecl>,
} }
/// The different kinds of types recognized by the compiler /// The different kinds of types recognized by the compiler
@ -1551,7 +1571,7 @@ pub enum TyKind {
/// The never type (`!`) /// The never type (`!`)
Never, Never,
/// A tuple (`(A, B, C, D,...)`) /// A tuple (`(A, B, C, D,...)`)
Tup(Vec<P<Ty>> ), Tup(Vec<P<Ty>>),
/// A path (`module::module::...::Type`), optionally /// A path (`module::module::...::Type`), optionally
/// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`. /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
/// ///
@ -1584,11 +1604,19 @@ pub enum TyKind {
impl TyKind { impl TyKind {
pub fn is_implicit_self(&self) -> bool { pub fn is_implicit_self(&self) -> bool {
if let TyKind::ImplicitSelf = *self { true } else { false } if let TyKind::ImplicitSelf = *self {
true
} else {
false
}
} }
pub fn is_unit(&self) -> bool { pub fn is_unit(&self) -> bool {
if let TyKind::Tup(ref tys) = *self { tys.is_empty() } else { false } if let TyKind::Tup(ref tys) = *self {
tys.is_empty()
} else {
false
}
} }
} }
@ -1666,12 +1694,14 @@ impl Arg {
if ident.name == keywords::SelfValue.name() { if ident.name == keywords::SelfValue.name() {
return match self.ty.node { return match self.ty.node {
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node.is_implicit_self() => { TyKind::Rptr(lt, MutTy { ref ty, mutbl }) if ty.node.is_implicit_self() => {
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
} }
_ => Some(respan(self.pat.span.to(self.ty.span), _ => Some(respan(
SelfKind::Explicit(self.ty.clone(), mutbl))), self.pat.span.to(self.ty.span),
} SelfKind::Explicit(self.ty.clone(), mutbl),
)),
};
} }
} }
None None
@ -1704,11 +1734,20 @@ impl Arg {
match eself.node { match eself.node {
SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty), SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),
SelfKind::Value(mutbl) => arg(mutbl, infer_ty), SelfKind::Value(mutbl) => arg(mutbl, infer_ty),
SelfKind::Region(lt, mutbl) => arg(Mutability::Immutable, P(Ty { SelfKind::Region(lt, mutbl) => arg(
id: DUMMY_NODE_ID, Mutability::Immutable,
node: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl: mutbl }), P(Ty {
span, id: DUMMY_NODE_ID,
})), node: TyKind::Rptr(
lt,
MutTy {
ty: infer_ty,
mutbl: mutbl,
},
),
span,
}),
),
} }
} }
} }
@ -1720,7 +1759,7 @@ impl Arg {
pub struct FnDecl { pub struct FnDecl {
pub inputs: Vec<Arg>, pub inputs: Vec<Arg>,
pub output: FunctionRetTy, pub output: FunctionRetTy,
pub variadic: bool pub variadic: bool,
} }
impl FnDecl { impl FnDecl {
@ -1736,7 +1775,7 @@ impl FnDecl {
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
pub enum IsAuto { pub enum IsAuto {
Yes, Yes,
No No,
} }
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)] #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
@ -1765,7 +1804,10 @@ impl IsAsync {
/// In case this is an `Async` return the `NodeId` for the generated impl Trait item /// In case this is an `Async` return the `NodeId` for the generated impl Trait item
pub fn opt_return_id(self) -> Option<NodeId> { pub fn opt_return_id(self) -> Option<NodeId> {
match self { match self {
IsAsync::Async { return_impl_trait_id, .. } => Some(return_impl_trait_id), IsAsync::Async {
return_impl_trait_id,
..
} => Some(return_impl_trait_id),
IsAsync::NotAsync => None, IsAsync::NotAsync => None,
} }
} }
@ -1785,10 +1827,13 @@ pub enum Defaultness {
impl fmt::Display for Unsafety { impl fmt::Display for Unsafety {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(match *self { fmt::Display::fmt(
Unsafety::Normal => "normal", match *self {
Unsafety::Unsafe => "unsafe", Unsafety::Normal => "normal",
}, f) Unsafety::Unsafe => "unsafe",
},
f,
)
} }
} }
@ -1809,7 +1854,6 @@ impl fmt::Debug for ImplPolarity {
} }
} }
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum FunctionRetTy { pub enum FunctionRetTy {
/// Return type is not specified. /// Return type is not specified.
@ -1904,8 +1948,13 @@ impl UseTree {
pub fn ident(&self) -> Ident { pub fn ident(&self) -> Ident {
match self.kind { match self.kind {
UseTreeKind::Simple(Some(rename), ..) => rename, UseTreeKind::Simple(Some(rename), ..) => rename,
UseTreeKind::Simple(None, ..) => UseTreeKind::Simple(None, ..) => {
self.prefix.segments.last().expect("empty prefix in a simple import").ident, self.prefix
.segments
.last()
.expect("empty prefix in a simple import")
.ident
}
_ => panic!("`UseTree::ident` can only be used on a simple import"), _ => panic!("`UseTree::ident` can only be used on a simple import"),
} }
} }
@ -1920,7 +1969,9 @@ pub enum AttrStyle {
Inner, Inner,
} }
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialOrd, Ord, Copy)] #[derive(
Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialOrd, Ord, Copy,
)]
pub struct AttrId(pub usize); pub struct AttrId(pub usize);
impl Idx for AttrId { impl Idx for AttrId {
@ -1971,7 +2022,10 @@ impl PolyTraitRef {
pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self { pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self {
PolyTraitRef { PolyTraitRef {
bound_generic_params: generic_params, bound_generic_params: generic_params,
trait_ref: TraitRef { path: path, ref_id: DUMMY_NODE_ID }, trait_ref: TraitRef {
path: path,
ref_id: DUMMY_NODE_ID,
},
span, span,
} }
} }
@ -1998,7 +2052,11 @@ pub enum VisibilityKind {
impl VisibilityKind { impl VisibilityKind {
pub fn is_pub(&self) -> bool { pub fn is_pub(&self) -> bool {
if let VisibilityKind::Public = *self { true } else { false } if let VisibilityKind::Public = *self {
true
} else {
false
}
} }
} }
@ -2051,17 +2109,29 @@ impl VariantData {
} }
pub fn id(&self) -> NodeId { pub fn id(&self) -> NodeId {
match *self { match *self {
VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
} }
} }
pub fn is_struct(&self) -> bool { pub fn is_struct(&self) -> bool {
if let VariantData::Struct(..) = *self { true } else { false } if let VariantData::Struct(..) = *self {
true
} else {
false
}
} }
pub fn is_tuple(&self) -> bool { pub fn is_tuple(&self) -> bool {
if let VariantData::Tuple(..) = *self { true } else { false } if let VariantData::Tuple(..) = *self {
true
} else {
false
}
} }
pub fn is_unit(&self) -> bool { pub fn is_unit(&self) -> bool {
if let VariantData::Unit(..) = *self { true } else { false } if let VariantData::Unit(..) = *self {
true
} else {
false
}
} }
} }
@ -2173,13 +2243,15 @@ pub enum ItemKind {
/// An implementation. /// An implementation.
/// ///
/// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }` /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
Impl(Unsafety, Impl(
ImplPolarity, Unsafety,
Defaultness, ImplPolarity,
Generics, Defaultness,
Option<TraitRef>, // (optional) trait this impl implements Generics,
P<Ty>, // self Option<TraitRef>, // (optional) trait this impl implements
Vec<ImplItem>), P<Ty>, // self
Vec<ImplItem>,
),
/// A macro invocation. /// A macro invocation.
/// ///
/// E.g. `macro_rules! foo { .. }` or `foo!(..)` /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
@ -2207,9 +2279,7 @@ impl ItemKind {
ItemKind::Union(..) => "union", ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait", ItemKind::Trait(..) => "trait",
ItemKind::TraitAlias(..) => "trait alias", ItemKind::TraitAlias(..) => "trait alias",
ItemKind::Mac(..) | ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl(..) => "item",
ItemKind::MacroDef(..) |
ItemKind::Impl(..) => "item"
} }
} }
} }
@ -2251,8 +2321,8 @@ impl ForeignItemKind {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serialize;
use super::*; use super::*;
use serialize;
// are ASTs encodable? // are ASTs encodable?
#[test] #[test]

View file

@ -415,9 +415,6 @@ declare_features! (
// Multiple patterns with `|` in `if let` and `while let` // Multiple patterns with `|` in `if let` and `while let`
(active, if_while_or_patterns, "1.26.0", Some(48215), None), (active, if_while_or_patterns, "1.26.0", Some(48215), None),
// Parentheses in patterns
(active, pattern_parentheses, "1.26.0", Some(51087), None),
// Allows `#[repr(packed)]` attribute on structs // Allows `#[repr(packed)]` attribute on structs
(active, repr_packed, "1.26.0", Some(33158), None), (active, repr_packed, "1.26.0", Some(33158), None),
@ -686,6 +683,8 @@ declare_features! (
(accepted, extern_absolute_paths, "1.30.0", Some(44660), None), (accepted, extern_absolute_paths, "1.30.0", Some(44660), None),
// Access to crate names passed via `--extern` through prelude // Access to crate names passed via `--extern` through prelude
(accepted, extern_prelude, "1.30.0", Some(44660), None), (accepted, extern_prelude, "1.30.0", Some(44660), None),
// Parentheses in patterns
(accepted, pattern_parentheses, "1.31.0", Some(51087), None),
); );
// If you change this, please modify src/doc/unstable-book as well. You must // If you change this, please modify src/doc/unstable-book as well. You must
@ -1791,10 +1790,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, exclusive_range_pattern, pattern.span, gate_feature_post!(&self, exclusive_range_pattern, pattern.span,
"exclusive range pattern syntax is experimental"); "exclusive range pattern syntax is experimental");
} }
PatKind::Paren(..) => {
gate_feature_post!(&self, pattern_parentheses, pattern.span,
"parentheses in patterns are unstable");
}
_ => {} _ => {}
} }
visit::walk_pat(self, pattern) visit::walk_pat(self, pattern)

View file

@ -284,9 +284,7 @@ fn run() {
reject_stmt_parse("#[attr] #![attr] foo!{}"); reject_stmt_parse("#[attr] #![attr] foo!{}");
// FIXME: Allow attributes in pattern constexprs? // FIXME: Allow attributes in pattern constexprs?
// would require parens in patterns to allow disambiguation... // note: requires parens in patterns to allow disambiguation
// —which is now available under the `pattern_parentheses` feature gate
// (tracking issue #51087)
reject_expr_parse("match 0 { reject_expr_parse("match 0 {
0..=#[attr] 10 => () 0..=#[attr] 10 => ()

View file

@ -1,15 +0,0 @@
// Copyright 2017 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.
fn main() {
match 0 {
(pat) => {} //~ ERROR parentheses in patterns are unstable
}
}

View file

@ -1,11 +0,0 @@
error[E0658]: parentheses in patterns are unstable (see issue #51087)
--> $DIR/feature-gate-pattern_parentheses.rs:13:9
|
LL | (pat) => {} //~ ERROR parentheses in patterns are unstable
| ^^^^^
|
= help: add #![feature(pattern_parentheses)] to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
// run-pass // run-pass
#![feature(pattern_parentheses)]
fn main() { fn main() {
match 0 { match 0 {

View file

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
// run-pass // run-pass
#![feature(box_patterns, pattern_parentheses)] #![feature(box_patterns)]
const VALUE: usize = 21; const VALUE: usize = 21;