Skip to content

Commit

Permalink
move Scope behind an enum
Browse files Browse the repository at this point in the history
  • Loading branch information
arielb1 committed Sep 24, 2017
1 parent b6bce56 commit 8214ab1
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 37 deletions.
12 changes: 11 additions & 1 deletion src/librustc/ich/impls_ty.rs
Expand Up @@ -514,7 +514,17 @@ impl_stable_hash_for!(enum ty::cast::CastKind {
FnPtrAddrCast
});

impl_stable_hash_for!(enum ::middle::region::Scope {
impl_stable_hash_for!(struct ::middle::region::FirstStatementIndex { idx });

impl<'gcx> HashStable<StableHashingContext<'gcx>> for ::middle::region::Scope {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
self.data().hash_stable(hcx, hasher)
}
}

impl_stable_hash_for!(enum ::middle::region::ScopeData {
Node(local_id),
Destruction(local_id),
CallSite(local_id),
Expand Down
16 changes: 9 additions & 7 deletions src/librustc/infer/error_reporting/mod.rs
Expand Up @@ -72,6 +72,8 @@ use syntax::ast::DUMMY_NODE_ID;
use syntax_pos::{Pos, Span};
use errors::{DiagnosticBuilder, DiagnosticStyledString};

use rustc_data_structures::indexed_vec::Idx;

mod note;

mod need_type_info;
Expand Down Expand Up @@ -152,21 +154,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
return;
}
};
let scope_decorated_tag = match scope {
region::Scope::Node(_) => tag,
region::Scope::CallSite(_) => {
let scope_decorated_tag = match scope.data() {
region::ScopeData::Node(_) => tag,
region::ScopeData::CallSite(_) => {
"scope of call-site for function"
}
region::Scope::Arguments(_) => {
region::ScopeData::Arguments(_) => {
"scope of function body"
}
region::Scope::Destruction(_) => {
region::ScopeData::Destruction(_) => {
new_string = format!("destruction scope surrounding {}", tag);
&new_string[..]
}
region::Scope::Remainder(r) => {
region::ScopeData::Remainder(r) => {
new_string = format!("block suffix following statement {}",
r.first_statement_index);
r.first_statement_index.index());
&new_string[..]
}
};
Expand Down
104 changes: 85 additions & 19 deletions src/librustc/middle/region.rs
Expand Up @@ -31,6 +31,7 @@ use hir::def_id::DefId;
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local};
use mir::transform::MirSource;
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};

Expand Down Expand Up @@ -96,7 +97,12 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
/// actually attach a more meaningful ordering to scopes than the one
/// generated via deriving here.
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
pub enum Scope {
pub struct Scope {
pub scope_data: ScopeData
}

#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
pub enum ScopeData {
Node(hir::ItemLocalId),

// Scope of the call-site for a function or closure
Expand Down Expand Up @@ -135,7 +141,64 @@ pub enum Scope {
RustcDecodable, Debug, Copy)]
pub struct BlockRemainder {
pub block: hir::ItemLocalId,
pub first_statement_index: u32,
pub first_statement_index: FirstStatementIndex,
}

#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
RustcDecodable, Debug, Copy)]
pub struct FirstStatementIndex { pub idx: u32 }

pub const FIRST_STATEMENT_MAX: usize = !0u32 as usize;

impl Idx for FirstStatementIndex {
fn new(idx: usize) -> Self {
assert!(idx <= FIRST_STATEMENT_MAX);
FirstStatementIndex { idx: idx as u32 }
}

fn index(self) -> usize {
self.idx as usize
}
}

impl From<ScopeData> for Scope {
#[inline]
fn from(scope_data: ScopeData) -> Self {
Self { scope_data }
}
}

#[allow(non_snake_case)]
impl Scope {
#[inline]
pub fn data(self) -> ScopeData {
self.scope_data
}

#[inline]
pub fn Node(id: hir::ItemLocalId) -> Self {
Self::from(ScopeData::Node(id))
}

#[inline]
pub fn CallSite(id: hir::ItemLocalId) -> Self {
Self::from(ScopeData::CallSite(id))
}

#[inline]
pub fn Arguments(id: hir::ItemLocalId) -> Self {
Self::from(ScopeData::Arguments(id))
}

#[inline]
pub fn Destruction(id: hir::ItemLocalId) -> Self {
Self::from(ScopeData::Destruction(id))
}

#[inline]
pub fn Remainder(r: BlockRemainder) -> Self {
Self::from(ScopeData::Remainder(r))
}
}

impl Scope {
Expand All @@ -144,15 +207,16 @@ impl Scope {
/// NB: likely to be replaced as API is refined; e.g. pnkfelix
/// anticipates `fn entry_node_id` and `fn each_exit_node_id`.
pub fn item_local_id(&self) -> hir::ItemLocalId {
match *self {
Scope::Node(id) => id,
// TODO: killme
match self.data() {
ScopeData::Node(id) => id,

// These cases all return rough approximations to the
// precise scope denoted by `self`.
Scope::Remainder(br) => br.block,
Scope::Destruction(id) |
Scope::CallSite(id) |
Scope::Arguments(id) => id,
ScopeData::Remainder(br) => br.block,
ScopeData::Destruction(id) |
ScopeData::CallSite(id) |
ScopeData::Arguments(id) => id,
}
}

Expand All @@ -177,7 +241,7 @@ impl Scope {
return DUMMY_SP;
}
let span = tcx.hir.span(node_id);
if let Scope::Remainder(r) = *self {
if let ScopeData::Remainder(r) = self.data() {
if let hir::map::NodeBlock(ref blk) = tcx.hir.get(node_id) {
// Want span for scope starting after the
// indexed statement and ending at end of
Expand All @@ -187,7 +251,7 @@ impl Scope {
// (This is the special case aluded to in the
// doc-comment for this method)

let stmt_span = blk.stmts[r.first_statement_index as usize].span;
let stmt_span = blk.stmts[r.first_statement_index.index()].span;

// To avoid issues with macro-generated spans, the span
// of the statement must be nested in that of the block.
Expand Down Expand Up @@ -387,7 +451,7 @@ impl<'tcx> ScopeTree {
}

// record the destruction scopes for later so we can query them
if let Scope::Destruction(n) = child {
if let ScopeData::Destruction(n) = child.data() {
self.destruction_scopes.insert(n, child);
}
}
Expand Down Expand Up @@ -482,8 +546,8 @@ impl<'tcx> ScopeTree {
let mut id = Scope::Node(expr_id);

while let Some(&p) = self.parent_map.get(&id) {
match p {
Scope::Destruction(..) => {
match p.data() {
ScopeData::Destruction(..) => {
debug!("temporary_scope({:?}) = {:?} [enclosing]",
expr_id, id);
return Some(id);
Expand Down Expand Up @@ -573,9 +637,9 @@ impl<'tcx> ScopeTree {
// infer::region_inference for more details.
let a_root_scope = a_ancestors[a_index];
let b_root_scope = a_ancestors[a_index];
return match (a_root_scope, b_root_scope) {
(Scope::Destruction(a_root_id),
Scope::Destruction(b_root_id)) => {
return match (a_root_scope.data(), b_root_scope.data()) {
(ScopeData::Destruction(a_root_id),
ScopeData::Destruction(b_root_id)) => {
if self.closure_is_enclosed_by(a_root_id, b_root_id) {
// `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a`
scope_b
Expand Down Expand Up @@ -764,7 +828,7 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
visitor.enter_scope(
Scope::Remainder(BlockRemainder {
block: blk.hir_id.local_id,
first_statement_index: i as u32
first_statement_index: FirstStatementIndex::new(i)
})
);
visitor.cx.var_parent = visitor.cx.parent;
Expand Down Expand Up @@ -915,8 +979,10 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
// Keep traversing up while we can.
match visitor.scope_tree.parent_map.get(&scope) {
// Don't cross from closure bodies to their parent.
Some(&Scope::CallSite(_)) => break,
Some(&superscope) => scope = superscope,
Some(&superscope) => match superscope.data() {
ScopeData::CallSite(_) => break,
_ => scope = superscope
},
None => break
}
}
Expand Down
15 changes: 8 additions & 7 deletions src/librustc/util/ppaux.rs
Expand Up @@ -26,6 +26,7 @@ use std::fmt;
use std::usize;

use rustc_const_math::ConstInt;
use rustc_data_structures::indexed_vec::Idx;
use syntax::abi::Abi;
use syntax::ast::CRATE_NODE_ID;
use syntax::symbol::Symbol;
Expand Down Expand Up @@ -530,17 +531,17 @@ impl fmt::Display for ty::RegionKind {
write!(f, "{}", br)
}
ty::ReScope(scope) if identify_regions() => {
match scope {
region::Scope::Node(id) =>
match scope.data() {
region::ScopeData::Node(id) =>
write!(f, "'{}s", id.as_usize()),
region::Scope::CallSite(id) =>
region::ScopeData::CallSite(id) =>
write!(f, "'{}cs", id.as_usize()),
region::Scope::Arguments(id) =>
region::ScopeData::Arguments(id) =>
write!(f, "'{}as", id.as_usize()),
region::Scope::Destruction(id) =>
region::ScopeData::Destruction(id) =>
write!(f, "'{}ds", id.as_usize()),
region::Scope::Remainder(BlockRemainder { block, first_statement_index }) =>
write!(f, "'{}_{}rs", block.as_usize(), first_statement_index),
region::ScopeData::Remainder(BlockRemainder { block, first_statement_index }) =>
write!(f, "'{}_{}rs", block.as_usize(), first_statement_index.index()),
}
}
ty::ReVar(region_vid) if identify_regions() => {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/scope.rs
Expand Up @@ -514,8 +514,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// The outermost scope (`scopes[0]`) will be the `CallSiteScope`.
// We want `scopes[1]`, which is the `ParameterScope`.
assert!(self.scopes.len() >= 2);
assert!(match self.scopes[1].region_scope {
region::Scope::Arguments(_) => true,
assert!(match self.scopes[1].region_scope.data() {
region::ScopeData::Arguments(_) => true,
_ => false,
});
self.scopes[1].region_scope
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_mir/hair/cx/block.rs
Expand Up @@ -14,6 +14,8 @@ use hair::cx::to_ref::ToRef;
use rustc::middle::region::{self, BlockRemainder};
use rustc::hir;

use rustc_data_structures::indexed_vec::Idx;

impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
type Output = Block<'tcx>;

Expand Down Expand Up @@ -61,7 +63,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
hir::DeclLocal(ref local) => {
let remainder_scope = region::Scope::Remainder(BlockRemainder {
block: block_id,
first_statement_index: index as u32,
first_statement_index: region::FirstStatementIndex::new(index),
});

let pattern = cx.pattern_from_hir(&local.pat);
Expand Down

0 comments on commit 8214ab1

Please sign in to comment.