about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-12-09 19:59:20 -0500
committerNiko Matsakis <niko@alum.mit.edu>2014-12-14 11:11:55 -0500
commit5686a91914ac678ccb78220367daefe585a0d66a (patch)
tree7bd32601968e48d22798cc425f0f1347feda80db /src/libsyntax
parent092d04a40a3db44af2dd50e43a77449a7e56dd13 (diff)
downloadrust-5686a91914ac678ccb78220367daefe585a0d66a.tar.gz
rust-5686a91914ac678ccb78220367daefe585a0d66a.zip
Parse `unsafe trait` but do not do anything with it beyond parsing and integrating into rustdoc etc.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs3
-rw-r--r--src/libsyntax/ast_map/mod.rs2
-rw-r--r--src/libsyntax/config.rs4
-rw-r--r--src/libsyntax/fold.rs5
-rw-r--r--src/libsyntax/parse/parser.rs24
-rw-r--r--src/libsyntax/print/pprust.rs8
-rw-r--r--src/libsyntax/visit.rs2
7 files changed, 35 insertions, 13 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 812b1baa8f7..1cc6b6feee8 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1611,7 +1611,8 @@ pub enum Item_ {
     ItemEnum(EnumDef, Generics),
     ItemStruct(P<StructDef>, Generics),
     /// Represents a Trait Declaration
-    ItemTrait(Generics,
+    ItemTrait(Unsafety,
+              Generics,
               Option<TraitRef>, // (optional) default bound not required for Self.
                                 // Currently, only Sized makes sense here.
               TyParamBounds,
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index 6f1d2d39b30..a2cdc4d2fbc 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -786,7 +786,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
                     None => {}
                 }
             }
-            ItemTrait(_, _, ref bounds, ref trait_items) => {
+            ItemTrait(_, _, _, ref bounds, ref trait_items) => {
                 for b in bounds.iter() {
                     if let TraitTyParamBound(ref t) = *b {
                         self.insert(t.trait_ref.ref_id, NodeItem(i));
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 87426dce918..ee651592117 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -139,11 +139,11 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
                                        .collect();
             ast::ItemImpl(a, b, c, impl_items)
         }
-        ast::ItemTrait(a, b, c, methods) => {
+        ast::ItemTrait(u, a, b, c, methods) => {
             let methods = methods.into_iter()
                                  .filter(|m| trait_method_in_cfg(cx, m))
                                  .collect();
-            ast::ItemTrait(a, b, c, methods)
+            ast::ItemTrait(u, a, b, c, methods)
         }
         ast::ItemStruct(def, generics) => {
             ast::ItemStruct(fold_struct(cx, def), generics)
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index c2c77e5a16c..daed014f4eb 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -1035,7 +1035,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
                      folder.fold_ty(ty),
                      new_impl_items)
         }
-        ItemTrait(generics, unbound, bounds, methods) => {
+        ItemTrait(unsafety, generics, unbound, bounds, methods) => {
             let bounds = folder.fold_bounds(bounds);
             let methods = methods.into_iter().flat_map(|method| {
                 let r = match method {
@@ -1063,7 +1063,8 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
                 };
                 r
             }).collect();
-            ItemTrait(folder.fold_generics(generics),
+            ItemTrait(unsafety,
+                      folder.fold_generics(generics),
                       unbound,
                       bounds,
                       methods)
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index cc96d45a1c8..b2c30797cac 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4628,7 +4628,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse trait Foo { ... }
-    fn parse_item_trait(&mut self) -> ItemInfo {
+    fn parse_item_trait(&mut self, unsafety: Unsafety) -> ItemInfo {
         let ident = self.parse_ident();
         let mut tps = self.parse_generics();
         let sized = self.parse_for_sized();
@@ -4639,7 +4639,7 @@ impl<'a> Parser<'a> {
         self.parse_where_clause(&mut tps);
 
         let meths = self.parse_trait_items();
-        (ident, ItemTrait(tps, sized, bounds, meths), None)
+        (ident, ItemTrait(unsafety, tps, sized, bounds, meths), None)
     }
 
     fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
@@ -5539,6 +5539,23 @@ impl<'a> Parser<'a> {
                                     maybe_append(attrs, extra_attrs));
             return IoviItem(item);
         }
+        if self.token.is_keyword(keywords::Unsafe) &&
+            self.look_ahead(1u, |t| t.is_keyword(keywords::Trait))
+        {
+            // UNSAFE TRAIT ITEM
+            self.expect_keyword(keywords::Unsafe);
+            self.expect_keyword(keywords::Trait);
+            let (ident, item_, extra_attrs) =
+                self.parse_item_trait(ast::Unsafety::Unsafe);
+            let last_span = self.last_span;
+            let item = self.mk_item(lo,
+                                    last_span.hi,
+                                    ident,
+                                    item_,
+                                    visibility,
+                                    maybe_append(attrs, extra_attrs));
+            return IoviItem(item);
+        }
         if self.token.is_keyword(keywords::Fn) &&
                 self.look_ahead(1, |f| !Parser::fn_expr_lookahead(f)) {
             // FUNCTION ITEM
@@ -5614,7 +5631,8 @@ impl<'a> Parser<'a> {
         }
         if self.eat_keyword(keywords::Trait) {
             // TRAIT ITEM
-            let (ident, item_, extra_attrs) = self.parse_item_trait();
+            let (ident, item_, extra_attrs) =
+                self.parse_item_trait(ast::Unsafety::Normal);
             let last_span = self.last_span;
             let item = self.mk_item(lo,
                                     last_span.hi,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 53399aba99a..037118b145f 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -955,9 +955,11 @@ impl<'a> State<'a> {
                 }
                 try!(self.bclose(item.span));
             }
-            ast::ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => {
-                try!(self.head(visibility_qualified(item.vis,
-                                                    "trait").as_slice()));
+            ast::ItemTrait(unsafety, ref generics, ref unbound, ref bounds, ref methods) => {
+                try!(self.head(""));
+                try!(self.print_visibility(item.vis));
+                try!(self.print_unsafety(unsafety));
+                try!(self.word_nbsp("trait"));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(generics));
                 if let &Some(ref tref) = unbound {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 6eedb77889a..7bb79a15f45 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -311,7 +311,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
                                      generics,
                                      item.id)
         }
-        ItemTrait(ref generics, _, ref bounds, ref methods) => {
+        ItemTrait(_, ref generics, _, ref bounds, ref methods) => {
             visitor.visit_generics(generics);
             walk_ty_param_bounds_helper(visitor, bounds);
             for method in methods.iter() {