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