1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 use tcx
::pattern
::PatNode
;
15 use tcx
::rustc
::middle
::region
::{BlockRemainder, CodeExtentData}
;
16 use tcx
::rustc_front
::hir
;
18 use tcx
::syntax
::ptr
::P
;
19 use tcx
::to_ref
::ToRef
;
21 impl<'a
,'tcx
:'a
> Mirror
<Cx
<'a
,'tcx
>> for &'tcx hir
::Block
{
22 type Output
= Block
<Cx
<'a
,'tcx
>>;
24 fn make_mirror(self, cx
: &mut Cx
<'a
,'tcx
>) -> Block
<Cx
<'a
,'tcx
>> {
25 // We have to eagerly translate the "spine" of the statements
26 // in order to get the lexical scoping correctly.
27 let stmts
= mirror_stmts(cx
, self.id
, self.stmts
.iter().enumerate());
29 extent
: cx
.tcx
.region_maps
.node_extent(self.id
),
32 expr
: self.expr
.to_ref()
37 impl<'a
,'tcx
:'a
> Mirror
<Cx
<'a
,'tcx
>> for &'tcx hir
::Stmt
{
38 type Output
= Stmt
<Cx
<'a
,'tcx
>>;
40 fn make_mirror(self, _cx
: &mut Cx
<'a
,'tcx
>) -> Stmt
<Cx
<'a
,'tcx
>> {
41 // In order to get the scoping correct, we eagerly mirror
42 // statements when we translate the enclosing block, so we
43 // should in fact never get to this point.
44 panic
!("statements are eagerly mirrored");
48 fn mirror_stmts
<'a
,'tcx
:'a
,STMTS
>(cx
: &mut Cx
<'a
,'tcx
>,
49 block_id
: ast
::NodeId
,
51 -> Vec
<StmtRef
<Cx
<'a
,'tcx
>>>
52 where STMTS
: Iterator
<Item
=(usize, &'tcx P
<hir
::Stmt
>)>
54 let mut result
= vec
![];
55 while let Some((index
, stmt
)) = stmts
.next() {
57 hir
::StmtExpr(ref expr
, id
) | hir
::StmtSemi(ref expr
, id
) =>
60 Box
::new(Stmt
{ span
: stmt
.span
,
61 kind
: StmtKind
::Expr
{
62 scope
: cx
.tcx
.region_maps
.node_extent(id
),
63 expr
: expr
.to_ref() } }))),
65 hir
::StmtDecl(ref decl
, id
) => {
67 hir
::DeclItem(..) => { /* ignore for purposes of the MIR */ }
68 hir
::DeclLocal(ref local
) => {
69 let remainder_extent
= CodeExtentData
::Remainder(BlockRemainder
{
71 first_statement_index
: index
as u32
73 let remainder_extent
=
74 cx
.tcx
.region_maps
.lookup_code_extent(remainder_extent
);
76 // pull in all following statements, since
77 // they are within the scope of this let:
78 let following_stmts
= mirror_stmts(cx
, block_id
, stmts
);
85 remainder_scope
: remainder_extent
,
86 init_scope
: cx
.tcx
.region_maps
.node_extent(id
),
87 pattern
: PatNode
::irrefutable(&local
.pat
).to_ref(),
88 initializer
: local
.init
.to_ref(),
89 stmts
: following_stmts
102 pub fn to_expr_ref
<'a
,'tcx
:'a
>(cx
: &mut Cx
<'a
,'tcx
>,
103 block
: &'tcx hir
::Block
)
104 -> ExprRef
<Cx
<'a
, 'tcx
>> {
105 let block_ty
= cx
.tcx
.node_id_to_type(block
.id
);
106 let temp_lifetime
= cx
.tcx
.region_maps
.temporary_scope(block
.id
);
109 temp_lifetime
: temp_lifetime
,
111 kind
: ExprKind
::Block { body: block }