Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
96f3e560
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,发现更多精彩内容 >>
提交
96f3e560
编写于
3月 29, 2018
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
remove dependency map and instead use a linked list of constraints
上级
1ef1b923
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
55 addition
and
17 deletion
+55
-17
src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
+1
-0
src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
+1
-1
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+53
-16
未找到文件。
src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
浏览文件 @
96f3e560
...
...
@@ -84,6 +84,7 @@ fn for_each_constraint(
sub
,
point
,
span
,
next
:
_
,
}
=
constraint
;
with_msg
(
&
format!
(
"{:?}: {:?} @ {:?} due to {:?}"
,
...
...
src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
浏览文件 @
96f3e560
...
...
@@ -55,7 +55,7 @@ fn nodes(&'this self) -> dot::Nodes<'this, RegionVid> {
vids
.into_cow
()
}
fn
edges
(
&
'this
self
)
->
dot
::
Edges
<
'this
,
Constraint
>
{
(
&
self
.constraints
[
..
])
.into_cow
()
(
&
self
.constraints
.raw
[
..
])
.into_cow
()
}
// Render `a: b` as `a <- b`, indicating the flow
...
...
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
浏览文件 @
96f3e560
...
...
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
std
::
collections
::
HashMap
;
use
super
::
universal_regions
::
UniversalRegions
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
infer
::
InferCtxt
;
...
...
@@ -23,9 +21,9 @@
Local
,
Location
,
Mir
};
use
rustc
::
traits
::
ObligationCause
;
use
rustc
::
ty
::{
self
,
RegionVid
,
Ty
,
TypeFoldable
};
use
rustc
::
util
::
common
::
ErrorReported
;
use
rustc
::
util
::
common
::
{
self
,
ErrorReported
}
;
use
rustc_data_structures
::
bitvec
::
BitVector
;
use
rustc_data_structures
::
indexed_vec
::
IndexVec
;
use
rustc_data_structures
::
indexed_vec
::
{
Idx
,
IndexVec
}
;
use
std
::
fmt
;
use
std
::
rc
::
Rc
;
use
syntax
::
ast
;
...
...
@@ -61,8 +59,15 @@ pub struct RegionInferenceContext<'tcx> {
/// until `solve` is invoked.
inferred_values
:
Option
<
RegionValues
>
,
/// For each variable, stores the index of the first constraint
/// where that variable appears on the RHS. This is the start of a
/// 'linked list' threaded by the `next` field in `Constraint`.
///
/// This map is build when values are inferred.
dependency_map
:
Option
<
IndexVec
<
RegionVid
,
Option
<
ConstraintIndex
>>>
,
/// The constraints we have accumulated and used during solving.
constraints
:
Vec
<
Constraint
>
,
constraints
:
IndexVec
<
ConstraintIndex
,
Constraint
>
,
/// Type constraints that we check after solving.
type_tests
:
Vec
<
TypeTest
<
'tcx
>>
,
...
...
@@ -143,10 +148,22 @@ pub struct Constraint {
/// At this location.
point
:
Location
,
/// Later on, we thread the constraints onto a linked list
/// sorted by their `sub` field. So if you had:
///
/// Index | Constraint | Next Field
/// ----- | ---------- | ----------
/// 0 | `'a: 'b` | Some(2)
/// 1 | `'b: 'c` | None
/// 2 | `'c: 'b` | None
next
:
Option
<
ConstraintIndex
>
,
/// Where did this constraint arise?
span
:
Span
,
}
newtype_index!
(
ConstraintIndex
{
DEBUG_FORMAT
=
"ConstraintIndex({})"
});
/// A "type test" corresponds to an outlives constraint between a type
/// and a lifetime, like `T: 'x` or `<T as Foo>::Bar: 'x`. They are
/// translated from the `Verify` region constraints in the ordinary
...
...
@@ -259,7 +276,8 @@ pub(crate) fn new(
elements
:
elements
.clone
(),
liveness_constraints
:
RegionValues
::
new
(
elements
,
num_region_variables
),
inferred_values
:
None
,
constraints
:
Vec
::
new
(),
dependency_map
:
None
,
constraints
:
IndexVec
::
new
(),
type_tests
:
Vec
::
new
(),
universal_regions
,
};
...
...
@@ -387,6 +405,7 @@ pub(super) fn add_outlives(
sup
,
sub
,
point
,
next
:
None
,
});
}
...
...
@@ -403,6 +422,17 @@ pub(super) fn solve<'gcx>(
infcx
:
&
InferCtxt
<
'_
,
'gcx
,
'tcx
>
,
mir
:
&
Mir
<
'tcx
>
,
mir_def_id
:
DefId
,
)
->
Option
<
ClosureRegionRequirements
<
'gcx
>>
{
common
::
time
(
infcx
.tcx.sess
,
&
format!
(
"solve({:?})"
,
mir_def_id
),
||
{
self
.solve_inner
(
infcx
,
mir
,
mir_def_id
)
})
}
fn
solve_inner
<
'gcx
>
(
&
mut
self
,
infcx
:
&
InferCtxt
<
'_
,
'gcx
,
'tcx
>
,
mir
:
&
Mir
<
'tcx
>
,
mir_def_id
:
DefId
,
)
->
Option
<
ClosureRegionRequirements
<
'gcx
>>
{
assert
!
(
self
.inferred_values
.is_none
(),
"values already inferred"
);
...
...
@@ -448,6 +478,7 @@ pub(super) fn compute_causal_info(&self, mir: &Mir<'tcx>) -> RegionCausalInfo {
/// satisfied. Note that some values may grow **too** large to be
/// feasible, but we check this later.
fn
propagate_constraints
(
&
mut
self
,
mir
:
&
Mir
<
'tcx
>
)
{
self
.dependency_map
=
Some
(
self
.build_dependency_map
());
let
inferred_values
=
self
.compute_region_values
(
mir
,
TrackCauses
(
false
));
self
.inferred_values
=
Some
(
inferred_values
);
}
...
...
@@ -465,17 +496,17 @@ fn compute_region_values(&self, mir: &Mir<'tcx>, track_causes: TrackCauses) -> R
// constraints we have accumulated.
let
mut
inferred_values
=
self
.liveness_constraints
.duplicate
(
track_causes
);
let
dependency_map
=
self
.
build_dependency_m
ap
();
let
dependency_map
=
self
.
dependency_map
.as_ref
()
.unwr
ap
();
// Constraints that may need to be repropagated (initially all):
let
mut
dirty_list
:
Vec
<
_
>
=
(
0
..
self
.constraints
.len
()
)
.collect
();
let
mut
dirty_list
:
Vec
<
_
>
=
self
.constraints
.indices
(
)
.collect
();
// Set to 0 for each constraint that is on the dirty list:
let
mut
clean_bit_vec
=
BitVector
::
new
(
dirty_list
.len
());
debug!
(
"propagate_constraints: --------------------"
);
while
let
Some
(
constraint_idx
)
=
dirty_list
.pop
()
{
clean_bit_vec
.insert
(
constraint_idx
);
clean_bit_vec
.insert
(
constraint_idx
.index
()
);
let
constraint
=
&
self
.constraints
[
constraint_idx
];
debug!
(
"propagate_constraints: constraint={:?}"
,
constraint
);
...
...
@@ -497,10 +528,12 @@ fn compute_region_values(&self, mir: &Mir<'tcx>, track_causes: TrackCauses) -> R
debug!
(
"propagate_constraints: sub={:?}"
,
constraint
.sub
);
debug!
(
"propagate_constraints: sup={:?}"
,
constraint
.sup
);
for
&
dep_idx
in
dependency_map
.get
(
&
constraint
.sup
)
.unwrap_or
(
&
vec!
[])
{
if
clean_bit_vec
.remove
(
dep_idx
)
{
let
mut
opt_dep_idx
=
dependency_map
[
constraint
.sup
];
while
let
Some
(
dep_idx
)
=
opt_dep_idx
{
if
clean_bit_vec
.remove
(
dep_idx
.index
())
{
dirty_list
.push
(
dep_idx
);
}
opt_dep_idx
=
self
.constraints
[
dep_idx
]
.next
;
}
}
...
...
@@ -514,11 +547,15 @@ fn compute_region_values(&self, mir: &Mir<'tcx>, track_causes: TrackCauses) -> R
/// indices of constraints that need to be re-evaluated when X changes.
/// These are constraints like Y: X @ P -- so if X changed, we may
/// need to grow Y.
fn
build_dependency_map
(
&
self
)
->
HashMap
<
RegionVid
,
Vec
<
usize
>>
{
let
mut
map
=
HashMap
::
new
();
for
(
idx
,
constraint
)
in
self
.constraints
.iter
()
.enumerate
()
{
map
.entry
(
constraint
.sub
)
.or_insert
(
Vec
::
new
())
.push
(
idx
);
#[inline(never)]
fn
build_dependency_map
(
&
mut
self
)
->
IndexVec
<
RegionVid
,
Option
<
ConstraintIndex
>>
{
let
mut
map
=
IndexVec
::
from_elem
(
None
,
&
self
.definitions
);
for
(
idx
,
constraint
)
in
self
.constraints
.iter_enumerated_mut
()
.rev
()
{
let
mut
head
=
&
mut
map
[
constraint
.sub
];
debug_assert!
(
constraint
.next
.is_none
());
constraint
.next
=
*
head
;
*
head
=
Some
(
idx
);
}
map
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录