Skip to content

Commit e0c7486

Browse files
committed
Fix stability
1 parent bfffa9e commit e0c7486

File tree

8 files changed

+87
-31
lines changed

8 files changed

+87
-31
lines changed

src/librustc/middle/effect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
102102
fn visit_block(&mut self, block: &hir::Block) {
103103
let old_unsafe_context = self.unsafe_context;
104104
match block.rules {
105-
hir::DefaultBlock => {}
106105
hir::UnsafeBlock(source) => {
107106
// By default only the outermost `unsafe` block is
108107
// "used" and so nested unsafe blocks are pointless
@@ -131,6 +130,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
131130
self.unsafe_context.push_unsafe_count =
132131
self.unsafe_context.push_unsafe_count.checked_sub(1).unwrap();
133132
}
133+
hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock => {}
134134
}
135135

136136
visit::walk_block(self, block);

src/librustc/middle/stability.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt)
270270
let mut checker = Checker {
271271
tcx: tcx,
272272
active_features: active_features,
273-
used_features: FnvHashMap()
273+
used_features: FnvHashMap(),
274+
in_skip_block: 0,
274275
};
275276

276277
let krate = tcx.map.krate();
@@ -283,14 +284,23 @@ pub fn check_unstable_api_usage(tcx: &ty::ctxt)
283284
struct Checker<'a, 'tcx: 'a> {
284285
tcx: &'a ty::ctxt<'tcx>,
285286
active_features: FnvHashSet<InternedString>,
286-
used_features: FnvHashMap<InternedString, attr::StabilityLevel>
287+
used_features: FnvHashMap<InternedString, attr::StabilityLevel>,
288+
// Within a block where feature gate checking can be skipped.
289+
in_skip_block: u32,
287290
}
288291

289292
impl<'a, 'tcx> Checker<'a, 'tcx> {
290293
fn check(&mut self, id: DefId, span: Span, stab: &Option<&Stability>) {
291294
// Only the cross-crate scenario matters when checking unstable APIs
292295
let cross_crate = !id.is_local();
293-
if !cross_crate { return }
296+
if !cross_crate {
297+
return
298+
}
299+
300+
// We don't need to check for stability - presumably compiler generated code.
301+
if self.in_skip_block > 0 {
302+
return;
303+
}
294304

295305
match *stab {
296306
Some(&Stability { level: attr::Unstable, ref feature, ref reason, issue, .. }) => {
@@ -369,6 +379,21 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
369379
&mut |id, sp, stab| self.check(id, sp, stab));
370380
visit::walk_pat(self, pat)
371381
}
382+
383+
fn visit_block(&mut self, b: &hir::Block) {
384+
let old_skip_count = self.in_skip_block;
385+
match b.rules {
386+
hir::BlockCheckMode::PushUnstableBlock => {
387+
self.in_skip_block += 1;
388+
}
389+
hir::BlockCheckMode::PopUnstableBlock => {
390+
self.in_skip_block = self.in_skip_block.checked_sub(1).unwrap();
391+
}
392+
_ => {}
393+
}
394+
visit::walk_block(self, b);
395+
self.in_skip_block = old_skip_count;
396+
}
372397
}
373398

374399
/// Helper for discovering nodes to check for stability

src/librustc_front/hir.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,9 @@ pub enum BlockCheckMode {
574574
UnsafeBlock(UnsafeSource),
575575
PushUnsafeBlock(UnsafeSource),
576576
PopUnsafeBlock(UnsafeSource),
577+
// Within this block (but outside a PopUnstableBlock), we suspend checking of stability.
578+
PushUnstableBlock,
579+
PopUnstableBlock,
577580
}
578581

579582
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]

src/librustc_front/lowering.rs

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -749,12 +749,28 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
749749
P(hir::Expr {
750750
id: e.id,
751751
node: match e.node {
752+
// Issue #22181:
753+
// Eventually a desugaring for `box EXPR`
754+
// (similar to the desugaring above for `in PLACE BLOCK`)
755+
// should go here, desugaring
756+
//
757+
// to:
758+
//
759+
// let mut place = BoxPlace::make_place();
760+
// let raw_place = Place::pointer(&mut place);
761+
// let value = $value;
762+
// unsafe {
763+
// ::std::ptr::write(raw_place, value);
764+
// Boxed::finalize(place)
765+
// }
766+
//
767+
// But for now there are type-inference issues doing that.
752768
ExprBox(ref e) => {
753769
hir::ExprBox(lower_expr(lctx, e))
754770
}
755771

756772
// Desugar ExprBox: `in (PLACE) EXPR`
757-
ExprInPlace(Some(ref placer), ref value_expr) => {
773+
ExprInPlace(ref placer, ref value_expr) => {
758774
// to:
759775
//
760776
// let p = PLACE;
@@ -810,23 +826,43 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
810826
};
811827

812828
// pop_unsafe!(EXPR));
813-
let pop_unsafe_expr = pop_unsafe_expr(lctx, value_expr, e.span);
829+
let pop_unsafe_expr =
830+
signal_block_expr(lctx,
831+
vec![],
832+
signal_block_expr(lctx,
833+
vec![],
834+
value_expr,
835+
e.span,
836+
hir::PopUnstableBlock),
837+
e.span,
838+
hir::PopUnsafeBlock(hir::CompilerGenerated));
814839

815840
// push_unsafe!({
816-
// ptr::write(p_ptr, pop_unsafe!(<value_expr>));
841+
// std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
817842
// InPlace::finalize(place)
818843
// })
819844
let expr = {
820-
let call_move_val_init = hir::StmtSemi(make_call(
821-
lctx, &move_val_init, vec![expr_ident(lctx, e.span, p_ptr_ident), pop_unsafe_expr]), lctx.next_id());
845+
let call_move_val_init =
846+
hir::StmtSemi(make_call(lctx,
847+
&move_val_init,
848+
vec![expr_ident(lctx, e.span, p_ptr_ident),
849+
pop_unsafe_expr]),
850+
lctx.next_id());
822851
let call_move_val_init = respan(e.span, call_move_val_init);
823852

824853
let call = make_call(lctx, &inplace_finalize, vec![expr_ident(lctx, e.span, agent_ident)]);
825-
Some(push_unsafe_expr(lctx, vec![P(call_move_val_init)], call, e.span))
854+
signal_block_expr(lctx,
855+
vec![P(call_move_val_init)],
856+
call,
857+
e.span,
858+
hir::PushUnsafeBlock(hir::CompilerGenerated))
826859
};
827860

828-
let block = block_all(lctx, e.span, vec![s1, s2, s3], expr);
829-
return expr_block(lctx, block);
861+
return signal_block_expr(lctx,
862+
vec![s1, s2, s3],
863+
expr,
864+
e.span,
865+
hir::PushUnstableBlock);
830866
}
831867

832868
ExprVec(ref exprs) => {
@@ -1475,21 +1511,9 @@ fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Pa
14751511
path_global(span, idents)
14761512
}
14771513

1478-
fn push_unsafe_expr(lctx: &LoweringContext, stmts: Vec<P<hir::Stmt>>,
1479-
expr: P<hir::Expr>, span: Span)
1480-
-> P<hir::Expr> {
1481-
let rules = hir::PushUnsafeBlock(hir::CompilerGenerated);
1514+
fn signal_block_expr(lctx: &LoweringContext, stmts: Vec<P<hir::Stmt>>, expr: P<hir::Expr>, span: Span, rule: hir::BlockCheckMode) -> P<hir::Expr> {
14821515
expr_block(lctx, P(hir::Block {
1483-
rules: rules, span: span, id: lctx.next_id(),
1516+
rules: rule, span: span, id: lctx.next_id(),
14841517
stmts: stmts, expr: Some(expr),
14851518
}))
14861519
}
1487-
1488-
fn pop_unsafe_expr(lctx: &LoweringContext, expr: P<hir::Expr>, span: Span)
1489-
-> P<hir::Expr> {
1490-
let rules = hir::PopUnsafeBlock(hir::CompilerGenerated);
1491-
expr_block(lctx, P(hir::Block {
1492-
rules: rules, span: span, id: lctx.next_id(),
1493-
stmts: vec![], expr: Some(expr),
1494-
}))
1495-
}

src/librustc_front/print/pprust.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,8 +1089,12 @@ impl<'a> State<'a> {
10891089
close_box: bool)
10901090
-> io::Result<()> {
10911091
match blk.rules {
1092-
hir::UnsafeBlock(..) | hir::PushUnsafeBlock(..) => try!(self.word_space("unsafe")),
1093-
hir::DefaultBlock | hir::PopUnsafeBlock(..) => (),
1092+
hir::UnsafeBlock(..) => try!(self.word_space("unsafe")),
1093+
hir::PushUnsafeBlock(..) => try!(self.word_space("push_unsafe")),
1094+
hir::PopUnsafeBlock(..) => try!(self.word_space("pop_unsafe")),
1095+
hir::PushUnstableBlock => try!(self.word_space("push_unstable")),
1096+
hir::PopUnstableBlock => try!(self.word_space("pop_unstable")),
1097+
hir::DefaultBlock => (),
10941098
}
10951099
try!(self.maybe_print_comment(blk.span.lo));
10961100
try!(self.ann.pre(self, NodeBlock(blk)));

src/librustc_typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl UnsafetyState {
269269
(unsafety, blk.id, self.unsafe_push_count.checked_sub(1).unwrap()),
270270
hir::UnsafeBlock(..) =>
271271
(hir::Unsafety::Unsafe, blk.id, self.unsafe_push_count),
272-
hir::DefaultBlock =>
272+
hir::DefaultBlock | hir::PushUnstableBlock | hir:: PopUnstableBlock =>
273273
(unsafety, self.def, self.unsafe_push_count),
274274
};
275275
UnsafetyState{ def: def,

src/libsyntax/ext/expand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
7070

7171
let placer = fld.fold_expr(placer);
7272
let value_expr = fld.fold_expr(value_expr);
73-
fld.cx.expr(span, ast::ExprBox(Some(placer), value_expr))
73+
fld.cx.expr(span, ast::ExprInPlace(placer, value_expr))
7474
}
7575

7676
ast::ExprWhile(cond, body, opt_ident) => {

src/libsyntax/feature_gate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
726726
}
727727

728728
struct PostExpansionVisitor<'a> {
729-
context: &'a Context<'a>
729+
context: &'a Context<'a>,
730730
}
731731

732732
impl<'a> PostExpansionVisitor<'a> {

0 commit comments

Comments
 (0)