Skip to content

Commit

Permalink
Remove hir::ScopeTarget
Browse files Browse the repository at this point in the history
When we want to implement label-break-value,
we can't really decide whether to emit ScopeTarget::Loop or
ScopeTarget::Block in the code that is supposed to create it.
So we get rid of it and reconstruct the information when
needed.
  • Loading branch information
est31 committed May 15, 2018
1 parent eca0da5 commit 3ef481a
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 85 deletions.
14 changes: 5 additions & 9 deletions src/librustc/cfg/construct.rs
Expand Up @@ -582,19 +582,16 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
scope_cf_kind: ScopeCfKind) -> (region::Scope, CFGIndex) {

match destination.target_id {
hir::ScopeTarget::Block(block_expr_id) => {
hir::LoopIdResult::Ok(loop_id) => {
for b in &self.breakable_block_scopes {
if b.block_expr_id == self.tcx.hir.node_to_hir_id(block_expr_id).local_id {
let scope_id = self.tcx.hir.node_to_hir_id(block_expr_id).local_id;
if b.block_expr_id == self.tcx.hir.node_to_hir_id(loop_id).local_id {
let scope_id = self.tcx.hir.node_to_hir_id(loop_id).local_id;
return (region::Scope::Node(scope_id), match scope_cf_kind {
ScopeCfKind::Break => b.break_index,
ScopeCfKind::Continue => bug!("can't continue to block"),
});
}
}
span_bug!(expr.span, "no block expr for id {}", block_expr_id);
}
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(loop_id)) => {
for l in &self.loop_scopes {
if l.loop_id == self.tcx.hir.node_to_hir_id(loop_id).local_id {
let scope_id = self.tcx.hir.node_to_hir_id(loop_id).local_id;
Expand All @@ -604,10 +601,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
});
}
}
span_bug!(expr.span, "no loop scope for id {}", loop_id);
span_bug!(expr.span, "no scope for id {}", loop_id);
}
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
span_bug!(expr.span, "loop scope error: {}", err),
hir::LoopIdResult::Err(err) => span_bug!(expr.span, "scope error: {}", err),
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions src/librustc/hir/intravisit.rs
Expand Up @@ -1039,10 +1039,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
if let Some(ref label) = destination.label {
visitor.visit_label(label);
match destination.target_id {
ScopeTarget::Block(node_id) |
ScopeTarget::Loop(LoopIdResult::Ok(node_id)) =>
LoopIdResult::Ok(node_id) =>
visitor.visit_def_mention(Def::Label(node_id)),
ScopeTarget::Loop(LoopIdResult::Err(_)) => {},
LoopIdResult::Err(_) => {},
};
}
walk_list!(visitor, visit_expr, opt_expr);
Expand All @@ -1051,10 +1050,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
if let Some(ref label) = destination.label {
visitor.visit_label(label);
match destination.target_id {
ScopeTarget::Block(_) => bug!("can't `continue` to a non-loop block"),
ScopeTarget::Loop(LoopIdResult::Ok(node_id)) =>
LoopIdResult::Ok(node_id) =>
visitor.visit_def_mention(Def::Label(node_id)),
ScopeTarget::Loop(LoopIdResult::Err(_)) => {},
LoopIdResult::Err(_) => {},
};
}
}
Expand Down
28 changes: 11 additions & 17 deletions src/librustc/hir/lowering.rs
Expand Up @@ -928,29 +928,27 @@ impl<'a> LoweringContext<'a> {
fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
match destination {
Some((id, label)) => {
let target = if let Def::Label(loop_id) = self.expect_full_def(id) {
let target_id = if let Def::Label(loop_id) = self.expect_full_def(id) {
hir::LoopIdResult::Ok(self.lower_node_id(loop_id).node_id)
} else {
hir::LoopIdResult::Err(hir::LoopIdError::UnresolvedLabel)
};
hir::Destination {
label: self.lower_label(Some(label)),
target_id: hir::ScopeTarget::Loop(target),
target_id,
}
}
None => {
let loop_id = self.loop_scopes
let target_id = self.loop_scopes
.last()
.map(|innermost_loop_id| *innermost_loop_id);
.map(|innermost_loop_id| *innermost_loop_id)
.map(|id| Ok(self.lower_node_id(id).node_id))
.unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
.into();

hir::Destination {
label: None,
target_id: hir::ScopeTarget::Loop(
loop_id
.map(|id| Ok(self.lower_node_id(id).node_id))
.unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
.into(),
),
target_id,
}
}
}
Expand Down Expand Up @@ -3193,9 +3191,7 @@ impl<'a> LoweringContext<'a> {
let destination = if self.is_in_loop_condition && opt_label.is_none() {
hir::Destination {
label: None,
target_id: hir::ScopeTarget::Loop(
Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
),
target_id: Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
}
} else {
self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
Expand All @@ -3209,9 +3205,7 @@ impl<'a> LoweringContext<'a> {
hir::ExprAgain(if self.is_in_loop_condition && opt_label.is_none() {
hir::Destination {
label: None,
target_id: hir::ScopeTarget::Loop(
Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
),
target_id: Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
}
} else {
self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
Expand Down Expand Up @@ -3604,7 +3598,7 @@ impl<'a> LoweringContext<'a> {
hir::ExprBreak(
hir::Destination {
label: None,
target_id: hir::ScopeTarget::Block(catch_node),
target_id: hir::LoopIdResult::Ok(catch_node),
},
Some(from_err_expr),
),
Expand Down
17 changes: 5 additions & 12 deletions src/librustc/hir/mod.rs
Expand Up @@ -1526,18 +1526,11 @@ impl From<Result<NodeId, LoopIdError>> for LoopIdResult {
}
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum ScopeTarget {
Block(NodeId),
Loop(LoopIdResult),
}

impl ScopeTarget {
pub fn opt_id(self) -> Option<NodeId> {
impl LoopIdResult {
pub fn ok(self) -> Option<NodeId> {
match self {
ScopeTarget::Block(node_id) |
ScopeTarget::Loop(LoopIdResult::Ok(node_id)) => Some(node_id),
ScopeTarget::Loop(LoopIdResult::Err(_)) => None,
LoopIdResult::Ok(node_id) => Some(node_id),
LoopIdResult::Err(_) => None,
}
}
}
Expand All @@ -1549,7 +1542,7 @@ pub struct Destination {

// These errors are caught and then reported during the diagnostics pass in
// librustc_passes/loops.rs
pub target_id: ScopeTarget,
pub target_id: LoopIdResult,
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
Expand Down
5 changes: 0 additions & 5 deletions src/librustc/ich/impls_hir.rs
Expand Up @@ -667,11 +667,6 @@ impl_stable_hash_for!(enum hir::LoopIdError {
UnresolvedLabel
});

impl_stable_hash_for!(enum hir::ScopeTarget {
Block(node_id),
Loop(loop_id_result)
});

impl<'a> HashStable<StableHashingContext<'a>> for ast::Ident {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
Expand Down
18 changes: 5 additions & 13 deletions src/librustc/middle/liveness.rs
Expand Up @@ -571,9 +571,6 @@ struct Liveness<'a, 'tcx: 'a> {
// it probably doesn't now)
break_ln: NodeMap<LiveNode>,
cont_ln: NodeMap<LiveNode>,

// mappings from node ID to LiveNode for "breakable" blocks-- currently only `catch {...}`
breakable_block_ln: NodeMap<LiveNode>,
}

impl<'a, 'tcx> Liveness<'a, 'tcx> {
Expand Down Expand Up @@ -601,7 +598,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
users: vec![invalid_users(); num_live_nodes * num_vars],
break_ln: NodeMap(),
cont_ln: NodeMap(),
breakable_block_ln: NodeMap(),
}
}

Expand Down Expand Up @@ -870,7 +866,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn propagate_through_block(&mut self, blk: &hir::Block, succ: LiveNode)
-> LiveNode {
if blk.targeted_by_break {
self.breakable_block_ln.insert(blk.id, succ);
self.break_ln.insert(blk.id, succ);
}
let succ = self.propagate_through_opt_expr(blk.expr.as_ref().map(|e| &**e), succ);
blk.stmts.iter().rev().fold(succ, |succ, stmt| {
Expand Down Expand Up @@ -1055,11 +1051,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprBreak(label, ref opt_expr) => {
// Find which label this break jumps to
let target = match label.target_id {
hir::ScopeTarget::Block(node_id) =>
self.breakable_block_ln.get(&node_id),
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(node_id)) =>
self.break_ln.get(&node_id),
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
hir::LoopIdResult::Ok(node_id) => self.break_ln.get(&node_id),
hir::LoopIdResult::Err(err) =>
span_bug!(expr.span, "loop scope error: {}", err),
}.map(|x| *x);

Expand All @@ -1075,9 +1068,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprAgain(label) => {
// Find which label this expr continues to
let sc = match label.target_id {
hir::ScopeTarget::Block(_) => bug!("can't `continue` to a non-loop block"),
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(node_id)) => node_id,
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
hir::LoopIdResult::Ok(node_id) => node_id,
hir::LoopIdResult::Err(err) =>
span_bug!(expr.span, "loop scope error: {}", err),
};

Expand Down
10 changes: 4 additions & 6 deletions src/librustc_mir/hair/cx/expr.rs
Expand Up @@ -536,22 +536,20 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
hir::ExprRet(ref v) => ExprKind::Return { value: v.to_ref() },
hir::ExprBreak(dest, ref value) => {
match dest.target_id {
hir::ScopeTarget::Block(target_id) |
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(target_id)) => ExprKind::Break {
hir::LoopIdResult::Ok(target_id) => ExprKind::Break {
label: region::Scope::Node(cx.tcx.hir.node_to_hir_id(target_id).local_id),
value: value.to_ref(),
},
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
hir::LoopIdResult::Err(err) =>
bug!("invalid loop id for break: {}", err)
}
}
hir::ExprAgain(dest) => {
match dest.target_id {
hir::ScopeTarget::Block(_) => bug!("cannot continue to blocks"),
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(loop_id)) => ExprKind::Continue {
hir::LoopIdResult::Ok(loop_id) => ExprKind::Continue {
label: region::Scope::Node(cx.tcx.hir.node_to_hir_id(loop_id).local_id),
},
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
hir::LoopIdResult::Err(err) =>
bug!("invalid loop id for continue: {}", err)
}
}
Expand Down
32 changes: 16 additions & 16 deletions src/librustc_passes/loops.rs
Expand Up @@ -85,20 +85,21 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
self.with_context(Closure, |v| v.visit_nested_body(b));
}
hir::ExprBreak(label, ref opt_expr) => {
let loop_id = match label.target_id {
hir::ScopeTarget::Block(_) => return,
hir::ScopeTarget::Loop(loop_res) => {
match loop_res.into() {
Ok(loop_id) => loop_id,
Err(hir::LoopIdError::OutsideLoopScope) => ast::DUMMY_NODE_ID,
Err(hir::LoopIdError::UnlabeledCfInWhileCondition) => {
self.emit_unlabled_cf_in_while_condition(e.span, "break");
ast::DUMMY_NODE_ID
},
Err(hir::LoopIdError::UnresolvedLabel) => ast::DUMMY_NODE_ID,
}
}
let loop_id = match label.target_id.into() {
Ok(loop_id) => loop_id,
Err(hir::LoopIdError::OutsideLoopScope) => ast::DUMMY_NODE_ID,
Err(hir::LoopIdError::UnlabeledCfInWhileCondition) => {
self.emit_unlabled_cf_in_while_condition(e.span, "break");
ast::DUMMY_NODE_ID
},
Err(hir::LoopIdError::UnresolvedLabel) => ast::DUMMY_NODE_ID,
};
if loop_id != ast::DUMMY_NODE_ID {
match self.hir_map.find(loop_id).unwrap() {
hir::map::NodeBlock(_) => return,
_=> (),
}
}

if opt_expr.is_some() {
let loop_kind = if loop_id == ast::DUMMY_NODE_ID {
Expand Down Expand Up @@ -132,9 +133,8 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
self.require_loop("break", e.span);
}
hir::ExprAgain(label) => {
if let hir::ScopeTarget::Loop(
hir::LoopIdResult::Err(
hir::LoopIdError::UnlabeledCfInWhileCondition)) = label.target_id {
if let hir::LoopIdResult::Err(
hir::LoopIdError::UnlabeledCfInWhileCondition) = label.target_id {
self.emit_unlabled_cf_in_while_condition(e.span, "continue");
}
self.require_loop("continue", e.span)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Expand Up @@ -3723,7 +3723,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
tcx.mk_nil()
}
hir::ExprBreak(destination, ref expr_opt) => {
if let Some(target_id) = destination.target_id.opt_id() {
if let Some(target_id) = destination.target_id.ok() {
let (e_ty, cause);
if let Some(ref e) = *expr_opt {
// If this is a break with a value, we need to type-check
Expand Down

0 comments on commit 3ef481a

Please sign in to comment.