auto merge of #8718 : bblum/rust/typeof, r=pcwalton

r? anybody
This commit is contained in:
bors 2013-08-28 15:30:38 -07:00
commit 7971c46c44
11 changed files with 78 additions and 4 deletions

View File

@ -33,7 +33,7 @@ syn match rustIdentifier contains=rustIdentifierPrime "\%([^[:cntrl:][:spac
syn match rustFuncName "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
" reserved
syn keyword rustKeyword be
syn keyword rustKeyword be yield typeof
syn keyword rustType int uint float char bool u8 u16 u32 u64 f32
syn keyword rustType f64 i8 i16 i32 i64 str Self

View File

@ -517,6 +517,9 @@ fn check_path_args(tcx: ty::ctxt,
}
}
}
ast::ty_typeof(_e) => {
tcx.sess.span_bug(ast_ty.span, "typeof is reserved but unimplemented");
}
ast::ty_infer => {
// ty_infer should only appear as the type of arguments or return
// values in a fn_expr, or as the type of local variables. Both of

View File

@ -791,6 +791,7 @@ pub enum ty_ {
ty_tup(~[Ty]),
ty_path(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
ty_mac(mac),
ty_typeof(@expr),
// ty_infer means the type should be inferred instead of it having been
// specified. This should only appear at the "top level" of a type and not
// nested in one.

View File

@ -697,6 +697,7 @@ fn fold_opt_bounds(b: &Option<OptVec<TyParamBound>>, fld: @ast_fold)
fld.fold_expr(e)
)
}
ty_typeof(e) => ty_typeof(fld.fold_expr(e)),
ty_mac(ref mac) => ty_mac(fold_mac(mac))
}
}

View File

@ -279,6 +279,9 @@ pub fn visit_ty<E:Clone>(t: &Ty, (e, v): (E, vt<E>)) {
(v.visit_ty)(mt.ty, (e.clone(), v));
(v.visit_expr)(ex, (e.clone(), v));
},
ty_typeof(ex) => {
(v.visit_expr)(ex, (e.clone(), v));
}
ty_nil | ty_bot | ty_mac(_) | ty_infer => ()
}
}

View File

@ -51,7 +51,7 @@
use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value};
use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok};
use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box};
use ast::{TypeField, ty_fixed_length_vec, ty_closure, ty_bare_fn};
use ast::{TypeField, ty_fixed_length_vec, ty_closure, ty_bare_fn, ty_typeof};
use ast::{ty_infer, TypeMethod};
use ast::{ty_nil, TyParam, TyParamBound, ty_path, ty_ptr, ty_rptr};
use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, uniq};
@ -1136,6 +1136,13 @@ pub fn parse_ty(&self, _: bool) -> Ty {
let result = self.parse_ty_closure(ast::BorrowedSigil, None);
self.obsolete(*self.last_span, ObsoleteBareFnType);
result
} else if self.eat_keyword(keywords::Typeof) {
// TYPEOF
// In order to not be ambiguous, the type must be surrounded by parens.
self.expect(&token::LPAREN);
let e = self.parse_expr();
self.expect(&token::RPAREN);
ty_typeof(e)
} else if *self.token == token::MOD_SEP
|| is_ident_or_path(self.token) {
// NAMED TYPE
@ -3610,6 +3617,19 @@ fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ {
self.bump();
sty_value
}
token::BINOP(token::STAR) => {
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
// emitting cryptic "unexpected token" errors.
self.bump();
if self.token_is_mutability(self.token) {
self.bump();
}
if self.is_self_ident() {
self.span_err(*self.span, "cannot pass self by unsafe pointer");
self.bump();
}
sty_value
}
_ => {
sty_static
}

View File

@ -478,6 +478,7 @@ fn mk_fresh_ident_interner() -> @ident_interner {
"be", // 64
"pure", // 65
"yield", // 66
"typeof", // 67
];
@ident_interner {
@ -595,6 +596,7 @@ pub enum Keyword {
True,
Trait,
Type,
Typeof,
Unsafe,
Use,
While,
@ -639,6 +641,7 @@ pub fn to_ident(&self) -> ident {
True => ident { name: 57, ctxt: 0 },
Trait => ident { name: 58, ctxt: 0 },
Type => ident { name: 59, ctxt: 0 },
Typeof => ident { name: 67, ctxt: 0 },
Unsafe => ident { name: 60, ctxt: 0 },
Use => ident { name: 61, ctxt: 0 },
While => ident { name: 62, ctxt: 0 },
@ -660,7 +663,7 @@ pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool {
pub fn is_any_keyword(tok: &Token) -> bool {
match *tok {
token::IDENT(sid, false) => match sid.name {
8 | 27 | 32 .. 66 => true,
8 | 27 | 32 .. 67 => true,
_ => false,
},
_ => false
@ -680,7 +683,7 @@ pub fn is_strict_keyword(tok: &Token) -> bool {
pub fn is_reserved_keyword(tok: &Token) -> bool {
match *tok {
token::IDENT(sid, false) => match sid.name {
64 .. 66 => true,
64 .. 67 => true,
_ => false,
},
_ => false,

View File

@ -435,6 +435,11 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
print_expr(s, v);
word(s.s, "]");
}
ast::ty_typeof(e) => {
word(s.s, "typeof(");
print_expr(s, e);
word(s.s, ")");
}
ast::ty_mac(_) => {
fail!("print_type doesn't know how to print a ty_mac");
}

View File

@ -314,6 +314,9 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
visitor.visit_ty(mutable_type.ty, env.clone());
visitor.visit_expr(expression, env)
}
ty_typeof(expression) => {
visitor.visit_expr(expression, env)
}
ty_nil | ty_bot | ty_mac(_) | ty_infer => ()
}
}

View File

@ -0,0 +1,13 @@
// Copyright 2013 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() {
let typeof = (); //~ ERROR `typeof` is a reserved keyword
}

View File

@ -0,0 +1,22 @@
// Copyright 2013 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.
trait A {
fn foo(*mut self); //~ ERROR cannot pass self by unsafe pointer
fn bar(*self); //~ ERROR cannot pass self by unsafe pointer
}
struct X;
impl A for X {
fn foo(*mut self) { } //~ ERROR cannot pass self by unsafe pointer
fn bar(*self) { } //~ ERROR cannot pass self by unsafe pointer
}
fn main() { }