Separate unsafe blocks into a ExprKind variant
diff --git a/src/expr.rs b/src/expr.rs
index df930ba..a6e7e06 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -202,9 +202,14 @@
             pub or2_token: Token![|],
         }),
 
-        /// A block (`{ ... }` or `unsafe { ... }`)
+        /// An unsafe block (`unsafe { ... }`)
+        pub Unsafe(ExprUnsafe #full {
+            pub unsafe_token: Token![unsafe],
+            pub block: Block,
+        }),
+
+        /// A block (`{ ... }`)
         pub Block(ExprBlock #full {
-            pub unsafety: Unsafety,
             pub block: Block,
         }),
 
@@ -628,6 +633,7 @@
     // see https://github.com/rust-lang/rust/blob/eb8f2586e
     //                       /src/libsyntax/parse/classify.rs#L17-L37
     match expr.node {
+        ExprKind::Unsafe(..) |
         ExprKind::Block(..) |
         ExprKind::If(..) |
         ExprKind::IfLet(..) |
@@ -1192,6 +1198,8 @@
         |
         syn!(ExprYield) => { ExprKind::Yield }
         |
+        syn!(ExprUnsafe) => { ExprKind::Unsafe }
+        |
         call!(expr_closure, allow_struct)
         |
         cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
@@ -1238,6 +1246,8 @@
         |
         syn!(ExprYield) => { ExprKind::Yield }
         |
+        syn!(ExprUnsafe) => { ExprKind::Unsafe }
+        |
         syn!(ExprBlock) => { ExprKind::Block }
     ), Expr::from));
 
@@ -1272,7 +1282,6 @@
                 kind: InPlaceKind::In(in_),
                 value: Box::new(Expr {
                     node: ExprBlock {
-                        unsafety: Unsafety::Normal,
                         block: Block {
                             stmts: value.0,
                             brace_token: value.1,
@@ -1403,7 +1412,6 @@
             do_parse!(
                 else_block: braces!(call!(Block::parse_within)) >>
                 (ExprKind::Block(ExprBlock {
-                    unsafety: Unsafety::Normal,
                     block: Block {
                         stmts: else_block.0,
                         brace_token: else_block.1,
@@ -1537,7 +1545,6 @@
                 body: syn!(Block) >>
                 (ReturnType::Type(ty, arrow),
                  ExprKind::Block(ExprBlock {
-                    unsafety: Unsafety::Normal,
                     block: body,
                 }).into())
             )
@@ -1739,12 +1746,22 @@
     }
 
     #[cfg(feature = "full")]
+    impl Synom for ExprUnsafe {
+        named!(parse -> Self, do_parse!(
+            unsafe_: keyword!(unsafe) >>
+            b: syn!(Block) >>
+            (ExprUnsafe {
+                unsafe_token: unsafe_,
+                block: b,
+            })
+        ));
+    }
+
+    #[cfg(feature = "full")]
     impl Synom for ExprBlock {
         named!(parse -> Self, do_parse!(
-            rules: syn!(Unsafety) >>
             b: syn!(Block) >>
             (ExprBlock {
-                unsafety: rules,
                 block: b,
             })
         ));
@@ -2568,9 +2585,16 @@
     }
 
     #[cfg(feature = "full")]
+    impl ToTokens for ExprUnsafe {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            self.unsafe_token.to_tokens(tokens);
+            self.block.to_tokens(tokens);
+        }
+    }
+
+    #[cfg(feature = "full")]
     impl ToTokens for ExprBlock {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            self.unsafety.to_tokens(tokens);
             self.block.to_tokens(tokens);
         }
     }
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 1b676e2..b6996f4 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -176,6 +176,8 @@
 
 fn fold_expr_unary(&mut self, i: ExprUnary) -> ExprUnary { fold_expr_unary(self, i) }
 # [ cfg ( feature = "full" ) ]
+fn fold_expr_unsafe(&mut self, i: ExprUnsafe) -> ExprUnsafe { fold_expr_unsafe(self, i) }
+# [ cfg ( feature = "full" ) ]
 fn fold_expr_while(&mut self, i: ExprWhile) -> ExprWhile { fold_expr_while(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn fold_expr_while_let(&mut self, i: ExprWhileLet) -> ExprWhileLet { fold_expr_while_let(self, i) }
@@ -833,7 +835,6 @@
 # [ cfg ( feature = "full" ) ]
 pub fn fold_expr_block<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprBlock) -> ExprBlock {
     ExprBlock {
-        unsafety: _visitor.fold_unsafety(_i . unsafety),
         block: _visitor.fold_block(_i . block),
     }
 }
@@ -1058,6 +1059,11 @@
                 full!(_visitor.fold_expr_closure(_binding_0)),
             )
         }
+        Unsafe(_binding_0, ) => {
+            Unsafe (
+                full!(_visitor.fold_expr_unsafe(_binding_0)),
+            )
+        }
         Block(_binding_0, ) => {
             Block (
                 full!(_visitor.fold_expr_block(_binding_0)),
@@ -1279,6 +1285,13 @@
     }
 }
 # [ cfg ( feature = "full" ) ]
+pub fn fold_expr_unsafe<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprUnsafe) -> ExprUnsafe {
+    ExprUnsafe {
+        unsafe_token: _i . unsafe_token,
+        block: _visitor.fold_block(_i . block),
+    }
+}
+# [ cfg ( feature = "full" ) ]
 pub fn fold_expr_while<V: Folder + ?Sized>(_visitor: &mut V, _i: ExprWhile) -> ExprWhile {
     ExprWhile {
         cond: Box::new(_visitor.fold_expr(* _i . cond)),
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index da068a1..ec40662 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -149,6 +149,8 @@
 
 fn visit_expr_unary(&mut self, i: &'ast ExprUnary) { visit_expr_unary(self, i) }
 # [ cfg ( feature = "full" ) ]
+fn visit_expr_unsafe(&mut self, i: &'ast ExprUnsafe) { visit_expr_unsafe(self, i) }
+# [ cfg ( feature = "full" ) ]
 fn visit_expr_while(&mut self, i: &'ast ExprWhile) { visit_expr_while(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn visit_expr_while_let(&mut self, i: &'ast ExprWhileLet) { visit_expr_while_let(self, i) }
@@ -687,7 +689,6 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_expr_block<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprBlock) {
-    _visitor.visit_unsafety(&_i . unsafety);
     _visitor.visit_block(&_i . block);
 }
 # [ cfg ( feature = "full" ) ]
@@ -845,6 +846,9 @@
         Closure(ref _binding_0, ) => {
             full!(_visitor.visit_expr_closure(&* _binding_0));
         }
+        Unsafe(ref _binding_0, ) => {
+            full!(_visitor.visit_expr_unsafe(&* _binding_0));
+        }
         Block(ref _binding_0, ) => {
             full!(_visitor.visit_expr_block(&* _binding_0));
         }
@@ -998,6 +1002,11 @@
     _visitor.visit_expr(&_i . expr);
 }
 # [ cfg ( feature = "full" ) ]
+pub fn visit_expr_unsafe<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprUnsafe) {
+    // Skipped field _i . unsafe_token;
+    _visitor.visit_block(&_i . block);
+}
+# [ cfg ( feature = "full" ) ]
 pub fn visit_expr_while<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprWhile) {
     _visitor.visit_expr(&_i . cond);
     _visitor.visit_block(&_i . body);
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 7d5c109..80329b0 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -149,6 +149,8 @@
 
 fn visit_expr_unary_mut(&mut self, i: &mut ExprUnary) { visit_expr_unary_mut(self, i) }
 # [ cfg ( feature = "full" ) ]
+fn visit_expr_unsafe_mut(&mut self, i: &mut ExprUnsafe) { visit_expr_unsafe_mut(self, i) }
+# [ cfg ( feature = "full" ) ]
 fn visit_expr_while_mut(&mut self, i: &mut ExprWhile) { visit_expr_while_mut(self, i) }
 # [ cfg ( feature = "full" ) ]
 fn visit_expr_while_let_mut(&mut self, i: &mut ExprWhileLet) { visit_expr_while_let_mut(self, i) }
@@ -687,7 +689,6 @@
 }
 # [ cfg ( feature = "full" ) ]
 pub fn visit_expr_block_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ExprBlock) {
-    _visitor.visit_unsafety_mut(&mut _i . unsafety);
     _visitor.visit_block_mut(&mut _i . block);
 }
 # [ cfg ( feature = "full" ) ]
@@ -845,6 +846,9 @@
         Closure(ref mut _binding_0, ) => {
             full!(_visitor.visit_expr_closure_mut(&mut * _binding_0));
         }
+        Unsafe(ref mut _binding_0, ) => {
+            full!(_visitor.visit_expr_unsafe_mut(&mut * _binding_0));
+        }
         Block(ref mut _binding_0, ) => {
             full!(_visitor.visit_expr_block_mut(&mut * _binding_0));
         }
@@ -998,6 +1002,11 @@
     _visitor.visit_expr_mut(&mut _i . expr);
 }
 # [ cfg ( feature = "full" ) ]
+pub fn visit_expr_unsafe_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ExprUnsafe) {
+    // Skipped field _i . unsafe_token;
+    _visitor.visit_block_mut(&mut _i . block);
+}
+# [ cfg ( feature = "full" ) ]
 pub fn visit_expr_while_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ExprWhile) {
     _visitor.visit_expr_mut(&mut _i . cond);
     _visitor.visit_block_mut(&mut _i . body);
diff --git a/src/lib.rs b/src/lib.rs
index 54f89e9..f88112d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,7 +31,7 @@
                ExprAssign, ExprAssignOp, ExprField, ExprTupField, ExprIndex,
                ExprRange, ExprPath, ExprAddrOf, ExprBreak, ExprContinue,
                ExprRet, ExprStruct, ExprRepeat, ExprParen, ExprTry, ExprCatch,
-               ExprGroup, ExprYield};
+               ExprGroup, ExprYield, ExprUnsafe};
 
 #[cfg(feature = "full")]
 pub use expr::{Arm, BindingMode, Block, CaptureBy, FieldPat, FieldValue, Local,
diff --git a/tests/test_precedence.rs b/tests/test_precedence.rs
index bbc6023..171bf4b 100644
--- a/tests/test_precedence.rs
+++ b/tests/test_precedence.rs
@@ -322,6 +322,7 @@
                 ExprKind::Group(_) => unreachable!(),
                 ExprKind::Paren(p) => paren(self, p.expr.node),
                 ExprKind::If(..) |
+                ExprKind::Unsafe(..) |
                 ExprKind::Block(..) |
                 ExprKind::IfLet(..) => {
                     return fold_expr(self, expr);