Skip to content

Remove ScopeTarget and LoopIdResult #50750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions src/librustc/cfg/construct.rs
Original file line number Diff line number Diff line change
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) => {
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),
Err(err) => span_bug!(expr.span, "scope error: {}", err),
}
}
}
Expand Down
12 changes: 4 additions & 8 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,10 +1039,8 @@ 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)) =>
visitor.visit_def_mention(Def::Label(node_id)),
ScopeTarget::Loop(LoopIdResult::Err(_)) => {},
Ok(node_id) => visitor.visit_def_mention(Def::Label(node_id)),
Err(_) => {},
};
}
walk_list!(visitor, visit_expr, opt_expr);
Expand All @@ -1051,10 +1049,8 @@ 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)) =>
visitor.visit_def_mention(Def::Label(node_id)),
ScopeTarget::Loop(LoopIdResult::Err(_)) => {},
Ok(node_id) => visitor.visit_def_mention(Def::Label(node_id)),
Err(_) => {},
};
}
}
Expand Down
32 changes: 13 additions & 19 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
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) {
hir::LoopIdResult::Ok(self.lower_node_id(loop_id).node_id)
let target_id = if let Def::Label(loop_id) = self.expect_full_def(id) {
Ok(self.lower_node_id(loop_id).node_id)
} else {
hir::LoopIdResult::Err(hir::LoopIdError::UnresolvedLabel)
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: Ok(catch_node),
},
Some(from_err_expr),
),
Expand Down
42 changes: 1 addition & 41 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1502,54 +1502,14 @@ impl fmt::Display for LoopIdError {
}
}

// FIXME(cramertj) this should use `Result` once master compiles w/ a vesion of Rust where
// `Result` implements `Encodable`/`Decodable`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum LoopIdResult {
Ok(NodeId),
Err(LoopIdError),
}
impl Into<Result<NodeId, LoopIdError>> for LoopIdResult {
fn into(self) -> Result<NodeId, LoopIdError> {
match self {
LoopIdResult::Ok(ok) => Ok(ok),
LoopIdResult::Err(err) => Err(err),
}
}
}
impl From<Result<NodeId, LoopIdError>> for LoopIdResult {
fn from(res: Result<NodeId, LoopIdError>) -> Self {
match res {
Ok(ok) => LoopIdResult::Ok(ok),
Err(err) => LoopIdResult::Err(err),
}
}
}

#[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> {
match self {
ScopeTarget::Block(node_id) |
ScopeTarget::Loop(LoopIdResult::Ok(node_id)) => Some(node_id),
ScopeTarget::Loop(LoopIdResult::Err(_)) => None,
}
}
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub struct Destination {
// This is `Some(_)` iff there is an explicit user-specified `label
pub label: Option<Label>,

// These errors are caught and then reported during the diagnostics pass in
// librustc_passes/loops.rs
pub target_id: ScopeTarget,
pub target_id: Result<NodeId, LoopIdError>,
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
Expand Down
10 changes: 0 additions & 10 deletions src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,22 +656,12 @@ impl_stable_hash_for!(struct hir::Destination {

impl_stable_hash_for_spanned!(ast::Ident);

impl_stable_hash_for!(enum hir::LoopIdResult {
Ok(node_id),
Err(loop_id_error)
});

impl_stable_hash_for!(enum hir::LoopIdError {
OutsideLoopScope,
UnlabeledCfInWhileCondition,
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
20 changes: 5 additions & 15 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
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,12 +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)) =>
span_bug!(expr.span, "loop scope error: {}", err),
Ok(node_id) => self.break_ln.get(&node_id),
Err(err) => span_bug!(expr.span, "loop scope error: {}", err),
}.map(|x| *x);

// Now that we know the label we're going to,
Expand All @@ -1075,10 +1067,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)) =>
span_bug!(expr.span, "loop scope error: {}", err),
Ok(node_id) => node_id,
Err(err) => span_bug!(expr.span, "loop scope error: {}", err),
};

// Now that we know the label we're going to,
Expand Down
12 changes: 4 additions & 8 deletions src/librustc_mir/hair/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,23 +536,19 @@ 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 {
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)) =>
bug!("invalid loop id for break: {}", err)
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 {
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)) =>
bug!("invalid loop id for continue: {}", err)
Err(err) => bug!("invalid loop id for continue: {}", err)
}
}
hir::ExprMatch(ref discr, ref arms, _) => {
Expand Down
31 changes: 15 additions & 16 deletions src/librustc_passes/loops.rs
Original file line number Diff line number Diff line change
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,7 @@ 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 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
Original file line number Diff line number Diff line change
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 Ok(target_id) = destination.target_id {
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