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
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
@@ -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;
@@ -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),
}
}
}
12 changes: 4 additions & 8 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
@@ -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);
@@ -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(_) => {},
};
}
}
32 changes: 13 additions & 19 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}
}
@@ -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)))
@@ -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)))
@@ -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),
),
42 changes: 1 addition & 41 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
@@ -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)]
10 changes: 0 additions & 10 deletions src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
@@ -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>,
20 changes: 5 additions & 15 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
@@ -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> {
@@ -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(),
}
}

@@ -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| {
@@ -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,
@@ -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,
12 changes: 4 additions & 8 deletions src/librustc_mir/hair/cx/expr.rs
Original file line number Diff line number Diff line change
@@ -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, _) => {
31 changes: 15 additions & 16 deletions src/librustc_passes/loops.rs
Original file line number Diff line number Diff line change
@@ -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 {
@@ -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)
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -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