Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
66fe4ff7
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
66fe4ff7
编写于
2月 26, 2019
作者:
S
Santiago Pastorino
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move unroll_place to Place::unroll
上级
6ed6f146
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
80 addition
and
79 deletion
+80
-79
src/librustc/mir/mod.rs
src/librustc/mir/mod.rs
+75
-0
src/librustc_mir/borrow_check/places_conflict.rs
src/librustc_mir/borrow_check/places_conflict.rs
+5
-79
未找到文件。
src/librustc/mir/mod.rs
浏览文件 @
66fe4ff7
...
...
@@ -2058,6 +2058,81 @@ pub fn base_local(&self) -> Option<Local> {
Place
::
Base
(
PlaceBase
::
Static
(
..
))
=>
None
,
}
}
/// Recursively "unroll" a place into a `PlaceComponents` list,
/// invoking `op` with a `PlaceComponentsIter`.
pub
fn
unroll
<
R
>
(
&
self
,
next
:
Option
<&
PlaceComponents
<
'_
,
'tcx
>>
,
op
:
impl
FnOnce
(
PlaceComponentsIter
<
'_
,
'tcx
>
)
->
R
,
)
->
R
{
match
self
{
Place
::
Projection
(
interior
)
=>
interior
.base
.unroll
(
Some
(
&
PlaceComponents
{
component
:
self
,
next
,
}),
op
,
),
Place
::
Base
(
PlaceBase
::
Local
(
_
))
|
Place
::
Base
(
PlaceBase
::
Static
(
_
))
=>
{
let
list
=
PlaceComponents
{
component
:
self
,
next
,
};
op
(
list
.iter
())
}
}
}
}
/// A linked list of places running up the stack; begins with the
/// innermost place and extends to projections (e.g., `a.b` would have
/// the place `a` with a "next" pointer to `a.b`). Created by
/// `Place::unroll`.
///
/// N.B., this particular impl strategy is not the most obvious. It was
/// chosen because it makes a measurable difference to NLL
/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
pub
struct
PlaceComponents
<
'p
,
'tcx
:
'p
>
{
pub
component
:
&
'p
Place
<
'tcx
>
,
pub
next
:
Option
<&
'p
PlaceComponents
<
'p
,
'tcx
>>
,
}
impl
<
'p
,
'tcx
>
PlaceComponents
<
'p
,
'tcx
>
{
/// Converts a list of `Place` components into an iterator; this
/// iterator yields up a never-ending stream of `Option<&Place>`.
/// These begin with the "innermost" place and then with each
/// projection therefrom. So given a place like `a.b.c` it would
/// yield up:
///
/// ```notrust
/// Some(`a`), Some(`a.b`), Some(`a.b.c`), None, None, ...
/// ```
fn
iter
(
&
self
)
->
PlaceComponentsIter
<
'_
,
'tcx
>
{
PlaceComponentsIter
{
value
:
Some
(
self
)
}
}
}
/// Iterator over components; see `PlaceComponents::iter` for more
/// information.
///
/// N.B., this is not a *true* Rust iterator -- the code above just
/// manually invokes `next`. This is because we (sometimes) want to
/// keep executing even after `None` has been returned.
pub
struct
PlaceComponentsIter
<
'p
,
'tcx
:
'p
>
{
pub
value
:
Option
<&
'p
PlaceComponents
<
'p
,
'tcx
>>
,
}
impl
<
'p
,
'tcx
>
PlaceComponentsIter
<
'p
,
'tcx
>
{
pub
fn
next
(
&
mut
self
)
->
Option
<&
'p
Place
<
'tcx
>>
{
if
let
Some
(
&
PlaceComponents
{
component
,
next
})
=
self
.value
{
self
.value
=
next
;
Some
(
component
)
}
else
{
None
}
}
}
impl
<
'tcx
>
Debug
for
Place
<
'tcx
>
{
...
...
src/librustc_mir/borrow_check/places_conflict.rs
浏览文件 @
66fe4ff7
...
...
@@ -2,7 +2,9 @@
use
crate
::
borrow_check
::
Overlap
;
use
crate
::
borrow_check
::{
Deep
,
Shallow
,
AccessDepth
};
use
rustc
::
hir
;
use
rustc
::
mir
::{
BorrowKind
,
Mir
,
Place
,
PlaceBase
,
Projection
,
ProjectionElem
,
StaticKind
};
use
rustc
::
mir
::{
BorrowKind
,
Mir
,
Place
,
PlaceBase
,
Projection
,
ProjectionElem
,
PlaceComponentsIter
,
StaticKind
};
use
rustc
::
ty
::{
self
,
TyCtxt
};
use
std
::
cmp
::
max
;
...
...
@@ -65,8 +67,8 @@ pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
}
}
unroll_place
(
borrow_place
,
None
,
|
borrow_components
|
{
unroll_place
(
access_place
,
None
,
|
access_components
|
{
borrow_place
.unroll
(
None
,
|
borrow_components
|
{
access_place
.unroll
(
None
,
|
access_components
|
{
place_components_conflict
(
tcx
,
mir
,
...
...
@@ -272,82 +274,6 @@ fn place_components_conflict<'gcx, 'tcx>(
}
}
/// A linked list of places running up the stack; begins with the
/// innermost place and extends to projections (e.g., `a.b` would have
/// the place `a` with a "next" pointer to `a.b`). Created by
/// `unroll_place`.
///
/// N.B., this particular impl strategy is not the most obvious. It was
/// chosen because it makes a measurable difference to NLL
/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
struct
PlaceComponents
<
'p
,
'tcx
:
'p
>
{
component
:
&
'p
Place
<
'tcx
>
,
next
:
Option
<&
'p
PlaceComponents
<
'p
,
'tcx
>>
,
}
impl
<
'p
,
'tcx
>
PlaceComponents
<
'p
,
'tcx
>
{
/// Converts a list of `Place` components into an iterator; this
/// iterator yields up a never-ending stream of `Option<&Place>`.
/// These begin with the "innermost" place and then with each
/// projection therefrom. So given a place like `a.b.c` it would
/// yield up:
///
/// ```notrust
/// Some(`a`), Some(`a.b`), Some(`a.b.c`), None, None, ...
/// ```
fn
iter
(
&
self
)
->
PlaceComponentsIter
<
'_
,
'tcx
>
{
PlaceComponentsIter
{
value
:
Some
(
self
)
}
}
}
/// Iterator over components; see `PlaceComponents::iter` for more
/// information.
///
/// N.B., this is not a *true* Rust iterator -- the code above just
/// manually invokes `next`. This is because we (sometimes) want to
/// keep executing even after `None` has been returned.
struct
PlaceComponentsIter
<
'p
,
'tcx
:
'p
>
{
value
:
Option
<&
'p
PlaceComponents
<
'p
,
'tcx
>>
,
}
impl
<
'p
,
'tcx
>
PlaceComponentsIter
<
'p
,
'tcx
>
{
fn
next
(
&
mut
self
)
->
Option
<&
'p
Place
<
'tcx
>>
{
if
let
Some
(
&
PlaceComponents
{
component
,
next
})
=
self
.value
{
self
.value
=
next
;
Some
(
component
)
}
else
{
None
}
}
}
/// Recursively "unroll" a place into a `PlaceComponents` list,
/// invoking `op` with a `PlaceComponentsIter`.
fn
unroll_place
<
'tcx
,
R
>
(
place
:
&
Place
<
'tcx
>
,
next
:
Option
<&
PlaceComponents
<
'_
,
'tcx
>>
,
op
:
impl
FnOnce
(
PlaceComponentsIter
<
'_
,
'tcx
>
)
->
R
,
)
->
R
{
match
place
{
Place
::
Projection
(
interior
)
=>
unroll_place
(
&
interior
.base
,
Some
(
&
PlaceComponents
{
component
:
place
,
next
,
}),
op
,
),
Place
::
Base
(
PlaceBase
::
Local
(
_
))
|
Place
::
Base
(
PlaceBase
::
Static
(
_
))
=>
{
let
list
=
PlaceComponents
{
component
:
place
,
next
,
};
op
(
list
.iter
())
}
}
}
// Given that the bases of `elem1` and `elem2` are always either equal
// or disjoint (and have the same type!), return the overlap situation
// between `elem1` and `elem2`.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录