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 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Clone + 'static>(
}
}
}
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 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
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::{struct_variant_kind, subtract};
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 @@ impl Parser {
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 @@ impl Parser {
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 mod keywords {
True,
Trait,
Type,
Typeof,
Unsafe,
Use,
While,
@ -639,6 +641,7 @@ pub mod keywords {
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() { }