提交 8fe63e23 编写于 作者: A Aaron Turon

Add `default` as contextual keyword, and parse it for impl items.

上级 659ba09b
......@@ -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::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 @@ pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> bool {
}
}
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 @@ pub fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>)
}
}
/// 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 @@ pub fn parse_impl_item(&mut self) -> PResult<'a, ImplItem> {
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 @@ pub fn parse_impl_item(&mut self) -> PResult<'a, ImplItem> {
span: mk_sp(lo, self.last_span.hi),
ident: name,
vis: vis,
defaultness: defaultness,
attrs: attrs,
node: node
})
......@@ -5208,6 +5228,15 @@ fn parse_visibility(&mut self) -> PResult<'a, Visibility> {
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 @@ pub mod special_idents {
(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 @@ fn create_derived_impl(&self,
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 @@ fn create_method(&self,
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,
......
// 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() {}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册