Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
719a5916
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
719a5916
编写于
5月 31, 2016
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
mir: distinguish between variable visibility scopes and SEME scopes.
上级
f3525503
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
259 addition
and
257 deletion
+259
-257
src/librustc/mir/repr.rs
src/librustc/mir/repr.rs
+20
-17
src/librustc/mir/visit.rs
src/librustc/mir/visit.rs
+18
-18
src/librustc_mir/build/block.rs
src/librustc_mir/build/block.rs
+27
-12
src/librustc_mir/build/cfg.rs
src/librustc_mir/build/cfg.rs
+4
-4
src/librustc_mir/build/expr/as_lvalue.rs
src/librustc_mir/build/expr/as_lvalue.rs
+1
-1
src/librustc_mir/build/expr/as_operand.rs
src/librustc_mir/build/expr/as_operand.rs
+1
-1
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/build/expr/as_rvalue.rs
+2
-2
src/librustc_mir/build/expr/as_temp.rs
src/librustc_mir/build/expr/as_temp.rs
+1
-1
src/librustc_mir/build/expr/into.rs
src/librustc_mir/build/expr/into.rs
+1
-1
src/librustc_mir/build/expr/stmt.rs
src/librustc_mir/build/expr/stmt.rs
+1
-1
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/mod.rs
+32
-46
src/librustc_mir/build/misc.rs
src/librustc_mir/build/misc.rs
+1
-1
src/librustc_mir/build/mod.rs
src/librustc_mir/build/mod.rs
+41
-19
src/librustc_mir/build/scope.rs
src/librustc_mir/build/scope.rs
+34
-22
src/librustc_mir/pretty.rs
src/librustc_mir/pretty.rs
+57
-79
src/librustc_mir/transform/promote_consts.rs
src/librustc_mir/transform/promote_consts.rs
+3
-3
src/librustc_trans/debuginfo/create_scope_map.rs
src/librustc_trans/debuginfo/create_scope_map.rs
+7
-7
src/librustc_trans/mir/mod.rs
src/librustc_trans/mir/mod.rs
+7
-10
src/test/debuginfo/function-prologue-stepping-no-stack-check.rs
...st/debuginfo/function-prologue-stepping-no-stack-check.rs
+1
-12
未找到文件。
src/librustc/mir/repr.rs
浏览文件 @
719a5916
...
...
@@ -32,9 +32,9 @@ pub struct Mir<'tcx> {
/// that indexes into this vector.
pub
basic_blocks
:
Vec
<
BasicBlockData
<
'tcx
>>
,
/// List of
lexical scopes; these are referenced by statements and
///
used (eventually) for debuginfo. Indexed by a `ScopeId
`.
pub
scopes
:
Vec
<
ScopeData
>
,
/// List of
visibility (lexical) scopes; these are referenced by statements
///
and used (eventually) for debuginfo. Indexed by a `VisibilityScope
`.
pub
visibility_scopes
:
Vec
<
Visibility
ScopeData
>
,
/// Rvalues promoted from this function, such as borrows of constants.
/// Each of them is the Mir of a constant with the fn's type parameters
...
...
@@ -173,7 +173,7 @@ pub struct VarDecl<'tcx> {
pub
ty
:
Ty
<
'tcx
>
,
/// scope in which variable was declared
pub
scope
:
ScopeId
,
pub
scope
:
VisibilityScope
,
/// span where variable was declared
pub
span
:
Span
,
...
...
@@ -276,7 +276,7 @@ pub struct BasicBlockData<'tcx> {
#[derive(Clone,
Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
Terminator
<
'tcx
>
{
pub
span
:
Span
,
pub
scope
:
ScopeId
,
pub
scope
:
VisibilityScope
,
pub
kind
:
TerminatorKind
<
'tcx
>
}
...
...
@@ -588,7 +588,7 @@ pub enum AssertMessage<'tcx> {
#[derive(Clone,
RustcEncodable,
RustcDecodable)]
pub
struct
Statement
<
'tcx
>
{
pub
span
:
Span
,
pub
scope
:
ScopeId
,
pub
scope
:
VisibilityScope
,
pub
kind
:
StatementKind
<
'tcx
>
,
}
...
...
@@ -754,29 +754,32 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
///////////////////////////////////////////////////////////////////////////
// Scopes
impl
Index
<
ScopeId
>
for
Vec
<
ScopeData
>
{
type
Output
=
ScopeData
;
impl
Index
<
VisibilityScope
>
for
Vec
<
Visibility
ScopeData
>
{
type
Output
=
Visibility
ScopeData
;
#[inline]
fn
index
(
&
self
,
index
:
ScopeId
)
->
&
ScopeData
{
fn
index
(
&
self
,
index
:
VisibilityScope
)
->
&
Visibility
ScopeData
{
&
self
[
index
.index
()]
}
}
impl
IndexMut
<
ScopeId
>
for
Vec
<
ScopeData
>
{
impl
IndexMut
<
VisibilityScope
>
for
Vec
<
Visibility
ScopeData
>
{
#[inline]
fn
index_mut
(
&
mut
self
,
index
:
ScopeId
)
->
&
mut
ScopeData
{
fn
index_mut
(
&
mut
self
,
index
:
VisibilityScope
)
->
&
mut
Visibility
ScopeData
{
&
mut
self
[
index
.index
()]
}
}
#[derive(Copy,
Clone,
Debug,
Hash,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable)]
pub
struct
ScopeId
(
u32
);
pub
struct
VisibilityScope
(
u32
);
impl
ScopeId
{
pub
fn
new
(
index
:
usize
)
->
ScopeId
{
/// The visibility scope all arguments go into.
pub
const
ARGUMENT_VISIBILITY_SCOPE
:
VisibilityScope
=
VisibilityScope
(
0
);
impl
VisibilityScope
{
pub
fn
new
(
index
:
usize
)
->
VisibilityScope
{
assert
!
(
index
<
(
u32
::
MAX
as
usize
));
ScopeId
(
index
as
u32
)
VisibilityScope
(
index
as
u32
)
}
pub
fn
index
(
self
)
->
usize
{
...
...
@@ -785,9 +788,9 @@ pub fn index(self) -> usize {
}
#[derive(Clone,
Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
ScopeData
{
pub
struct
Visibility
ScopeData
{
pub
span
:
Span
,
pub
parent_scope
:
Option
<
ScopeId
>
,
pub
parent_scope
:
Option
<
VisibilityScope
>
,
}
///////////////////////////////////////////////////////////////////////////
...
...
src/librustc/mir/visit.rs
浏览文件 @
719a5916
...
...
@@ -97,9 +97,9 @@ fn visit_basic_block_data(&mut self,
self
.super_basic_block_data
(
block
,
data
);
}
fn
visit_scope_data
(
&
mut
self
,
scope_data
:
&
$
(
$mutability
)
*
ScopeData
)
{
self
.super_scope_data
(
scope_data
);
fn
visit_
visibility_
scope_data
(
&
mut
self
,
scope_data
:
&
$
(
$mutability
)
*
Visibility
ScopeData
)
{
self
.super_
visibility_
scope_data
(
scope_data
);
}
fn
visit_statement
(
&
mut
self
,
...
...
@@ -236,9 +236,9 @@ fn visit_arg_decl(&mut self,
self
.super_arg_decl
(
arg_decl
);
}
fn
visit_
scope_id
(
&
mut
self
,
scope_id
:
&
$
(
$mutability
)
*
ScopeId
)
{
self
.super_
scope_id
(
scope_id
);
fn
visit_
visibility_scope
(
&
mut
self
,
scope
:
&
$
(
$mutability
)
*
VisibilityScope
)
{
self
.super_
visibility_scope
(
scope
);
}
// The `super_xxx` methods comprise the default behavior and are
...
...
@@ -248,7 +248,7 @@ fn super_mir(&mut self,
mir
:
&
$
(
$mutability
)
*
Mir
<
'tcx
>
)
{
let
Mir
{
ref
$
(
$mutability
)
*
basic_blocks
,
ref
$
(
$mutability
)
*
scopes
,
ref
$
(
$mutability
)
*
visibility_
scopes
,
promoted
:
_
,
// Visited by passes separately.
ref
$
(
$mutability
)
*
return_ty
,
ref
$
(
$mutability
)
*
var_decls
,
...
...
@@ -263,8 +263,8 @@ fn super_mir(&mut self,
self
.visit_basic_block_data
(
block
,
data
);
}
for
scope
in
scopes
{
self
.visit_scope_data
(
scope
);
for
scope
in
visibility_
scopes
{
self
.visit_
visibility_
scope_data
(
scope
);
}
self
.visit_fn_output
(
return_ty
);
...
...
@@ -302,16 +302,16 @@ fn super_basic_block_data(&mut self,
}
}
fn
super_scope_data
(
&
mut
self
,
scope_data
:
&
$
(
$mutability
)
*
ScopeData
)
{
let
ScopeData
{
fn
super_
visibility_
scope_data
(
&
mut
self
,
scope_data
:
&
$
(
$mutability
)
*
Visibility
ScopeData
)
{
let
Visibility
ScopeData
{
ref
$
(
$mutability
)
*
span
,
ref
$
(
$mutability
)
*
parent_scope
,
}
=
*
scope_data
;
self
.visit_span
(
span
);
if
let
Some
(
ref
$
(
$mutability
)
*
parent_scope
)
=
*
parent_scope
{
self
.visit_
scope_id
(
parent_scope
);
self
.visit_
visibility_scope
(
parent_scope
);
}
}
...
...
@@ -325,7 +325,7 @@ fn super_statement(&mut self,
}
=
*
statement
;
self
.visit_span
(
span
);
self
.visit_
scope_id
(
scope
);
self
.visit_
visibility_scope
(
scope
);
match
*
kind
{
StatementKind
::
Assign
(
ref
$
(
$mutability
)
*
lvalue
,
ref
$
(
$mutability
)
*
rvalue
)
=>
{
...
...
@@ -352,7 +352,7 @@ fn super_terminator(&mut self,
}
=
*
terminator
;
self
.visit_span
(
span
);
self
.visit_
scope_id
(
scope
);
self
.visit_
visibility_scope
(
scope
);
self
.visit_terminator_kind
(
block
,
kind
);
}
...
...
@@ -627,7 +627,7 @@ fn super_var_decl(&mut self,
}
=
*
var_decl
;
self
.visit_ty
(
ty
);
self
.visit_
scope_id
(
scope
);
self
.visit_
visibility_scope
(
scope
);
self
.visit_span
(
span
);
}
...
...
@@ -651,8 +651,8 @@ fn super_arg_decl(&mut self,
self
.visit_ty
(
ty
);
}
fn
super_
scope_id
(
&
mut
self
,
_
scope_id
:
&
$
(
$mutability
)
*
ScopeId
)
{
fn
super_
visibility_scope
(
&
mut
self
,
_
scope
:
&
$
(
$mutability
)
*
VisibilityScope
)
{
}
fn
super_branch
(
&
mut
self
,
...
...
src/librustc_mir/build/block.rs
浏览文件 @
719a5916
...
...
@@ -22,7 +22,7 @@ pub fn ast_block(&mut self,
ast_block
:
&
'tcx
hir
::
Block
)
->
BlockAnd
<
()
>
{
let
Block
{
extent
,
span
,
stmts
,
expr
}
=
self
.hir
.mirror
(
ast_block
);
self
.in_scope
(
extent
,
block
,
move
|
this
,
_
|
{
self
.in_scope
(
extent
,
block
,
move
|
this
|
{
// This convoluted structure is to avoid using recursion as we walk down a list
// of statements. Basically, the structure we get back is something like:
//
...
...
@@ -40,27 +40,40 @@ pub fn ast_block(&mut self,
//
// First we build all the statements in the block.
let
mut
let_extent_stack
=
Vec
::
with_capacity
(
8
);
let
outer_visibility_scope
=
this
.visibility_scope
;
for
stmt
in
stmts
{
let
Stmt
{
span
:
_
,
kind
}
=
this
.hir
.mirror
(
stmt
);
match
kind
{
StmtKind
::
Expr
{
scope
,
expr
}
=>
{
unpack!
(
block
=
this
.in_scope
(
scope
,
block
,
|
this
,
_
|
{
unpack!
(
block
=
this
.in_scope
(
scope
,
block
,
|
this
|
{
let
expr
=
this
.hir
.mirror
(
expr
);
this
.stmt_expr
(
block
,
expr
)
}));
}
StmtKind
::
Let
{
remainder_scope
,
init_scope
,
pattern
,
initializer
}
=>
{
let
remainder_scope_id
=
this
.push_scope
(
remainder_scope
,
block
);
let
tcx
=
this
.hir
.tcx
();
// Enter the remainder scope, i.e. the bindings' destruction scope.
this
.push_scope
(
remainder_scope
,
block
);
let_extent_stack
.push
(
remainder_scope
);
unpack!
(
block
=
this
.in_scope
(
init_scope
,
block
,
move
|
this
,
_
|
{
// FIXME #30046 ^~~~
if
let
Some
(
init
)
=
initializer
{
this
.expr_into_pattern
(
block
,
remainder_scope_id
,
pattern
,
init
)
}
else
{
this
.declare_bindings
(
remainder_scope_id
,
&
pattern
);
block
.unit
()
}
}));
// Declare the bindings, which may create a visibility scope.
let
remainder_span
=
remainder_scope
.span
(
&
tcx
.region_maps
,
&
tcx
.map
);
let
remainder_span
=
remainder_span
.unwrap_or
(
span
);
let
scope
=
this
.declare_bindings
(
None
,
remainder_span
,
&
pattern
);
// Evaluate the initializer, if present.
if
let
Some
(
init
)
=
initializer
{
unpack!
(
block
=
this
.in_scope
(
init_scope
,
block
,
move
|
this
|
{
// FIXME #30046 ^~~~
this
.expr_into_pattern
(
block
,
pattern
,
init
)
}));
}
// Enter the visibility scope, after evaluating the initializer.
if
let
Some
(
visibility_scope
)
=
scope
{
this
.visibility_scope
=
visibility_scope
;
}
}
}
}
...
...
@@ -78,6 +91,8 @@ pub fn ast_block(&mut self,
for
extent
in
let_extent_stack
.into_iter
()
.rev
()
{
unpack!
(
block
=
this
.pop_scope
(
extent
,
block
));
}
// Restore the original visibility scope.
this
.visibility_scope
=
outer_visibility_scope
;
block
.unit
()
})
}
...
...
src/librustc_mir/build/cfg.rs
浏览文件 @
719a5916
...
...
@@ -50,7 +50,7 @@ pub fn current_location(&mut self, block: BasicBlock) -> Location {
pub
fn
push_assign
(
&
mut
self
,
block
:
BasicBlock
,
scope
:
ScopeId
,
scope
:
VisibilityScope
,
span
:
Span
,
lvalue
:
&
Lvalue
<
'tcx
>
,
rvalue
:
Rvalue
<
'tcx
>
)
{
...
...
@@ -63,7 +63,7 @@ pub fn push_assign(&mut self,
pub
fn
push_assign_constant
(
&
mut
self
,
block
:
BasicBlock
,
scope
:
ScopeId
,
scope
:
VisibilityScope
,
span
:
Span
,
temp
:
&
Lvalue
<
'tcx
>
,
constant
:
Constant
<
'tcx
>
)
{
...
...
@@ -73,7 +73,7 @@ pub fn push_assign_constant(&mut self,
pub
fn
push_assign_unit
(
&
mut
self
,
block
:
BasicBlock
,
scope
:
ScopeId
,
scope
:
VisibilityScope
,
span
:
Span
,
lvalue
:
&
Lvalue
<
'tcx
>
)
{
self
.push_assign
(
block
,
scope
,
span
,
lvalue
,
Rvalue
::
Aggregate
(
...
...
@@ -83,7 +83,7 @@ pub fn push_assign_unit(&mut self,
pub
fn
terminate
(
&
mut
self
,
block
:
BasicBlock
,
scope
:
ScopeId
,
scope
:
VisibilityScope
,
span
:
Span
,
kind
:
TerminatorKind
<
'tcx
>
)
{
debug_assert!
(
self
.block_data
(
block
)
.terminator
.is_none
(),
...
...
src/librustc_mir/build/expr/as_lvalue.rs
浏览文件 @
719a5916
...
...
@@ -38,7 +38,7 @@ fn expr_as_lvalue(&mut self,
let
expr_span
=
expr
.span
;
match
expr
.kind
{
ExprKind
::
Scope
{
extent
,
value
}
=>
{
this
.in_scope
(
extent
,
block
,
|
this
,
_
|
this
.as_lvalue
(
block
,
value
))
this
.in_scope
(
extent
,
block
,
|
this
|
this
.as_lvalue
(
block
,
value
))
}
ExprKind
::
Field
{
lhs
,
name
}
=>
{
let
lvalue
=
unpack!
(
block
=
this
.as_lvalue
(
block
,
lhs
));
...
...
src/librustc_mir/build/expr/as_operand.rs
浏览文件 @
719a5916
...
...
@@ -35,7 +35,7 @@ fn expr_as_operand(&mut self,
let
this
=
self
;
if
let
ExprKind
::
Scope
{
extent
,
value
}
=
expr
.kind
{
return
this
.in_scope
(
extent
,
block
,
|
this
,
_
|
this
.as_operand
(
block
,
value
));
return
this
.in_scope
(
extent
,
block
,
|
this
|
this
.as_operand
(
block
,
value
));
}
let
category
=
Category
::
of
(
&
expr
.kind
)
.unwrap
();
...
...
src/librustc_mir/build/expr/as_rvalue.rs
浏览文件 @
719a5916
...
...
@@ -46,7 +46,7 @@ fn expr_as_rvalue(&mut self,
match
expr
.kind
{
ExprKind
::
Scope
{
extent
,
value
}
=>
{
this
.in_scope
(
extent
,
block
,
|
this
,
_
|
this
.as_rvalue
(
block
,
value
))
this
.in_scope
(
extent
,
block
,
|
this
|
this
.as_rvalue
(
block
,
value
))
}
ExprKind
::
InlineAsm
{
asm
,
outputs
,
inputs
}
=>
{
let
outputs
=
outputs
.into_iter
()
.map
(|
output
|
{
...
...
@@ -100,7 +100,7 @@ fn expr_as_rvalue(&mut self,
let
result
=
this
.temp
(
expr
.ty
);
// to start, malloc some memory of suitable type (thus far, uninitialized):
this
.cfg
.push_assign
(
block
,
scope_id
,
expr_span
,
&
result
,
Rvalue
::
Box
(
value
.ty
));
this
.in_scope
(
value_extents
,
block
,
|
this
,
_
|
{
this
.in_scope
(
value_extents
,
block
,
|
this
|
{
// schedule a shallow free of that memory, lest we unwind:
this
.schedule_box_free
(
expr_span
,
value_extents
,
&
result
,
value
.ty
);
// initialize the box contents:
...
...
src/librustc_mir/build/expr/as_temp.rs
浏览文件 @
719a5916
...
...
@@ -30,7 +30,7 @@ fn expr_as_temp(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<
let
this
=
self
;
if
let
ExprKind
::
Scope
{
extent
,
value
}
=
expr
.kind
{
return
this
.in_scope
(
extent
,
block
,
|
this
,
_
|
this
.as_temp
(
block
,
value
));
return
this
.in_scope
(
extent
,
block
,
|
this
|
this
.as_temp
(
block
,
value
));
}
let
expr_ty
=
expr
.ty
.clone
();
...
...
src/librustc_mir/build/expr/into.rs
浏览文件 @
719a5916
...
...
@@ -37,7 +37,7 @@ pub fn into_expr(&mut self,
match
expr
.kind
{
ExprKind
::
Scope
{
extent
,
value
}
=>
{
this
.in_scope
(
extent
,
block
,
|
this
,
_
|
this
.into
(
destination
,
block
,
value
))
this
.in_scope
(
extent
,
block
,
|
this
|
this
.into
(
destination
,
block
,
value
))
}
ExprKind
::
Block
{
body
:
ast_block
}
=>
{
this
.ast_block
(
destination
,
expr
.ty
.is_nil
(),
block
,
ast_block
)
...
...
src/librustc_mir/build/expr/stmt.rs
浏览文件 @
719a5916
...
...
@@ -26,7 +26,7 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
match
expr
.kind
{
ExprKind
::
Scope
{
extent
,
value
}
=>
{
let
value
=
this
.hir
.mirror
(
value
);
this
.in_scope
(
extent
,
block
,
|
this
,
_
|
this
.stmt_expr
(
block
,
value
))
this
.in_scope
(
extent
,
block
,
|
this
|
this
.stmt_expr
(
block
,
value
))
}
ExprKind
::
Assign
{
lhs
,
rhs
}
=>
{
let
lhs
=
this
.hir
.mirror
(
lhs
);
...
...
src/librustc_mir/build/matches/mod.rs
浏览文件 @
719a5916
...
...
@@ -44,21 +44,11 @@ pub fn match_expr(&mut self,
.collect
(),
};
// Get the body expressions and their scopes, while declaring bindings.
let
arm_bodies
:
Vec
<
_
>
=
arms
.iter
()
.enumerate
()
.map
(|(
i
,
arm
)|
{
// Assume that all expressions are wrapped in Scope.
// Get the arm bodies and their scopes, while declaring bindings.
let
arm_bodies
:
Vec
<
_
>
=
arms
.iter
()
.map
(|
arm
|
{
let
body
=
self
.hir
.mirror
(
arm
.body
.clone
());
match
body
.kind
{
ExprKind
::
Scope
{
extent
,
value
}
=>
{
let
scope_id
=
self
.push_scope
(
extent
,
arm_blocks
.blocks
[
i
]);
self
.declare_bindings
(
scope_id
,
&
arm
.patterns
[
0
]);
(
extent
,
self
.scopes
.pop
()
.unwrap
(),
value
)
}
_
=>
{
span_bug!
(
body
.span
,
"arm body is not wrapped in Scope {:?}"
,
body
.kind
);
}
}
let
scope
=
self
.declare_bindings
(
None
,
body
.span
,
&
arm
.patterns
[
0
]);
(
body
,
scope
.unwrap_or
(
self
.visibility_scope
))
})
.collect
();
// assemble a list of candidates: there is one candidate per
...
...
@@ -99,63 +89,48 @@ pub fn match_expr(&mut self,
// all the arm blocks will rejoin here
let
end_block
=
self
.cfg
.start_new_block
();
let
scope_id
=
self
.innermost_scope_id
();
for
(
arm_index
,
(
extent
,
scope
,
body
))
in
arm_bodies
.into_iter
()
.enumerate
()
{
let
outer_visibility_scope
=
self
.innermost_scope_id
();
for
(
arm_index
,
(
body
,
visibility_scope
))
in
arm_bodies
.into_iter
()
.enumerate
()
{
let
mut
arm_block
=
arm_blocks
.blocks
[
arm_index
];
// Re-enter the scope we created the bindings in.
self
.
scopes
.push
(
scope
)
;
// Re-enter the
visibility
scope we created the bindings in.
self
.
visibility_scope
=
visibility_scope
;
unpack!
(
arm_block
=
self
.into
(
destination
,
arm_block
,
body
));
unpack!
(
arm_block
=
self
.pop_scope
(
extent
,
arm_block
));
self
.cfg
.terminate
(
arm_block
,
scope_id
,
outer_visibility_scope
,
span
,
TerminatorKind
::
Goto
{
target
:
end_block
});
}
self
.visibility_scope
=
outer_visibility_scope
;
end_block
.unit
()
}
pub
fn
expr_into_pattern
(
&
mut
self
,
mut
block
:
BasicBlock
,
var_scope_id
:
ScopeId
,
// lifetime of vars
irrefutable_pat
:
Pattern
<
'tcx
>
,
initializer
:
ExprRef
<
'tcx
>
)
->
BlockAnd
<
()
>
{
// optimize the case of `let x = ...`
match
*
irrefutable_pat
.kind
{
PatternKind
::
Binding
{
mutability
,
name
,
mode
:
BindingMode
::
ByValue
,
PatternKind
::
Binding
{
mode
:
BindingMode
::
ByValue
,
var
,
ty
,
subpattern
:
None
}
=>
{
let
index
=
self
.declare_binding
(
var_scope_id
,
mutability
,
name
,
var
,
ty
,
irrefutable_pat
.span
);
let
lvalue
=
Lvalue
::
Var
(
index
);
subpattern
:
None
,
..
}
=>
{
let
lvalue
=
Lvalue
::
Var
(
self
.var_indices
[
&
var
]);
return
self
.into
(
&
lvalue
,
block
,
initializer
);
}
_
=>
{}
}
let
lvalue
=
unpack!
(
block
=
self
.as_lvalue
(
block
,
initializer
));
self
.lvalue_into_pattern
(
block
,
var_scope_id
,
irrefutable_pat
,
&
lvalue
)
}
pub
fn
lvalue_into_pattern
(
&
mut
self
,
mut
block
:
BasicBlock
,
var_scope_id
:
ScopeId
,
irrefutable_pat
:
Pattern
<
'tcx
>
,
initializer
:
&
Lvalue
<
'tcx
>
)
->
BlockAnd
<
()
>
{
// first, creating the bindings
self
.declare_bindings
(
var_scope_id
,
&
irrefutable_pat
);
// create a dummy candidate
let
mut
candidate
=
Candidate
{
span
:
irrefutable_pat
.span
,
...
...
@@ -182,32 +157,43 @@ pub fn lvalue_into_pattern(&mut self,
block
.unit
()
}
pub
fn
declare_bindings
(
&
mut
self
,
var_scope_id
:
ScopeId
,
pattern
:
&
Pattern
<
'tcx
>
)
{
/// Declares the bindings of the given pattern and returns the visibility scope
/// for the bindings in this patterns, if such a scope had to be created.
/// NOTE: Declaring the bindings should always be done in their drop scope.
pub
fn
declare_bindings
(
&
mut
self
,
mut
var_scope
:
Option
<
VisibilityScope
>
,
scope_span
:
Span
,
pattern
:
&
Pattern
<
'tcx
>
)
->
Option
<
VisibilityScope
>
{
match
*
pattern
.kind
{
PatternKind
::
Binding
{
mutability
,
name
,
mode
:
_
,
var
,
ty
,
ref
subpattern
}
=>
{
self
.declare_binding
(
var_scope_id
,
mutability
,
name
,
var
,
ty
,
pattern
.span
);
if
var_scope
.is_none
()
{
var_scope
=
Some
(
self
.new_visibility_scope
(
scope_span
));
}
self
.declare_binding
(
var_scope
.unwrap
(),
mutability
,
name
,
var
,
ty
,
pattern
.span
);
if
let
Some
(
subpattern
)
=
subpattern
.as_ref
()
{
self
.declare_bindings
(
var_scope_id
,
subpattern
);
var_scope
=
self
.declare_bindings
(
var_scope
,
scope_span
,
subpattern
);
}
}
PatternKind
::
Array
{
ref
prefix
,
ref
slice
,
ref
suffix
}
|
PatternKind
::
Slice
{
ref
prefix
,
ref
slice
,
ref
suffix
}
=>
{
for
subpattern
in
prefix
.iter
()
.chain
(
slice
)
.chain
(
suffix
)
{
self
.declare_bindings
(
var_scope_id
,
subpattern
);
var_scope
=
self
.declare_bindings
(
var_scope
,
scope_span
,
subpattern
);
}
}
PatternKind
::
Constant
{
..
}
|
PatternKind
::
Range
{
..
}
|
PatternKind
::
Wild
=>
{
}
PatternKind
::
Deref
{
ref
subpattern
}
=>
{
self
.declare_bindings
(
var_scope_id
,
subpattern
);
var_scope
=
self
.declare_bindings
(
var_scope
,
scope_span
,
subpattern
);
}
PatternKind
::
Leaf
{
ref
subpatterns
}
|
PatternKind
::
Variant
{
ref
subpatterns
,
..
}
=>
{
for
subpattern
in
subpatterns
{
self
.declare_bindings
(
var_scope_id
,
&
subpattern
.pattern
);
var_scope
=
self
.declare_bindings
(
var_scope
,
scope_span
,
&
subpattern
.pattern
);
}
}
}
var_scope
}
}
...
...
@@ -635,7 +621,7 @@ fn bind_matched_candidate(&mut self,
}
fn
declare_binding
(
&
mut
self
,
var_scope_id
:
ScopeId
,
var_scope_id
:
VisibilityScope
,
mutability
:
Mutability
,
name
:
Name
,
var_id
:
NodeId
,
...
...
@@ -655,7 +641,7 @@ fn declare_binding(&mut self,
span
:
span
,
});
let
index
=
index
as
u32
;
let
extent
=
self
.
scope_auxiliary
[
var_scope_id
]
.extent
;
let
extent
=
self
.
extent_of_innermost_scope
()
;
self
.schedule_drop
(
span
,
extent
,
&
Lvalue
::
Var
(
index
),
var_ty
);
self
.var_indices
.insert
(
var_id
,
index
);
...
...
src/librustc_mir/build/misc.rs
浏览文件 @
719a5916
...
...
@@ -103,7 +103,7 @@ pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
pub
fn
push_usize
(
&
mut
self
,
block
:
BasicBlock
,
scope_id
:
ScopeId
,
scope_id
:
VisibilityScope
,
span
:
Span
,
value
:
u64
)
->
Lvalue
<
'tcx
>
{
...
...
src/librustc_mir/build/mod.rs
浏览文件 @
719a5916
...
...
@@ -15,6 +15,7 @@
use
rustc_data_structures
::
fnv
::
FnvHashMap
;
use
rustc
::
hir
;
use
std
::
ops
::{
Index
,
IndexMut
};
use
std
::
u32
;
use
syntax
::
abi
::
Abi
;
use
syntax
::
ast
;
use
syntax
::
codemap
::
Span
;
...
...
@@ -43,7 +44,8 @@ pub struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
/// the vector of all scopes that we have created thus far;
/// we track this for debuginfo later
scope_datas
:
Vec
<
ScopeData
>
,
visibility_scopes
:
Vec
<
VisibilityScopeData
>
,
visibility_scope
:
VisibilityScope
,
var_decls
:
Vec
<
VarDecl
<
'tcx
>>
,
var_indices
:
FnvHashMap
<
ast
::
NodeId
,
u32
>
,
...
...
@@ -61,6 +63,20 @@ struct CFG<'tcx> {
basic_blocks
:
Vec
<
BasicBlockData
<
'tcx
>>
,
}
#[derive(Copy,
Clone,
Debug,
PartialEq,
Eq)]
pub
struct
ScopeId
(
u32
);
impl
ScopeId
{
pub
fn
new
(
index
:
usize
)
->
ScopeId
{
assert
!
(
index
<
(
u32
::
MAX
as
usize
));
ScopeId
(
index
as
u32
)
}
pub
fn
index
(
self
)
->
usize
{
self
.0
as
usize
}
}
/// For each scope, we track the extent (from the HIR) and a
/// single-entry-multiple-exit subgraph that contains all the
/// statements/terminators within it.
...
...
@@ -179,17 +195,16 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
tcx
.region_maps
.lookup_code_extent
(
CodeExtentData
::
ParameterScope
{
fn_id
:
fn_id
,
body_id
:
body_id
});
let
mut
block
=
START_BLOCK
;
let
mut
arg_decls
=
unpack!
(
block
=
builder
.in_scope
(
call_site_extent
,
block
,
|
builder
,
call_site_scope_id
|
{
let
arg_decls
=
unpack!
(
block
=
builder
.in_scope
(
arg_extent
,
block
,
|
builder
,
arg_scope_id
|
{
builder
.args_and_body
(
block
,
return_ty
,
arguments
,
arg_scope_id
,
ast_block
)
let
mut
arg_decls
=
unpack!
(
block
=
builder
.in_scope
(
call_site_extent
,
block
,
|
builder
|
{
let
arg_decls
=
unpack!
(
block
=
builder
.in_scope
(
arg_extent
,
block
,
|
builder
|
{
builder
.args_and_body
(
block
,
return_ty
,
arguments
,
arg_extent
,
ast_block
)
}));
let
visibility_scope
=
builder
.visibility_scope
;
let
return_block
=
builder
.return_block
();
builder
.cfg
.terminate
(
block
,
call_site_scope_id
,
span
,
builder
.cfg
.terminate
(
block
,
visibility_scope
,
span
,
TerminatorKind
::
Goto
{
target
:
return_block
});
builder
.cfg
.terminate
(
return_block
,
call_site_scope_id
,
span
,
builder
.cfg
.terminate
(
return_block
,
visibility_scope
,
span
,
TerminatorKind
::
Return
);
return_block
.and
(
arg_decls
)
}));
...
...
@@ -241,14 +256,15 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
let
extent
=
ROOT_CODE_EXTENT
;
let
mut
block
=
START_BLOCK
;
let
_
=
builder
.in_scope
(
extent
,
block
,
|
builder
,
call_site_scope_id
|
{
let
_
=
builder
.in_scope
(
extent
,
block
,
|
builder
|
{
let
expr
=
builder
.hir
.mirror
(
ast_expr
);
unpack!
(
block
=
builder
.into
(
&
Lvalue
::
ReturnPointer
,
block
,
expr
));
let
visibility_scope
=
builder
.visibility_scope
;
let
return_block
=
builder
.return_block
();
builder
.cfg
.terminate
(
block
,
call_site_scope_id
,
span
,
builder
.cfg
.terminate
(
block
,
visibility_scope
,
span
,
TerminatorKind
::
Goto
{
target
:
return_block
});
builder
.cfg
.terminate
(
return_block
,
call_site_scope_id
,
span
,
builder
.cfg
.terminate
(
return_block
,
visibility_scope
,
span
,
TerminatorKind
::
Return
);
return_block
.unit
()
...
...
@@ -265,7 +281,8 @@ fn new(hir: Cx<'a, 'gcx, 'tcx>, span: Span) -> Builder<'a, 'gcx, 'tcx> {
cfg
:
CFG
{
basic_blocks
:
vec!
[]
},
fn_span
:
span
,
scopes
:
vec!
[],
scope_datas
:
vec!
[],
visibility_scopes
:
vec!
[],
visibility_scope
:
ARGUMENT_VISIBILITY_SCOPE
,
scope_auxiliary
:
ScopeAuxiliaryVec
{
vec
:
vec!
[]
},
loop_scopes
:
vec!
[],
temp_decls
:
vec!
[],
...
...
@@ -277,6 +294,8 @@ fn new(hir: Cx<'a, 'gcx, 'tcx>, span: Span) -> Builder<'a, 'gcx, 'tcx> {
};
assert_eq!
(
builder
.cfg
.start_new_block
(),
START_BLOCK
);
assert_eq!
(
builder
.new_visibility_scope
(
span
),
ARGUMENT_VISIBILITY_SCOPE
);
builder
.visibility_scopes
[
ARGUMENT_VISIBILITY_SCOPE
]
.parent_scope
=
None
;
builder
}
...
...
@@ -294,7 +313,7 @@ fn finish(self,
(
Mir
{
basic_blocks
:
self
.cfg.basic_blocks
,
scopes
:
self
.scope_data
s
,
visibility_scopes
:
self
.visibility_scope
s
,
promoted
:
vec!
[],
var_decls
:
self
.var_decls
,
arg_decls
:
arg_decls
,
...
...
@@ -309,24 +328,22 @@ fn args_and_body<A>(&mut self,
mut
block
:
BasicBlock
,
return_ty
:
ty
::
FnOutput
<
'tcx
>
,
arguments
:
A
,
argument_
scope_id
:
ScopeId
,
argument_
extent
:
CodeExtent
,
ast_block
:
&
'gcx
hir
::
Block
)
->
BlockAnd
<
Vec
<
ArgDecl
<
'tcx
>>>
where
A
:
Iterator
<
Item
=
(
Ty
<
'gcx
>
,
Option
<&
'gcx
hir
::
Pat
>
)
>
{
// to start, translate the argument patterns and collect the argument types.
let
mut
scope
=
None
;
let
arg_decls
=
arguments
.enumerate
()
.map
(|(
index
,
(
ty
,
pattern
))|
{
let
lvalue
=
Lvalue
::
Arg
(
index
as
u32
);
if
let
Some
(
pattern
)
=
pattern
{
let
pattern
=
self
.hir
.irrefutable_pat
(
pattern
);
unpack!
(
block
=
self
.lvalue_into_pattern
(
block
,
argument_scope_id
,
pattern
,
&
lvalue
));
scope
=
self
.declare_bindings
(
scope
,
ast_block
.span
,
&
pattern
);
unpack!
(
block
=
self
.lvalue_into_pattern
(
block
,
pattern
,
&
lvalue
));
}
// Make sure we drop (parts of) the argument even when not matched on.
let
argument_extent
=
self
.scope_auxiliary
[
argument_scope_id
]
.extent
;
self
.schedule_drop
(
pattern
.as_ref
()
.map_or
(
ast_block
.span
,
|
pat
|
pat
.span
),
argument_extent
,
&
lvalue
,
ty
);
...
...
@@ -344,6 +361,11 @@ fn args_and_body<A>(&mut self,
}
})
.collect
();
// Enter the argument pattern bindings visibility scope, if it exists.
if
let
Some
(
visibility_scope
)
=
scope
{
self
.visibility_scope
=
visibility_scope
;
}
// FIXME(#32959): temporary hack for the issue at hand
let
return_is_unit
=
if
let
ty
::
FnConverging
(
t
)
=
return_ty
{
t
.is_nil
()
...
...
src/librustc_mir/build/scope.rs
浏览文件 @
719a5916
...
...
@@ -86,7 +86,7 @@
*/
use
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
,
CFG
,
ScopeAuxiliary
};
use
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
,
CFG
,
ScopeAuxiliary
,
ScopeId
};
use
rustc
::
middle
::
region
::{
CodeExtent
,
CodeExtentData
};
use
rustc
::
middle
::
lang_items
;
use
rustc
::
ty
::
subst
::{
Substs
,
Subst
,
VecPerParamSpace
};
...
...
@@ -98,9 +98,12 @@
use
rustc_const_math
::
ConstInt
;
pub
struct
Scope
<
'tcx
>
{
/// the scope-id within the scope_
datas
/// the scope-id within the scope_
auxiliary
id
:
ScopeId
,
/// The visibility scope this scope was created in.
visibility_scope
:
VisibilityScope
,
/// the extent of this scope within source code; also stored in
/// `ScopeAuxiliary`, but kept here for convenience
extent
:
CodeExtent
,
...
...
@@ -237,11 +240,11 @@ pub fn in_loop_scope<F>(&mut self,
/// Convenience wrapper that pushes a scope and then executes `f`
/// to build its contents, popping the scope afterwards.
pub
fn
in_scope
<
F
,
R
>
(
&
mut
self
,
extent
:
CodeExtent
,
mut
block
:
BasicBlock
,
f
:
F
)
->
BlockAnd
<
R
>
where
F
:
FnOnce
(
&
mut
Builder
<
'a
,
'gcx
,
'tcx
>
,
ScopeId
)
->
BlockAnd
<
R
>
where
F
:
FnOnce
(
&
mut
Builder
<
'a
,
'gcx
,
'tcx
>
)
->
BlockAnd
<
R
>
{
debug!
(
"in_scope(extent={:?}, block={:?})"
,
extent
,
block
);
let
id
=
self
.push_scope
(
extent
,
block
);
let
rv
=
unpack!
(
block
=
f
(
self
,
id
));
self
.push_scope
(
extent
,
block
);
let
rv
=
unpack!
(
block
=
f
(
self
));
unpack!
(
block
=
self
.pop_scope
(
extent
,
block
));
debug!
(
"in_scope: exiting extent={:?} block={:?}"
,
extent
,
block
);
block
.and
(
rv
)
...
...
@@ -251,17 +254,13 @@ pub fn in_scope<F, R>(&mut self, extent: CodeExtent, mut block: BasicBlock, f: F
/// scope and call `pop_scope` afterwards. Note that these two
/// calls must be paired; using `in_scope` as a convenience
/// wrapper maybe preferable.
pub
fn
push_scope
(
&
mut
self
,
extent
:
CodeExtent
,
entry
:
BasicBlock
)
->
ScopeId
{
pub
fn
push_scope
(
&
mut
self
,
extent
:
CodeExtent
,
entry
:
BasicBlock
)
{
debug!
(
"push_scope({:?})"
,
extent
);
let
parent_id
=
self
.scopes
.last
()
.map
(|
s
|
s
.id
);
let
id
=
ScopeId
::
new
(
self
.scope_datas
.len
());
let
tcx
=
self
.hir
.tcx
();
self
.scope_datas
.push
(
ScopeData
{
span
:
extent
.span
(
&
tcx
.region_maps
,
&
tcx
.map
)
.unwrap_or
(
DUMMY_SP
),
parent_scope
:
parent_id
,
});
let
id
=
ScopeId
::
new
(
self
.scope_auxiliary.vec
.len
());
let
vis_scope
=
self
.visibility_scope
;
self
.scopes
.push
(
Scope
{
id
:
id
,
visibility_scope
:
vis_scope
,
extent
:
extent
,
drops
:
vec!
[],
free
:
None
,
...
...
@@ -272,7 +271,6 @@ pub fn push_scope(&mut self, extent: CodeExtent, entry: BasicBlock) -> ScopeId {
dom
:
self
.cfg
.current_location
(
entry
),
postdoms
:
vec!
[]
});
id
}
/// Pops a scope, which should have extent `extent`, adding any
...
...
@@ -320,7 +318,7 @@ pub fn exit_scope(&mut self,
if
let
Some
(
ref
free_data
)
=
scope
.free
{
let
next
=
self
.cfg
.start_new_block
();
let
free
=
build_free
(
self
.hir
.tcx
(),
&
tmp
,
free_data
,
next
);
self
.cfg
.terminate
(
block
,
scope
.
id
,
span
,
free
);
self
.cfg
.terminate
(
block
,
scope
.
visibility_scope
,
span
,
free
);
block
=
next
;
}
self
.scope_auxiliary
[
scope
.id
]
...
...
@@ -334,11 +332,22 @@ pub fn exit_scope(&mut self,
.next
()
.unwrap
();
self
.cfg
.terminate
(
block
,
scope
.
id
,
scope
.
visibility_scope
,
span
,
TerminatorKind
::
Goto
{
target
:
target
});
}
/// Creates a new visibility scope, nested in the current one.
pub
fn
new_visibility_scope
(
&
mut
self
,
span
:
Span
)
->
VisibilityScope
{
let
parent
=
self
.visibility_scope
;
let
scope
=
VisibilityScope
::
new
(
self
.visibility_scopes
.len
());
self
.visibility_scopes
.push
(
VisibilityScopeData
{
span
:
span
,
parent_scope
:
Some
(
parent
),
});
scope
}
// Finding scopes
// ==============
/// Finds the loop scope for a given label. This is used for
...
...
@@ -363,8 +372,8 @@ pub fn find_loop_scope(&mut self,
}
.unwrap_or_else
(||
span_bug!
(
span
,
"no enclosing loop scope found?"
))
}
pub
fn
innermost_scope_id
(
&
self
)
->
ScopeId
{
self
.
scopes
.last
()
.map
(|
scope
|
scope
.id
)
.unwrap
()
pub
fn
innermost_scope_id
(
&
self
)
->
VisibilityScope
{
self
.
visibility_scope
}
pub
fn
extent_of_innermost_scope
(
&
self
)
->
CodeExtent
{
...
...
@@ -481,7 +490,10 @@ pub fn diverge_cleanup(&mut self) -> Option<BasicBlock> {
target
}
else
{
let
resumeblk
=
cfg
.start_new_cleanup_block
();
cfg
.terminate
(
resumeblk
,
scopes
[
0
]
.id
,
self
.fn_span
,
TerminatorKind
::
Resume
);
cfg
.terminate
(
resumeblk
,
scopes
[
0
]
.visibility_scope
,
self
.fn_span
,
TerminatorKind
::
Resume
);
*
cached_resume_block
=
Some
(
resumeblk
);
resumeblk
};
...
...
@@ -658,7 +670,7 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
earlier_scopes
.iter
()
.rev
()
.flat_map
(|
s
|
s
.cached_block
())
.next
()
});
let
next
=
cfg
.start_new_block
();
cfg
.terminate
(
block
,
scope
.
id
,
drop_data
.span
,
TerminatorKind
::
Drop
{
cfg
.terminate
(
block
,
scope
.
visibility_scope
,
drop_data
.span
,
TerminatorKind
::
Drop
{
location
:
drop_data
.location
.clone
(),
target
:
next
,
unwind
:
on_diverge
...
...
@@ -695,7 +707,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
}
else
{
let
into
=
cfg
.start_new_cleanup_block
();
cfg
.terminate
(
into
,
scope
.
id
,
scope
.
visibility_scope
,
free_data
.span
,
build_free
(
tcx
,
unit_temp
,
free_data
,
target
));
free_data
.cached_block
=
Some
(
into
);
...
...
@@ -712,7 +724,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
}
else
{
let
block
=
cfg
.start_new_cleanup_block
();
cfg
.terminate
(
block
,
scope
.
id
,
scope
.
visibility_scope
,
drop_data
.span
,
TerminatorKind
::
Drop
{
location
:
drop_data
.location
.clone
(),
...
...
src/librustc_mir/pretty.rs
浏览文件 @
719a5916
...
...
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
build
::{
Location
,
ScopeAuxiliaryVec
};
use
build
::{
Location
,
ScopeAuxiliaryVec
,
ScopeId
};
use
rustc
::
hir
;
use
rustc
::
mir
::
repr
::
*
;
use
rustc
::
mir
::
transform
::
MirSource
;
...
...
@@ -139,20 +139,11 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
write_mir_intro
(
tcx
,
src
,
mir
,
w
)
?
;
for
block
in
mir
.all_basic_blocks
()
{
write_basic_block
(
tcx
,
block
,
mir
,
w
,
&
annotations
)
?
;
if
block
.index
()
+
1
!=
mir
.basic_blocks
.len
()
{
writeln!
(
w
,
""
)
?
;
}
}
// construct a scope tree and write it out
let
mut
scope_tree
:
FnvHashMap
<
Option
<
ScopeId
>
,
Vec
<
ScopeId
>>
=
FnvHashMap
();
for
(
index
,
scope_data
)
in
mir
.scopes
.iter
()
.enumerate
()
{
scope_tree
.entry
(
scope_data
.parent_scope
)
.or_insert
(
vec!
[])
.push
(
ScopeId
::
new
(
index
));
}
writeln!
(
w
,
"{}scope tree:"
,
INDENT
)
?
;
write_scope_tree
(
tcx
,
mir
,
auxiliary
,
&
scope_tree
,
w
,
None
,
1
,
false
)
?
;
writeln!
(
w
,
""
)
?
;
writeln!
(
w
,
"}}"
)
?
;
Ok
(())
}
...
...
@@ -204,66 +195,59 @@ fn write_basic_block(tcx: TyCtxt,
writeln!
(
w
,
"{}}}
\n
"
,
INDENT
)
}
fn
comment
(
tcx
:
TyCtxt
,
scope
:
ScopeId
,
span
:
Span
)
->
String
{
fn
comment
(
tcx
:
TyCtxt
,
scope
:
VisibilityScope
,
span
:
Span
)
->
String
{
format!
(
"scope {} at {}"
,
scope
.index
(),
tcx
.sess
.codemap
()
.span_to_string
(
span
))
}
fn
write_scope_tree
(
tcx
:
TyCtxt
,
mir
:
&
Mir
,
auxiliary
:
Option
<&
ScopeAuxiliaryVec
>
,
scope_tree
:
&
FnvHashMap
<
Option
<
ScopeId
>
,
Vec
<
ScopeId
>>
,
scope_tree
:
&
FnvHashMap
<
VisibilityScope
,
Vec
<
VisibilityScope
>>
,
w
:
&
mut
Write
,
parent
:
Option
<
ScopeId
>
,
depth
:
usize
,
same_line
:
bool
)
parent
:
VisibilityScope
,
depth
:
usize
)
->
io
::
Result
<
()
>
{
let
indent
=
if
same_line
{
0
}
else
{
depth
*
INDENT
.len
()
};
let
indent
=
depth
*
INDENT
.len
();
let
children
=
match
scope_tree
.get
(
&
parent
)
{
Some
(
childs
)
=>
childs
,
None
=>
return
Ok
(()),
};
for
(
index
,
&
child
)
in
children
.iter
()
.enumerate
()
{
if
index
==
0
&&
same_line
{
// We know we're going to output a scope, so prefix it with a space to separate it from
// the previous scopes on this line
write!
(
w
,
" "
)
?
;
}
let
data
=
&
mir
.scopes
[
child
];
assert_eq!
(
data
.parent_scope
,
parent
);
write!
(
w
,
"{0:1$}{2}"
,
""
,
indent
,
child
.index
())
?
;
for
&
child
in
children
{
let
data
=
&
mir
.visibility_scopes
[
child
];
assert_eq!
(
data
.parent_scope
,
Some
(
parent
));
writeln!
(
w
,
"{0:1$}scope {2} {{"
,
""
,
indent
,
child
.index
())
?
;
let
indent
=
indent
+
INDENT
.len
();
// User variable types (including the user's name in a comment).
for
(
i
,
var
)
in
mir
.var_decls
.iter
()
.enumerate
()
{
// Skip if not declared in this scope.
if
var
.scope
!=
child
{
continue
;
}
if
let
Some
(
auxiliary
)
=
auxiliary
{
let
extent
=
auxiliary
[
child
]
.extent
;
let
data
=
tcx
.region_maps
.code_extent_data
(
extent
);
writeln!
(
w
,
"{0:1$}Extent: {2:?}"
,
""
,
indent
,
data
)
?
;
let
mut_str
=
if
var
.mutability
==
Mutability
::
Mut
{
"mut "
}
else
{
""
};
let
indent
=
indent
+
INDENT
.len
();
let
indented_var
=
format!
(
"{0:1$}let {2}{3:?}: {4};"
,
INDENT
,
indent
,
mut_str
,
Lvalue
::
Var
(
i
as
u32
),
var
.ty
);
writeln!
(
w
,
"{0:1$} //
\"
{2}
\"
in {3}"
,
indented_var
,
ALIGN
,
var
.name
,
comment
(
tcx
,
var
.scope
,
var
.span
))
?
;
}
let
child_count
=
scope_tree
.get
(
&
Some
(
child
))
.map
(
Vec
::
len
)
.unwrap_or
(
0
);
if
child_count
<
2
{
// Skip the braces when there's no or only a single subscope
write_scope_tree
(
tcx
,
mir
,
auxiliary
,
scope_tree
,
w
,
Some
(
child
),
depth
,
true
)
?
;
}
else
{
// 2 or more child scopes? Put them in braces and on new lines.
writeln!
(
w
,
" {{"
)
?
;
write_scope_tree
(
tcx
,
mir
,
auxiliary
,
scope_tree
,
w
,
Some
(
child
),
depth
+
1
,
false
)
?
;
write!
(
w
,
"
\n
{0:1$}}}"
,
""
,
depth
*
INDENT
.len
())
?
;
}
write_scope_tree
(
tcx
,
mir
,
scope_tree
,
w
,
child
,
depth
+
1
)
?
;
if
!
same_line
&&
index
+
1
<
children
.len
()
{
writeln!
(
w
,
""
)
?
;
}
writeln!
(
w
,
"{0:1$}}}"
,
""
,
depth
*
INDENT
.len
())
?
;
}
Ok
(())
...
...
@@ -278,7 +262,23 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
->
io
::
Result
<
()
>
{
write_mir_sig
(
tcx
,
src
,
mir
,
w
)
?
;
writeln!
(
w
,
" {{"
)
?
;
write_mir_decls
(
tcx
,
mir
,
w
)
// construct a scope tree and write it out
let
mut
scope_tree
:
FnvHashMap
<
VisibilityScope
,
Vec
<
VisibilityScope
>>
=
FnvHashMap
();
for
(
index
,
scope_data
)
in
mir
.visibility_scopes
.iter
()
.enumerate
()
{
if
let
Some
(
parent
)
=
scope_data
.parent_scope
{
scope_tree
.entry
(
parent
)
.or_insert
(
vec!
[])
.push
(
VisibilityScope
::
new
(
index
));
}
else
{
// Only the argument scope has no parent, because it's the root.
assert_eq!
(
index
,
ARGUMENT_VISIBILITY_SCOPE
.index
());
}
}
write_scope_tree
(
tcx
,
mir
,
&
scope_tree
,
w
,
ARGUMENT_VISIBILITY_SCOPE
,
1
)
?
;
write_mir_decls
(
mir
,
w
)
}
fn
write_mir_sig
(
tcx
:
TyCtxt
,
src
:
MirSource
,
mir
:
&
Mir
,
w
:
&
mut
Write
)
...
...
@@ -318,29 +318,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write)
}
}
fn
write_mir_decls
(
tcx
:
TyCtxt
,
mir
:
&
Mir
,
w
:
&
mut
Write
)
->
io
::
Result
<
()
>
{
// User variable types (including the user's name in a comment).
for
(
i
,
var
)
in
mir
.var_decls
.iter
()
.enumerate
()
{
let
mut_str
=
if
var
.mutability
==
Mutability
::
Mut
{
"mut "
}
else
{
""
};
let
indented_var
=
format!
(
"{}let {}{:?}: {};"
,
INDENT
,
mut_str
,
Lvalue
::
Var
(
i
as
u32
),
var
.ty
);
writeln!
(
w
,
"{0:1$} //
\"
{2}
\"
in {3}"
,
indented_var
,
ALIGN
,
var
.name
,
comment
(
tcx
,
var
.scope
,
var
.span
))
?
;
}
fn
write_mir_decls
(
mir
:
&
Mir
,
w
:
&
mut
Write
)
->
io
::
Result
<
()
>
{
// Compiler-introduced temporary types.
for
(
i
,
temp
)
in
mir
.temp_decls
.iter
()
.enumerate
()
{
writeln!
(
w
,
"{}let mut {:?}: {};"
,
INDENT
,
Lvalue
::
Temp
(
i
as
u32
),
temp
.ty
)
?
;
...
...
src/librustc_mir/transform/promote_consts.rs
浏览文件 @
719a5916
...
...
@@ -168,7 +168,7 @@ fn new_block(&mut self) -> BasicBlock {
statements
:
vec!
[],
terminator
:
Some
(
Terminator
{
span
:
self
.promoted.span
,
scope
:
ScopeId
::
new
(
0
),
scope
:
VisibilityScope
::
new
(
0
),
kind
:
TerminatorKind
::
Return
}),
is_cleanup
:
false
...
...
@@ -180,7 +180,7 @@ fn assign(&mut self, dest: Lvalue<'tcx>, rvalue: Rvalue<'tcx>, span: Span) {
let
data
=
self
.promoted.basic_blocks
.last_mut
()
.unwrap
();
data
.statements
.push
(
Statement
{
span
:
span
,
scope
:
ScopeId
::
new
(
0
),
scope
:
VisibilityScope
::
new
(
0
),
kind
:
StatementKind
::
Assign
(
dest
,
rvalue
)
});
}
...
...
@@ -367,7 +367,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
source
:
mir
,
promoted
:
Mir
{
basic_blocks
:
vec!
[],
scopes
:
vec!
[
ScopeData
{
visibility_scopes
:
vec!
[
Visibility
ScopeData
{
span
:
span
,
parent_scope
:
None
}],
...
...
src/librustc_trans/debuginfo/create_scope_map.rs
浏览文件 @
719a5916
...
...
@@ -16,7 +16,7 @@
use
llvm
::
debuginfo
::{
DIScope
,
DISubprogram
};
use
common
::{
CrateContext
,
FunctionContext
};
use
rustc
::
hir
::
pat_util
;
use
rustc
::
mir
::
repr
::{
Mir
,
ScopeId
};
use
rustc
::
mir
::
repr
::{
Mir
,
VisibilityScope
};
use
rustc
::
util
::
nodemap
::
NodeMap
;
use
libc
::
c_uint
;
...
...
@@ -71,7 +71,7 @@ pub fn create_scope_map(cx: &CrateContext,
/// If debuginfo is disabled, the returned vector is empty.
pub
fn
create_mir_scopes
(
fcx
:
&
FunctionContext
)
->
Vec
<
DIScope
>
{
let
mir
=
fcx
.mir
.clone
()
.expect
(
"create_mir_scopes: missing MIR for fn"
);
let
mut
scopes
=
vec!
[
ptr
::
null_mut
();
mir
.scopes
.len
()];
let
mut
scopes
=
vec!
[
ptr
::
null_mut
();
mir
.
visibility_
scopes
.len
()];
let
fn_metadata
=
match
fcx
.debug_context
{
FunctionDebugContext
::
RegularContext
(
box
ref
data
)
=>
data
.fn_metadata
,
...
...
@@ -82,14 +82,14 @@ pub fn create_mir_scopes(fcx: &FunctionContext) -> Vec<DIScope> {
};
// Find all the scopes with variables defined in them.
let
mut
has_variables
=
BitVector
::
new
(
mir
.scopes
.len
());
let
mut
has_variables
=
BitVector
::
new
(
mir
.
visibility_
scopes
.len
());
for
var
in
&
mir
.var_decls
{
has_variables
.insert
(
var
.scope
.index
());
}
// Instantiate all scopes.
for
idx
in
0
..
mir
.scopes
.len
()
{
let
scope
=
ScopeId
::
new
(
idx
);
for
idx
in
0
..
mir
.
visibility_
scopes
.len
()
{
let
scope
=
VisibilityScope
::
new
(
idx
);
make_mir_scope
(
fcx
.ccx
,
&
mir
,
&
has_variables
,
fn_metadata
,
scope
,
&
mut
scopes
);
}
...
...
@@ -100,14 +100,14 @@ fn make_mir_scope(ccx: &CrateContext,
mir
:
&
Mir
,
has_variables
:
&
BitVector
,
fn_metadata
:
DISubprogram
,
scope
:
ScopeId
,
scope
:
VisibilityScope
,
scopes
:
&
mut
[
DIScope
])
{
let
idx
=
scope
.index
();
if
!
scopes
[
idx
]
.is_null
()
{
return
;
}
let
scope_data
=
&
mir
.scopes
[
scope
];
let
scope_data
=
&
mir
.
visibility_
scopes
[
scope
];
let
parent_scope
=
if
let
Some
(
parent
)
=
scope_data
.parent_scope
{
make_mir_scope
(
ccx
,
mir
,
has_variables
,
fn_metadata
,
parent
,
scopes
);
scopes
[
parent
.index
()]
...
...
src/librustc_trans/mir/mod.rs
浏览文件 @
719a5916
...
...
@@ -266,16 +266,13 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
let
mut
idx
=
0
;
let
mut
llarg_idx
=
fcx
.fn_ty.ret
.is_indirect
()
as
usize
;
// Get the argument scope assuming ScopeId(0) has no parent.
let
arg_scope
=
mir
.scopes
.get
(
0
)
.and_then
(|
data
|
{
let
scope
=
scopes
[
0
];
if
data
.parent_scope
.is_none
()
&&
!
scope
.is_null
()
&&
bcx
.sess
()
.opts.debuginfo
==
FullDebugInfo
{
Some
(
scope
)
}
else
{
None
}
});
// Get the argument scope, if it exists and if we need it.
let
arg_scope
=
scopes
[
mir
::
ARGUMENT_VISIBILITY_SCOPE
.index
()];
let
arg_scope
=
if
!
arg_scope
.is_null
()
&&
bcx
.sess
()
.opts.debuginfo
==
FullDebugInfo
{
Some
(
arg_scope
)
}
else
{
None
};
mir
.arg_decls
.iter
()
.enumerate
()
.map
(|(
arg_index
,
arg_decl
)|
{
let
arg_ty
=
bcx
.monomorphize
(
&
arg_decl
.ty
);
...
...
src/test/debuginfo/function-prologue-stepping-no-stack-check.rs
浏览文件 @
719a5916
...
...
@@ -247,11 +247,10 @@
// lldb-command:continue
#![allow(dead_code,
unused_assignments,
unused_variables)]
#![feature(omit_gdb_pretty_printer_section
,
rustc_attrs
)]
#![feature(omit_gdb_pretty_printer_section)]
#![omit_gdb_pretty_printer_section]
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
immediate_args
(
a
:
isize
,
b
:
bool
,
c
:
f64
)
{
println!
(
""
);
}
...
...
@@ -268,51 +267,43 @@ struct BigStruct {
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
non_immediate_args
(
a
:
BigStruct
,
b
:
BigStruct
)
{
println!
(
""
);
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
binding
(
a
:
i64
,
b
:
u64
,
c
:
f64
)
{
let
x
=
0
;
println!
(
""
);
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
assignment
(
mut
a
:
u64
,
b
:
u64
,
c
:
f64
)
{
a
=
b
;
println!
(
""
);
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
function_call
(
x
:
u64
,
y
:
u64
,
z
:
f64
)
{
println!
(
"Hi!"
)
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
identifier
(
x
:
u64
,
y
:
u64
,
z
:
f64
)
->
u64
{
x
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
return_expr
(
x
:
u64
,
y
:
u64
,
z
:
f64
)
->
u64
{
return
x
;
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
arithmetic_expr
(
x
:
u64
,
y
:
u64
,
z
:
f64
)
->
u64
{
x
+
y
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
if_expr
(
x
:
u64
,
y
:
u64
,
z
:
f64
)
->
u64
{
if
x
+
y
<
1000
{
x
...
...
@@ -322,7 +313,6 @@ fn if_expr(x: u64, y: u64, z: f64) -> u64 {
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
while_expr
(
mut
x
:
u64
,
y
:
u64
,
z
:
u64
)
->
u64
{
while
x
+
y
<
1000
{
x
+=
z
...
...
@@ -331,7 +321,6 @@ fn while_expr(mut x: u64, y: u64, z: u64) -> u64 {
}
#[no_stack_check]
#[rustc_no_mir]
// FIXME(#32949) MIR debuginfo shadows arguments with uninit vars.
fn
loop_expr
(
mut
x
:
u64
,
y
:
u64
,
z
:
u64
)
->
u64
{
loop
{
x
+=
z
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录