Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
cc2a1c7b
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,发现更多精彩内容 >>
提交
cc2a1c7b
编写于
10月 09, 2017
作者:
P
Paul Faria
提交者:
Paul Daniel Faria
10月 13, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Initial attempt at implementation of inference layout for nll
上级
43d95e2c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
224 addition
and
5 deletion
+224
-5
src/librustc_mir/transform/nll/infer.rs
src/librustc_mir/transform/nll/infer.rs
+206
-0
src/librustc_mir/transform/nll/mod.rs
src/librustc_mir/transform/nll/mod.rs
+18
-5
未找到文件。
src/librustc_mir/transform/nll/infer.rs
0 → 100644
浏览文件 @
cc2a1c7b
use
super
::{
Region
,
RegionIndex
};
use
std
::
mem
;
use
rustc
::
infer
::
InferCtxt
;
use
rustc
::
mir
::{
Location
,
Mir
};
use
rustc_data_structures
::
indexed_vec
::{
Idx
,
IndexVec
};
use
rustc_data_structures
::
fx
::
FxHashSet
;
pub
struct
InferenceContext
{
definitions
:
IndexVec
<
RegionIndex
,
VarDefinition
>
,
constraints
:
IndexVec
<
ConstraintIndex
,
Constraint
>
,
errors
:
IndexVec
<
InferenceErrorIndex
,
InferenceError
>
,
}
pub
struct
InferenceError
{
pub
constraint_point
:
Location
,
pub
name
:
(),
// TODO(nashenas88) RegionName
}
newtype_index!
(
InferenceErrorIndex
);
struct
VarDefinition
{
name
:
(),
// TODO(nashenas88) RegionName
value
:
Region
,
capped
:
bool
,
}
impl
VarDefinition
{
pub
fn
new
(
value
:
Region
)
->
Self
{
Self
{
name
:
(),
value
,
capped
:
false
,
}
}
}
#[derive(Copy,
Clone,
Debug,
PartialEq,
Eq,
Hash)]
pub
struct
Constraint
{
sub
:
RegionIndex
,
sup
:
RegionIndex
,
point
:
Location
,
}
newtype_index!
(
ConstraintIndex
);
impl
InferenceContext
{
pub
fn
new
(
values
:
IndexVec
<
RegionIndex
,
Region
>
)
->
Self
{
Self
{
definitions
:
values
.into_iter
()
.map
(
VarDefinition
::
new
)
.collect
(),
constraints
:
IndexVec
::
new
(),
errors
:
IndexVec
::
new
(),
}
}
pub
fn
cap_var
(
&
mut
self
,
v
:
RegionIndex
)
{
self
.definitions
[
v
]
.capped
=
true
;
}
pub
fn
add_live_point
(
&
mut
self
,
v
:
RegionIndex
,
point
:
Location
)
{
debug!
(
"add_live_point({:?}, {:?})"
,
v
,
point
);
let
definition
=
&
mut
self
.definitions
[
v
];
if
definition
.value
.add_point
(
point
)
{
if
definition
.capped
{
self
.errors
.push
(
InferenceError
{
constraint_point
:
point
,
name
:
definition
.name
,
});
}
}
}
pub
fn
add_outlives
(
&
mut
self
,
sup
:
RegionIndex
,
sub
:
RegionIndex
,
point
:
Location
)
{
debug!
(
"add_outlives({:?}: {:?} @ {:?}"
,
sup
,
sub
,
point
);
self
.constraints
.push
(
Constraint
{
sup
,
sub
,
point
});
}
pub
fn
region
(
&
self
,
v
:
RegionIndex
)
->
&
Region
{
&
self
.definitions
[
v
]
.value
}
pub
fn
solve
<
'a
,
'gcx
,
'tcx
>
(
&
mut
self
,
infcx
:
InferCtxt
<
'a
,
'gcx
,
'tcx
>
,
mir
:
&
'a
Mir
<
'tcx
>
,
)
->
IndexVec
<
InferenceErrorIndex
,
InferenceError
>
where
'gcx
:
'tcx
+
'a
,
'tcx
:
'a
,
{
let
mut
changed
=
true
;
let
mut
dfs
=
Dfs
::
new
(
infcx
,
mir
);
while
changed
{
changed
=
false
;
for
constraint
in
&
self
.constraints
{
let
sub
=
&
self
.definitions
[
constraint
.sub
]
.value
.clone
();
let
sup_def
=
&
self
.definitions
[
constraint
.sup
];
debug!
(
"constraint: {:?}"
,
constraint
);
debug!
(
" sub (before): {:?}"
,
sub
);
debug!
(
" sup (before): {:?}"
,
sup_def
.value
);
if
dfs
.copy
(
sub
,
&
mut
sup_def
.value
,
constraint
.point
)
{
changed
=
true
;
if
sup_def
.capped
{
// This is kind of a hack, but when we add a
// constraint, the "point" is always the point
// AFTER the action that induced the
// constraint. So report the error on the
// action BEFORE that.
assert
!
(
constraint
.point.statement_index
>
0
);
let
p
=
Location
{
block
:
constraint
.point.block
,
statement_index
:
constraint
.point.statement_index
-
1
,
};
self
.errors
.push
(
InferenceError
{
constraint_point
:
p
,
name
:
sup_def
.name
,
});
}
}
debug!
(
" sup (after) : {:?}"
,
sup_def
.value
);
debug!
(
" changed : {:?}"
,
changed
);
}
debug!
(
"
\n
"
);
}
mem
::
replace
(
&
mut
self
.errors
,
IndexVec
::
new
())
}
}
struct
Dfs
<
'a
,
'gcx
:
'tcx
+
'a
,
'tcx
:
'a
>
{
infcx
:
InferCtxt
<
'a
,
'gcx
,
'tcx
>
,
mir
:
&
'a
Mir
<
'tcx
>
,
}
impl
<
'a
,
'gcx
:
'tcx
,
'tcx
:
'a
>
Dfs
<
'a
,
'gcx
,
'tcx
>
{
fn
new
(
infcx
:
InferCtxt
<
'a
,
'gcx
,
'tcx
>
,
mir
:
&
'a
Mir
<
'tcx
>
)
->
Self
{
Self
{
infcx
,
mir
}
}
fn
copy
(
&
mut
self
,
from_region
:
&
Region
,
to_region
:
&
mut
Region
,
start_point
:
Location
,
)
->
bool
{
let
mut
changed
=
false
;
let
mut
stack
=
vec!
[];
let
mut
visited
=
FxHashSet
();
stack
.push
(
start_point
);
while
let
Some
(
p
)
=
stack
.pop
()
{
debug!
(
" dfs: p={:?}"
,
p
);
if
!
from_region
.may_contain
(
p
)
{
debug!
(
" not in from-region"
);
continue
;
}
if
!
visited
.insert
(
p
)
{
debug!
(
" already visited"
);
continue
;
}
changed
|
=
to_region
.add_point
(
p
);
let
block_data
=
self
.mir
[
p
.block
];
let
successor_points
=
if
p
.statement_index
<
block_data
.statements
.len
()
{
vec!
[
Location
{
statement_index
:
p
.statement_index
+
1
,
..
p
}]
}
else
{
block_data
.terminator
()
.successors
()
.iter
()
.map
(|
&
basic_block
|
Location
{
statement_index
:
0
,
block
:
basic_block
,
})
.collect
::
<
Vec
<
_
>>
()
};
if
successor_points
.is_empty
()
{
// If we reach the END point in the graph, then copy
// over any skolemized end points in the `from_region`
// and make sure they are included in the `to_region`.
for
region_decl
in
self
.infcx.tcx.tables
.borrow
()
.free_region_map
()
{
// TODO(nashenas88) figure out skolemized_end points
let
block
=
self
.env.graph
.skolemized_end
(
region_decl
.name
);
let
skolemized_end_point
=
Location
{
block
,
statement_index
:
0
,
};
changed
|
=
to_region
.add_point
(
skolemized_end_point
);
}
}
else
{
stack
.extend
(
successor_points
);
}
}
changed
}
}
src/librustc_mir/transform/nll/mod.rs
浏览文件 @
cc2a1c7b
...
...
@@ -8,13 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
self
::
infer
::
InferenceContext
;
use
rustc
::
ty
::
TypeFoldable
;
use
rustc
::
ty
::
subst
::{
Kind
,
Substs
};
use
rustc
::
ty
::{
Ty
,
TyCtxt
,
ClosureSubsts
,
RegionVid
,
RegionKind
};
use
rustc
::
mir
::{
Mir
,
Location
,
Rvalue
,
BasicBlock
,
Statement
,
StatementKind
};
use
rustc
::
mir
::
visit
::{
MutVisitor
,
Lookup
};
use
rustc
::
mir
::
transform
::{
MirPass
,
MirSource
};
use
rustc
::
infer
::{
self
,
InferCtxt
};
use
rustc
::
infer
::{
self
as
rustc_infer
,
InferCtxt
};
use
rustc
::
util
::
nodemap
::
FxHashSet
;
use
rustc_data_structures
::
indexed_vec
::{
IndexVec
,
Idx
};
use
syntax_pos
::
DUMMY_SP
;
...
...
@@ -24,6 +25,8 @@
use
util
as
mir_util
;
use
self
::
mir_util
::
PassWhere
;
mod
infer
;
#[allow(dead_code)]
struct
NLLVisitor
<
'a
,
'gcx
:
'a
+
'tcx
,
'tcx
:
'a
>
{
lookup_map
:
HashMap
<
RegionVid
,
Lookup
>
,
...
...
@@ -40,14 +43,14 @@ pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
}
}
pub
fn
into_results
(
self
)
->
HashMap
<
RegionVid
,
Lookup
>
{
self
.lookup_map
pub
fn
into_results
(
self
)
->
(
HashMap
<
RegionVid
,
Lookup
>
,
IndexVec
<
RegionIndex
,
Region
>
)
{
(
self
.lookup_map
,
self
.regions
)
}
fn
renumber_regions
<
T
>
(
&
mut
self
,
value
:
&
T
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
{
self
.infcx.tcx
.fold_regions
(
value
,
&
mut
false
,
|
_
region
,
_
depth
|
{
self
.regions
.push
(
Region
::
default
());
self
.infcx
.next_region_var
(
infer
::
MiscVariable
(
DUMMY_SP
))
self
.infcx
.next_region_var
(
rustc_
infer
::
MiscVariable
(
DUMMY_SP
))
})
}
...
...
@@ -157,7 +160,9 @@ fn run_pass<'a, 'tcx>(&self,
}
Ok
(())
});
let
_
results
=
visitor
.into_results
();
let
(
_
lookup_map
,
regions
)
=
visitor
.into_results
();
let
inference_context
=
InferenceContext
::
new
(
regions
);
inference_context
.solve
(
infcx
,
&
renumbered_mir
);
})
}
}
...
...
@@ -173,6 +178,14 @@ fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
}
}
impl
Region
{
pub
fn
add_point
(
&
mut
self
,
point
:
Location
)
->
bool
{
self
.points
.insert
(
point
)
}
pub
fn
may_contain
(
&
self
,
point
:
Location
)
->
bool
{
self
.points
.contains
(
&
point
)
}
}
newtype_index!
(
RegionIndex
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录