]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #8718 : bblum/rust/typeof, r=pcwalton
authorbors <bors@rust-lang.org>
Wed, 28 Aug 2013 22:30:38 +0000 (15:30 -0700)
committerbors <bors@rust-lang.org>
Wed, 28 Aug 2013 22:30:38 +0000 (15:30 -0700)
r? anybody

src/etc/vim/syntax/rust.vim
src/librustc/middle/typeck/astconv.rs
src/libsyntax/ast.rs
src/libsyntax/fold.rs
src/libsyntax/oldvisit.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/test/compile-fail/keyword-typeof.rs [new file with mode: 0644]
src/test/compile-fail/no-unsafe-self.rs [new file with mode: 0644]

index 260b23cb70be4c01dee0e6e233309cb56642f3b6..b5e52939635977bede356378a109b735a6208807 100644 (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
index 17b4716ad508e8927ab4c5953c0171dfa5db8a57..6ebcf4facc180e43413c5644f7cfcc606c767e7d 100644 (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
index 44015a8b443f092b899f7102beb53f48ffbca9f8..aec279e9c53bd1bff8d8ffbb7c570fd6f9e7992c 100644 (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.
index 458737e2fbf0bad484310ff5336bd2628942aa4f..6e3cd8e71597178664b8be07e86feaebb62a8b9e 100644 (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))
     }
 }
index 56576ee359960b0a40f5fcedaab5a899def08679..e1dcdb9222c7bdc654b13848d0be63822143c7f9 100644 (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 => ()
     }
 }
index 8ca858b7935eceedd2b818e4ee91469ea6e61bf6..ea7a7540e363dce1a3f520a3e090e54f57bd31b2 100644 (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
           }
index 0d7def84003e4d27ee13962544995c5f47ebb139..8128a4e905c16ff77e90bcfc4214bc34438bc1bd 100644 (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,
index d449ba4eb5fb4609c3045958a7fdb004d1da3f0c..9c31d982590eafd4c943bcd3dc55575239711d9e 100644 (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");
       }
index e5b7823ae44ecc9a5e1ae7335bd47b93829669a7..79304aebea2d47afb94f0f9b31afe0781ab1ec1c 100644 (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 => ()
     }
 }
diff --git a/src/test/compile-fail/keyword-typeof.rs b/src/test/compile-fail/keyword-typeof.rs
new file mode 100644 (file)
index 0000000..c428753
--- /dev/null
@@ -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
+}
diff --git a/src/test/compile-fail/no-unsafe-self.rs b/src/test/compile-fail/no-unsafe-self.rs
new file mode 100644 (file)
index 0000000..0bf73bb
--- /dev/null
@@ -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() { }