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 syn match rustFuncName "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
" reserved " 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 int uint float char bool u8 u16 u32 u64 f32
syn keyword rustType f64 i8 i16 i32 i64 str Self 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 => { ast::ty_infer => {
// ty_infer should only appear as the type of arguments or return // 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 // 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_tup(~[Ty]),
ty_path(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above ty_path(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
ty_mac(mac), ty_mac(mac),
ty_typeof(@expr),
// ty_infer means the type should be inferred instead of it having been // 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 // specified. This should only appear at the "top level" of a type and not
// nested in one. // nested in one.

View file

@ -697,6 +697,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
fld.fold_expr(e) fld.fold_expr(e)
) )
} }
ty_typeof(e) => ty_typeof(fld.fold_expr(e)),
ty_mac(ref mac) => ty_mac(fold_mac(mac)) 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_ty)(mt.ty, (e.clone(), v));
(v.visit_expr)(ex, (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 => () 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::{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::{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::{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_infer, TypeMethod};
use ast::{ty_nil, TyParam, TyParamBound, ty_path, ty_ptr, ty_rptr}; use ast::{ty_nil, TyParam, TyParamBound, ty_path, ty_ptr, ty_rptr};
use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, uniq}; 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); let result = self.parse_ty_closure(ast::BorrowedSigil, None);
self.obsolete(*self.last_span, ObsoleteBareFnType); self.obsolete(*self.last_span, ObsoleteBareFnType);
result 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 } else if *self.token == token::MOD_SEP
|| is_ident_or_path(self.token) { || is_ident_or_path(self.token) {
// NAMED TYPE // NAMED TYPE
@ -3610,6 +3617,19 @@ impl Parser {
self.bump(); self.bump();
sty_value 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 sty_static
} }

View file

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

View file

@ -435,6 +435,11 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
print_expr(s, v); print_expr(s, v);
word(s.s, "]"); word(s.s, "]");
} }
ast::ty_typeof(e) => {
word(s.s, "typeof(");
print_expr(s, e);
word(s.s, ")");
}
ast::ty_mac(_) => { ast::ty_mac(_) => {
fail!("print_type doesn't know how to print a 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_ty(mutable_type.ty, env.clone());
visitor.visit_expr(expression, env) visitor.visit_expr(expression, env)
} }
ty_typeof(expression) => {
visitor.visit_expr(expression, env)
}
ty_nil | ty_bot | ty_mac(_) | ty_infer => () 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() { }