This is a [breaking change].
match *b {
DefaultBlock => hir::DefaultBlock,
UnsafeBlock(u) => hir::UnsafeBlock(lower_unsafe_source(_lctx, u)),
- PushUnsafeBlock(u) => hir::PushUnsafeBlock(lower_unsafe_source(_lctx, u)),
- PopUnsafeBlock(u) => hir::PopUnsafeBlock(lower_unsafe_source(_lctx, u)),
}
}
pub enum BlockCheckMode {
DefaultBlock,
UnsafeBlock(UnsafeSource),
- PushUnsafeBlock(UnsafeSource),
- PopUnsafeBlock(UnsafeSource),
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
syntax_expanders.insert(intern("cfg"),
builtin_normal_expander(
ext::cfg::expand_cfg));
- syntax_expanders.insert(intern("push_unsafe"),
- builtin_normal_expander(
- ext::pushpop_safe::expand_push_unsafe));
- syntax_expanders.insert(intern("pop_unsafe"),
- builtin_normal_expander(
- ext::pushpop_safe::expand_pop_unsafe));
syntax_expanders.insert(intern("trace_macros"),
builtin_normal_expander(
ext::trace_macros::expand_trace_macros));
+++ /dev/null
-// Copyright 2015 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.
-
-/*
- * The compiler code necessary to support the `push_unsafe!` and
- * `pop_unsafe!` macros.
- *
- * This is a hack to allow a kind of "safety hygiene", where a macro
- * can generate code with an interior expression that inherits the
- * safety of some outer context.
- *
- * For example, in:
- *
- * ```rust
- * fn foo() { push_unsafe!( { EXPR_1; pop_unsafe!( EXPR_2 ) } ) }
- * ```
- *
- * the `EXPR_1` is considered to be in an `unsafe` context,
- * but `EXPR_2` is considered to be in a "safe" (i.e. checked) context.
- *
- * For comparison, in:
- *
- * ```rust
- * fn foo() { unsafe { push_unsafe!( { EXPR_1; pop_unsafe!( EXPR_2 ) } ) } }
- * ```
- *
- * both `EXPR_1` and `EXPR_2` are considered to be in `unsafe`
- * contexts.
- *
- */
-
-use ast;
-use codemap::Span;
-use ext::base::*;
-use ext::base;
-use ext::build::AstBuilder;
-use feature_gate;
-use ptr::P;
-
-enum PushPop { Push, Pop }
-
-pub fn expand_push_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
- -> Box<base::MacResult+'cx> {
- expand_pushpop_unsafe(cx, sp, tts, PushPop::Push)
-}
-
-pub fn expand_pop_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
- -> Box<base::MacResult+'cx> {
- expand_pushpop_unsafe(cx, sp, tts, PushPop::Pop)
-}
-
-fn expand_pushpop_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree],
- pp: PushPop) -> Box<base::MacResult+'cx> {
- feature_gate::check_for_pushpop_syntax(
- cx.ecfg.features, &cx.parse_sess.span_diagnostic, sp);
-
- let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
- Some(exprs) => exprs.into_iter(),
- None => return DummyResult::expr(sp),
- };
-
- let expr = match (exprs.next(), exprs.next()) {
- (Some(expr), None) => expr,
- _ => {
- let msg = match pp {
- PushPop::Push => "push_unsafe! takes 1 arguments",
- PushPop::Pop => "pop_unsafe! takes 1 arguments",
- };
- cx.span_err(sp, msg);
- return DummyResult::expr(sp);
- }
- };
-
- let source = ast::UnsafeSource::CompilerGenerated;
- let check_mode = match pp {
- PushPop::Push => ast::BlockCheckMode::PushUnsafeBlock(source),
- PushPop::Pop => ast::BlockCheckMode::PopUnsafeBlock(source),
- };
-
- MacEager::expr(cx.expr_block(P(ast::Block {
- stmts: vec![],
- expr: Some(expr),
- id: ast::DUMMY_NODE_ID,
- rules: check_mode,
- span: sp
- })))
-}
pub mod log_syntax;
pub mod mtwt;
pub mod quote;
- pub mod pushpop_safe;
pub mod source_util;
pub mod trace_macros;
attrs: &[ast::Attribute],
close_box: bool) -> io::Result<()> {
match blk.rules {
- ast::UnsafeBlock(..) | ast::PushUnsafeBlock(..) => try!(self.word_space("unsafe")),
- ast::DefaultBlock | ast::PopUnsafeBlock(..) => ()
+ ast::UnsafeBlock(..) => try!(self.word_space("unsafe")),
+ ast::DefaultBlock => ()
}
try!(self.maybe_print_comment(blk.span.lo));
try!(self.ann.pre(self, NodeBlock(blk)));
+++ /dev/null
-// Copyright 2015 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 c = push_unsafe!('c'); //~ ERROR push/pop_unsafe macros are experimental
- let c = pop_unsafe!('c'); //~ ERROR push/pop_unsafe macros are experimental
-}
+++ /dev/null
-// Copyright 2012 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.
-
-// Basic sanity check for `push_unsafe!(EXPR)` and
-// `pop_unsafe!(EXPR)`: we can call unsafe code when there are a
-// positive number of pushes in the stack, or if we are within a
-// normal `unsafe` block, but otherwise cannot.
-
-#![feature(pushpop_unsafe)]
-
-static mut X: i32 = 0;
-
-unsafe fn f() { X += 1; return; }
-fn g() { unsafe { X += 1_000; } return; }
-
-fn main() {
- push_unsafe!( {
- f(); pop_unsafe!({
- f() //~ ERROR: call to unsafe function
- })
- } );
-
- push_unsafe!({
- f();
- pop_unsafe!({
- g();
- f(); //~ ERROR: call to unsafe function
- })
- } );
-
- push_unsafe!({
- g(); pop_unsafe!({
- unsafe {
- f();
- }
- f(); //~ ERROR: call to unsafe function
- })
- });
-
-
- // Note: For implementation simplicity the compiler just
- // ICE's if you underflow the push_unsafe stack.
- //
- // Thus all of the following cases cause an ICE.
- //
- // (The "ERROR" notes are from an earlier version
- // that used saturated arithmetic rather than checked
- // arithmetic.)
-
- // pop_unsafe!{ g() };
- //
- // push_unsafe!({
- // pop_unsafe!(pop_unsafe!{ g() })
- // });
- //
- // push_unsafe!({
- // g();
- // pop_unsafe!(pop_unsafe!({
- // f() // ERROR: call to unsafe function
- // }))
- // });
- //
- // pop_unsafe!({
- // f(); // ERROR: call to unsafe function
- // })
-
-}
+++ /dev/null
-// Copyright 2015 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.
-
-// Basic sanity check for `push_unsafe!(EXPR)` and
-// `pop_unsafe!(EXPR)`: we can call unsafe code when there are a
-// positive number of pushes in the stack, or if we are within a
-// normal `unsafe` block, but otherwise cannot.
-
-// ignore-pretty because the `push_unsafe!` and `pop_unsafe!` macros
-// are not integrated with the pretty-printer.
-
-#![feature(pushpop_unsafe)]
-
-static mut X: i32 = 0;
-
-unsafe fn f() { X += 1; return; }
-fn g() { unsafe { X += 1_000; } return; }
-
-fn check_reset_x(x: i32) -> bool {
- #![allow(unused_parens)] // dont you judge my style choices!
- unsafe {
- let ret = (x == X);
- X = 0;
- ret
- }
-}
-
-fn main() {
- // double-check test infrastructure
- assert!(check_reset_x(0));
- unsafe { f(); }
- assert!(check_reset_x(1));
- assert!(check_reset_x(0));
- { g(); }
- assert!(check_reset_x(1000));
- assert!(check_reset_x(0));
- unsafe { f(); g(); g(); }
- assert!(check_reset_x(2001));
-
- push_unsafe!( { f(); pop_unsafe!( g() ) } );
- assert!(check_reset_x(1_001));
- push_unsafe!( { g(); pop_unsafe!( unsafe { f(); f(); } ) } );
- assert!(check_reset_x(1_002));
-
- unsafe { push_unsafe!( { f(); pop_unsafe!( { f(); f(); } ) } ); }
- assert!(check_reset_x(3));
- push_unsafe!( { f(); push_unsafe!( { pop_unsafe!( { f(); f(); f(); } ) } ); } );
- assert!(check_reset_x(4));
-}