提交 e0c74868 编写于 作者: N Nick Cameron

Fix stability

上级 bfffa9ec
...@@ -102,7 +102,6 @@ fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl, ...@@ -102,7 +102,6 @@ fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl,
fn visit_block(&mut self, block: &hir::Block) { fn visit_block(&mut self, block: &hir::Block) {
let old_unsafe_context = self.unsafe_context; let old_unsafe_context = self.unsafe_context;
match block.rules { match block.rules {
hir::DefaultBlock => {}
hir::UnsafeBlock(source) => { hir::UnsafeBlock(source) => {
// By default only the outermost `unsafe` block is // By default only the outermost `unsafe` block is
// "used" and so nested unsafe blocks are pointless // "used" and so nested unsafe blocks are pointless
...@@ -131,6 +130,7 @@ fn visit_block(&mut self, block: &hir::Block) { ...@@ -131,6 +130,7 @@ fn visit_block(&mut self, block: &hir::Block) {
self.unsafe_context.push_unsafe_count = self.unsafe_context.push_unsafe_count =
self.unsafe_context.push_unsafe_count.checked_sub(1).unwrap(); self.unsafe_context.push_unsafe_count.checked_sub(1).unwrap();
} }
hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock => {}
} }
visit::walk_block(self, block); visit::walk_block(self, block);
......
...@@ -270,7 +270,8 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt) ...@@ -270,7 +270,8 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt)
let mut checker = Checker { let mut checker = Checker {
tcx: tcx, tcx: tcx,
active_features: active_features, active_features: active_features,
used_features: FnvHashMap() used_features: FnvHashMap(),
in_skip_block: 0,
}; };
let krate = tcx.map.krate(); let krate = tcx.map.krate();
...@@ -283,14 +284,23 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt) ...@@ -283,14 +284,23 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt)
struct Checker<'a, 'tcx: 'a> { struct Checker<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>, tcx: &'a ty::ctxt<'tcx>,
active_features: FnvHashSet<InternedString>, active_features: FnvHashSet<InternedString>,
used_features: FnvHashMap<InternedString, attr::StabilityLevel> used_features: FnvHashMap<InternedString, attr::StabilityLevel>,
// Within a block where feature gate checking can be skipped.
in_skip_block: u32,
} }
impl<'a, 'tcx> Checker<'a, 'tcx> { impl<'a, 'tcx> Checker<'a, 'tcx> {
fn check(&mut self, id: DefId, span: Span, stab: &Option<&Stability>) { fn check(&mut self, id: DefId, span: Span, stab: &Option<&Stability>) {
// Only the cross-crate scenario matters when checking unstable APIs // Only the cross-crate scenario matters when checking unstable APIs
let cross_crate = !id.is_local(); let cross_crate = !id.is_local();
if !cross_crate { return } if !cross_crate {
return
}
// We don't need to check for stability - presumably compiler generated code.
if self.in_skip_block > 0 {
return;
}
match *stab { match *stab {
Some(&Stability { level: attr::Unstable, ref feature, ref reason, issue, .. }) => { Some(&Stability { level: attr::Unstable, ref feature, ref reason, issue, .. }) => {
...@@ -369,6 +379,21 @@ fn visit_pat(&mut self, pat: &hir::Pat) { ...@@ -369,6 +379,21 @@ fn visit_pat(&mut self, pat: &hir::Pat) {
&mut |id, sp, stab| self.check(id, sp, stab)); &mut |id, sp, stab| self.check(id, sp, stab));
visit::walk_pat(self, pat) visit::walk_pat(self, pat)
} }
fn visit_block(&mut self, b: &hir::Block) {
let old_skip_count = self.in_skip_block;
match b.rules {
hir::BlockCheckMode::PushUnstableBlock => {
self.in_skip_block += 1;
}
hir::BlockCheckMode::PopUnstableBlock => {
self.in_skip_block = self.in_skip_block.checked_sub(1).unwrap();
}
_ => {}
}
visit::walk_block(self, b);
self.in_skip_block = old_skip_count;
}
} }
/// Helper for discovering nodes to check for stability /// Helper for discovering nodes to check for stability
......
...@@ -574,6 +574,9 @@ pub enum BlockCheckMode { ...@@ -574,6 +574,9 @@ pub enum BlockCheckMode {
UnsafeBlock(UnsafeSource), UnsafeBlock(UnsafeSource),
PushUnsafeBlock(UnsafeSource), PushUnsafeBlock(UnsafeSource),
PopUnsafeBlock(UnsafeSource), PopUnsafeBlock(UnsafeSource),
// Within this block (but outside a PopUnstableBlock), we suspend checking of stability.
PushUnstableBlock,
PopUnstableBlock,
} }
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
......
...@@ -749,12 +749,28 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> { ...@@ -749,12 +749,28 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
P(hir::Expr { P(hir::Expr {
id: e.id, id: e.id,
node: match e.node { node: match e.node {
// Issue #22181:
// Eventually a desugaring for `box EXPR`
// (similar to the desugaring above for `in PLACE BLOCK`)
// should go here, desugaring
//
// to:
//
// let mut place = BoxPlace::make_place();
// let raw_place = Place::pointer(&mut place);
// let value = $value;
// unsafe {
// ::std::ptr::write(raw_place, value);
// Boxed::finalize(place)
// }
//
// But for now there are type-inference issues doing that.
ExprBox(ref e) => { ExprBox(ref e) => {
hir::ExprBox(lower_expr(lctx, e)) hir::ExprBox(lower_expr(lctx, e))
} }
// Desugar ExprBox: `in (PLACE) EXPR` // Desugar ExprBox: `in (PLACE) EXPR`
ExprInPlace(Some(ref placer), ref value_expr) => { ExprInPlace(ref placer, ref value_expr) => {
// to: // to:
// //
// let p = PLACE; // let p = PLACE;
...@@ -810,23 +826,43 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> { ...@@ -810,23 +826,43 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
}; };
// pop_unsafe!(EXPR)); // pop_unsafe!(EXPR));
let pop_unsafe_expr = pop_unsafe_expr(lctx, value_expr, e.span); let pop_unsafe_expr =
signal_block_expr(lctx,
vec![],
signal_block_expr(lctx,
vec![],
value_expr,
e.span,
hir::PopUnstableBlock),
e.span,
hir::PopUnsafeBlock(hir::CompilerGenerated));
// push_unsafe!({ // push_unsafe!({
// ptr::write(p_ptr, pop_unsafe!(<value_expr>)); // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
// InPlace::finalize(place) // InPlace::finalize(place)
// }) // })
let expr = { let expr = {
let call_move_val_init = hir::StmtSemi(make_call( let call_move_val_init =
lctx, &move_val_init, vec![expr_ident(lctx, e.span, p_ptr_ident), pop_unsafe_expr]), lctx.next_id()); hir::StmtSemi(make_call(lctx,
&move_val_init,
vec![expr_ident(lctx, e.span, p_ptr_ident),
pop_unsafe_expr]),
lctx.next_id());
let call_move_val_init = respan(e.span, call_move_val_init); let call_move_val_init = respan(e.span, call_move_val_init);
let call = make_call(lctx, &inplace_finalize, vec![expr_ident(lctx, e.span, agent_ident)]); let call = make_call(lctx, &inplace_finalize, vec![expr_ident(lctx, e.span, agent_ident)]);
Some(push_unsafe_expr(lctx, vec![P(call_move_val_init)], call, e.span)) signal_block_expr(lctx,
vec![P(call_move_val_init)],
call,
e.span,
hir::PushUnsafeBlock(hir::CompilerGenerated))
}; };
let block = block_all(lctx, e.span, vec![s1, s2, s3], expr); return signal_block_expr(lctx,
return expr_block(lctx, block); vec![s1, s2, s3],
expr,
e.span,
hir::PushUnstableBlock);
} }
ExprVec(ref exprs) => { ExprVec(ref exprs) => {
...@@ -1475,21 +1511,9 @@ fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Pa ...@@ -1475,21 +1511,9 @@ fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Pa
path_global(span, idents) path_global(span, idents)
} }
fn push_unsafe_expr(lctx: &LoweringContext, stmts: Vec<P<hir::Stmt>>, fn signal_block_expr(lctx: &LoweringContext, stmts: Vec<P<hir::Stmt>>, expr: P<hir::Expr>, span: Span, rule: hir::BlockCheckMode) -> P<hir::Expr> {
expr: P<hir::Expr>, span: Span)
-> P<hir::Expr> {
let rules = hir::PushUnsafeBlock(hir::CompilerGenerated);
expr_block(lctx, P(hir::Block { expr_block(lctx, P(hir::Block {
rules: rules, span: span, id: lctx.next_id(), rules: rule, span: span, id: lctx.next_id(),
stmts: stmts, expr: Some(expr), stmts: stmts, expr: Some(expr),
})) }))
} }
fn pop_unsafe_expr(lctx: &LoweringContext, expr: P<hir::Expr>, span: Span)
-> P<hir::Expr> {
let rules = hir::PopUnsafeBlock(hir::CompilerGenerated);
expr_block(lctx, P(hir::Block {
rules: rules, span: span, id: lctx.next_id(),
stmts: vec![], expr: Some(expr),
}))
}
...@@ -1089,8 +1089,12 @@ pub fn print_block_maybe_unclosed(&mut self, ...@@ -1089,8 +1089,12 @@ pub fn print_block_maybe_unclosed(&mut self,
close_box: bool) close_box: bool)
-> io::Result<()> { -> io::Result<()> {
match blk.rules { match blk.rules {
hir::UnsafeBlock(..) | hir::PushUnsafeBlock(..) => try!(self.word_space("unsafe")), hir::UnsafeBlock(..) => try!(self.word_space("unsafe")),
hir::DefaultBlock | hir::PopUnsafeBlock(..) => (), hir::PushUnsafeBlock(..) => try!(self.word_space("push_unsafe")),
hir::PopUnsafeBlock(..) => try!(self.word_space("pop_unsafe")),
hir::PushUnstableBlock => try!(self.word_space("push_unstable")),
hir::PopUnstableBlock => try!(self.word_space("pop_unstable")),
hir::DefaultBlock => (),
} }
try!(self.maybe_print_comment(blk.span.lo)); try!(self.maybe_print_comment(blk.span.lo));
try!(self.ann.pre(self, NodeBlock(blk))); try!(self.ann.pre(self, NodeBlock(blk)));
......
...@@ -269,7 +269,7 @@ pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState { ...@@ -269,7 +269,7 @@ pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {
(unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()), (unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
hir::UnsafeBlock(..) => hir::UnsafeBlock(..) =>
(hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count), (hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
hir::DefaultBlock => hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
(unsafety, self.def, self.unsafe_push_count), (unsafety, self.def, self.unsafe_push_count),
}; };
UnsafetyState{ def: def, UnsafetyState{ def: def,
......
...@@ -70,7 +70,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { ...@@ -70,7 +70,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
let placer = fld.fold_expr(placer); let placer = fld.fold_expr(placer);
let value_expr = fld.fold_expr(value_expr); let value_expr = fld.fold_expr(value_expr);
fld.cx.expr(span, ast::ExprBox(Some(placer), value_expr)) fld.cx.expr(span, ast::ExprInPlace(placer, value_expr))
} }
ast::ExprWhile(cond, body, opt_ident) => { ast::ExprWhile(cond, body, opt_ident) => {
......
...@@ -726,7 +726,7 @@ fn visit_expr(&mut self, e: &ast::Expr) { ...@@ -726,7 +726,7 @@ fn visit_expr(&mut self, e: &ast::Expr) {
} }
struct PostExpansionVisitor<'a> { struct PostExpansionVisitor<'a> {
context: &'a Context<'a> context: &'a Context<'a>,
} }
impl<'a> PostExpansionVisitor<'a> { impl<'a> PostExpansionVisitor<'a> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册