Add default
as contextual keyword, and parse it for impl items.
This commit is contained in:
parent
659ba09b2d
commit
8fe63e2342
src
librustc_front
libsyntax
libsyntax_ext/deriving/generic
test/parse-fail
@ -839,6 +839,7 @@ pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T) -> ImplItem {
|
||||
name: folder.fold_name(i.name),
|
||||
attrs: fold_attrs(i.attrs, folder),
|
||||
vis: i.vis,
|
||||
defaultness: i.defaultness,
|
||||
node: match i.node {
|
||||
ImplItemKind::Const(ty, expr) => {
|
||||
ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr))
|
||||
|
@ -864,10 +864,10 @@ pub struct MethodSig {
|
||||
pub explicit_self: ExplicitSelf,
|
||||
}
|
||||
|
||||
/// Represents a method declaration in a trait declaration, possibly including
|
||||
/// a default implementation A trait method is either required (meaning it
|
||||
/// doesn't have an implementation, just a signature) or provided (meaning it
|
||||
/// has a default implementation).
|
||||
/// Represents an item declaration within a trait declaration,
|
||||
/// possibly including a default implementation. A trait item is
|
||||
/// either required (meaning it doesn't have an implementation, just a
|
||||
/// signature) or provided (meaning it has a default implementation).
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct TraitItem {
|
||||
pub id: NodeId,
|
||||
@ -889,6 +889,7 @@ pub struct ImplItem {
|
||||
pub id: NodeId,
|
||||
pub name: Name,
|
||||
pub vis: Visibility,
|
||||
pub defaultness: Defaultness,
|
||||
pub attrs: HirVec<Attribute>,
|
||||
pub node: ImplItemKind,
|
||||
pub span: Span,
|
||||
@ -1046,6 +1047,12 @@ pub enum Constness {
|
||||
NotConst,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum Defaultness {
|
||||
Default,
|
||||
Final,
|
||||
}
|
||||
|
||||
impl fmt::Display for Unsafety {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(match *self {
|
||||
|
@ -756,6 +756,7 @@ pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem {
|
||||
name: i.ident.name,
|
||||
attrs: lower_attrs(lctx, &i.attrs),
|
||||
vis: lower_visibility(lctx, i.vis),
|
||||
defaultness: lower_defaultness(lctx, i.defaultness),
|
||||
node: match i.node {
|
||||
ImplItemKind::Const(ref ty, ref expr) => {
|
||||
hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr))
|
||||
@ -1707,6 +1708,13 @@ pub fn lower_visibility(_lctx: &LoweringContext, v: Visibility) -> hir::Visibili
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lower_defaultness(_lctx: &LoweringContext, d: Defaultness) -> hir::Defaultness {
|
||||
match d {
|
||||
Defaultness::Default => hir::Defaultness::Default,
|
||||
Defaultness::Final => hir::Defaultness::Final,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lower_block_check_mode(lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode {
|
||||
match *b {
|
||||
BlockCheckMode::Default => hir::DefaultBlock,
|
||||
|
@ -1328,10 +1328,10 @@ pub struct MethodSig {
|
||||
pub explicit_self: ExplicitSelf,
|
||||
}
|
||||
|
||||
/// Represents a method declaration in a trait declaration, possibly including
|
||||
/// a default implementation. A trait method is either required (meaning it
|
||||
/// doesn't have an implementation, just a signature) or provided (meaning it
|
||||
/// has a default implementation).
|
||||
/// Represents an item declaration within a trait declaration,
|
||||
/// possibly including a default implementation. A trait item is
|
||||
/// either required (meaning it doesn't have an implementation, just a
|
||||
/// signature) or provided (meaning it has a default implementation).
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct TraitItem {
|
||||
pub id: NodeId,
|
||||
@ -1353,6 +1353,7 @@ pub struct ImplItem {
|
||||
pub id: NodeId,
|
||||
pub ident: Ident,
|
||||
pub vis: Visibility,
|
||||
pub defaultness: Defaultness,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub node: ImplItemKind,
|
||||
pub span: Span,
|
||||
@ -1654,6 +1655,12 @@ pub enum Constness {
|
||||
NotConst,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum Defaultness {
|
||||
Default,
|
||||
Final,
|
||||
}
|
||||
|
||||
impl fmt::Display for Unsafety {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(match *self {
|
||||
|
@ -1061,6 +1061,7 @@ fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander)
|
||||
ident: ii.ident,
|
||||
attrs: ii.attrs,
|
||||
vis: ii.vis,
|
||||
defaultness: ii.defaultness,
|
||||
node: match ii.node {
|
||||
ast::ImplItemKind::Method(sig, body) => {
|
||||
let (sig, body) = expand_and_rename_method(sig, body, fld);
|
||||
|
@ -993,6 +993,7 @@ pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T)
|
||||
ident: folder.fold_ident(i.ident),
|
||||
attrs: fold_attrs(i.attrs, folder),
|
||||
vis: i.vis,
|
||||
defaultness: i.defaultness,
|
||||
node: match i.node {
|
||||
ast::ImplItemKind::Const(ty, expr) => {
|
||||
ast::ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr))
|
||||
|
@ -18,7 +18,7 @@ use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind};
|
||||
use ast::Block;
|
||||
use ast::{BlockCheckMode, CaptureBy};
|
||||
use ast::{Constness, Crate, CrateConfig};
|
||||
use ast::{Decl, DeclKind};
|
||||
use ast::{Decl, DeclKind, Defaultness};
|
||||
use ast::{EMPTY_CTXT, EnumDef, ExplicitSelf};
|
||||
use ast::{Expr, ExprKind, RangeLimits};
|
||||
use ast::{Field, FnDecl};
|
||||
@ -644,6 +644,25 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_contextual_keyword(&mut self, ident: Ident) -> bool {
|
||||
let tok = token::Ident(ident, token::Plain);
|
||||
self.expected_tokens.push(TokenType::Token(tok));
|
||||
if let token::Ident(ref cur_ident, _) = self.token {
|
||||
cur_ident.name == ident.name
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eat_contextual_keyword(&mut self, ident: Ident) -> PResult<bool> {
|
||||
if self.check_contextual_keyword(ident) {
|
||||
try!(self.bump());
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
/// If the given word is not a keyword, signal an error.
|
||||
/// If the next token is not the given word, signal an error.
|
||||
/// Otherwise, eat it.
|
||||
@ -705,7 +724,6 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Attempt to consume a `<`. If `<<` is seen, replace it with a single
|
||||
/// `<` and continue. If a `<` is not seen, return false.
|
||||
///
|
||||
@ -4846,6 +4864,7 @@ impl<'a> Parser<'a> {
|
||||
let mut attrs = try!(self.parse_outer_attributes());
|
||||
let lo = self.span.lo;
|
||||
let vis = try!(self.parse_visibility());
|
||||
let defaultness = try!(self.parse_defaultness());
|
||||
let (name, node) = if self.eat_keyword(keywords::Type) {
|
||||
let name = try!(self.parse_ident());
|
||||
try!(self.expect(&token::Eq));
|
||||
@ -4872,6 +4891,7 @@ impl<'a> Parser<'a> {
|
||||
span: mk_sp(lo, self.last_span.hi),
|
||||
ident: name,
|
||||
vis: vis,
|
||||
defaultness: defaultness,
|
||||
attrs: attrs,
|
||||
node: node
|
||||
})
|
||||
@ -5208,6 +5228,15 @@ impl<'a> Parser<'a> {
|
||||
else { Ok(Visibility::Inherited) }
|
||||
}
|
||||
|
||||
/// Parse defaultness: DEFAULT or nothing
|
||||
fn parse_defaultness(&mut self) -> PResult<Defaultness> {
|
||||
if try!(self.eat_contextual_keyword(special_idents::DEFAULT)) {
|
||||
Ok(Defaultness::Default)
|
||||
} else {
|
||||
Ok(Defaultness::Final)
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a termination token, parse all of the items in a module
|
||||
fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> PResult<'a, Mod> {
|
||||
let mut items = vec![];
|
||||
|
@ -545,66 +545,67 @@ declare_special_idents_and_keywords! {
|
||||
(9, __unused1, "<__unused1>");
|
||||
(super::SELF_TYPE_KEYWORD_NAME_NUM, type_self, "Self");
|
||||
(11, prelude_import, "prelude_import");
|
||||
(12, DEFAULT, "default");
|
||||
}
|
||||
|
||||
pub mod keywords {
|
||||
// These ones are variants of the Keyword enum
|
||||
|
||||
'strict:
|
||||
(12, As, "as");
|
||||
(13, Break, "break");
|
||||
(14, Crate, "crate");
|
||||
(15, Else, "else");
|
||||
(16, Enum, "enum");
|
||||
(17, Extern, "extern");
|
||||
(18, False, "false");
|
||||
(19, Fn, "fn");
|
||||
(20, For, "for");
|
||||
(21, If, "if");
|
||||
(22, Impl, "impl");
|
||||
(23, In, "in");
|
||||
(24, Let, "let");
|
||||
(25, Loop, "loop");
|
||||
(26, Match, "match");
|
||||
(27, Mod, "mod");
|
||||
(28, Move, "move");
|
||||
(29, Mut, "mut");
|
||||
(30, Pub, "pub");
|
||||
(31, Ref, "ref");
|
||||
(32, Return, "return");
|
||||
(13, As, "as");
|
||||
(14, Break, "break");
|
||||
(15, Crate, "crate");
|
||||
(16, Else, "else");
|
||||
(17, Enum, "enum");
|
||||
(18, Extern, "extern");
|
||||
(19, False, "false");
|
||||
(20, Fn, "fn");
|
||||
(21, For, "for");
|
||||
(22, If, "if");
|
||||
(23, Impl, "impl");
|
||||
(24, In, "in");
|
||||
(25, Let, "let");
|
||||
(26, Loop, "loop");
|
||||
(27, Match, "match");
|
||||
(28, Mod, "mod");
|
||||
(29, Move, "move");
|
||||
(30, Mut, "mut");
|
||||
(31, Pub, "pub");
|
||||
(32, Ref, "ref");
|
||||
(33, Return, "return");
|
||||
// Static and Self are also special idents (prefill de-dupes)
|
||||
(super::STATIC_KEYWORD_NAME_NUM, Static, "static");
|
||||
(super::SELF_KEYWORD_NAME_NUM, SelfValue, "self");
|
||||
(super::SELF_TYPE_KEYWORD_NAME_NUM, SelfType, "Self");
|
||||
(33, Struct, "struct");
|
||||
(34, Struct, "struct");
|
||||
(super::SUPER_KEYWORD_NAME_NUM, Super, "super");
|
||||
(34, True, "true");
|
||||
(35, Trait, "trait");
|
||||
(36, Type, "type");
|
||||
(37, Unsafe, "unsafe");
|
||||
(38, Use, "use");
|
||||
(39, While, "while");
|
||||
(40, Continue, "continue");
|
||||
(41, Box, "box");
|
||||
(42, Const, "const");
|
||||
(43, Where, "where");
|
||||
(35, True, "true");
|
||||
(36, Trait, "trait");
|
||||
(37, Type, "type");
|
||||
(38, Unsafe, "unsafe");
|
||||
(39, Use, "use");
|
||||
(40, While, "while");
|
||||
(41, Continue, "continue");
|
||||
(42, Box, "box");
|
||||
(43, Const, "const");
|
||||
(44, Where, "where");
|
||||
'reserved:
|
||||
(44, Virtual, "virtual");
|
||||
(45, Proc, "proc");
|
||||
(46, Alignof, "alignof");
|
||||
(47, Become, "become");
|
||||
(48, Offsetof, "offsetof");
|
||||
(49, Priv, "priv");
|
||||
(50, Pure, "pure");
|
||||
(51, Sizeof, "sizeof");
|
||||
(52, Typeof, "typeof");
|
||||
(53, Unsized, "unsized");
|
||||
(54, Yield, "yield");
|
||||
(55, Do, "do");
|
||||
(56, Abstract, "abstract");
|
||||
(57, Final, "final");
|
||||
(58, Override, "override");
|
||||
(59, Macro, "macro");
|
||||
(45, Virtual, "virtual");
|
||||
(46, Proc, "proc");
|
||||
(47, Alignof, "alignof");
|
||||
(48, Become, "become");
|
||||
(49, Offsetof, "offsetof");
|
||||
(50, Priv, "priv");
|
||||
(51, Pure, "pure");
|
||||
(52, Sizeof, "sizeof");
|
||||
(53, Typeof, "typeof");
|
||||
(54, Unsized, "unsized");
|
||||
(55, Yield, "yield");
|
||||
(56, Do, "do");
|
||||
(57, Abstract, "abstract");
|
||||
(58, Final, "final");
|
||||
(59, Override, "override");
|
||||
(60, Macro, "macro");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,6 +476,7 @@ impl<'a> TraitDef<'a> {
|
||||
span: self.span,
|
||||
ident: ident,
|
||||
vis: ast::Visibility::Inherited,
|
||||
defaultness: ast::Defaultness::Final,
|
||||
attrs: Vec::new(),
|
||||
node: ast::ImplItemKind::Type(type_def.to_ty(cx,
|
||||
self.span,
|
||||
@ -893,6 +894,7 @@ impl<'a> MethodDef<'a> {
|
||||
attrs: self.attributes.clone(),
|
||||
span: trait_.span,
|
||||
vis: ast::Visibility::Inherited,
|
||||
defaultness: ast::Defaultness::Final,
|
||||
ident: method_ident,
|
||||
node: ast::ImplItemKind::Method(ast::MethodSig {
|
||||
generics: fn_generics,
|
||||
|
35
src/test/parse-fail/default.rs
Normal file
35
src/test/parse-fail/default.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
// compile-flags: -Z parse-only
|
||||
|
||||
// Test successful and unsucessful parsing of the `default` contextual keyword
|
||||
|
||||
trait Foo {
|
||||
fn foo<T: Default>() -> T;
|
||||
}
|
||||
|
||||
impl Foo for u8 {
|
||||
default fn foo<T: Default>() -> T {
|
||||
T::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Foo for u16 {
|
||||
pub default fn foo<T: Default>() -> T {
|
||||
T::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Foo for u32 {
|
||||
default pub fn foo<T: Default>() -> T { T::default() } //~ ERROR expected one of
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user