Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
740117f9
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,发现更多精彩内容 >>
提交
740117f9
编写于
10月 31, 2018
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix bug in NLL error reporting
Account for incompatible universes and higher-ranked subtyping.
上级
a1be20c9
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
111 addition
and
8 deletion
+111
-8
src/librustc/ty/mod.rs
src/librustc/ty/mod.rs
+8
-1
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
..._mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+90
-6
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+12
-0
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
+1
-1
未找到文件。
src/librustc/ty/mod.rs
浏览文件 @
740117f9
...
...
@@ -1522,10 +1522,17 @@ pub fn next_universe(self) -> UniverseIndex {
/// True if `self` can name a name from `other` -- in other words,
/// if the set of names in `self` is a superset of those in
/// `other`.
/// `other`
(`self >= other`)
.
pub
fn
can_name
(
self
,
other
:
UniverseIndex
)
->
bool
{
self
.private
>=
other
.private
}
/// True if `self` cannot name some names from `other` -- in other
/// words, if the set of names in `self` is a strict subset of
/// those in `other` (`self < other`).
pub
fn
cannot_name
(
self
,
other
:
UniverseIndex
)
->
bool
{
self
.private
<
other
.private
}
}
/// The "placeholder index" fully defines a placeholder region.
...
...
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
浏览文件 @
740117f9
...
...
@@ -16,6 +16,7 @@
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
infer
::
error_reporting
::
nice_region_error
::
NiceRegionError
;
use
rustc
::
infer
::
InferCtxt
;
use
rustc
::
infer
::
NLLRegionVariableOrigin
;
use
rustc
::
mir
::{
ConstraintCategory
,
Location
,
Mir
};
use
rustc
::
ty
::{
self
,
RegionVid
};
use
rustc_data_structures
::
indexed_vec
::
IndexVec
;
...
...
@@ -177,6 +178,13 @@ fn find_constraint_paths_between_regions(
deque
.push_back
(
from_region
);
while
let
Some
(
r
)
=
deque
.pop_front
()
{
debug!
(
"find_constraint_paths_between_regions: from_region={:?} r={:?} value={}"
,
from_region
,
r
,
self
.region_value_str
(
r
),
);
// Check if we reached the region we were looking for. If so,
// we can reconstruct the path that led to it and return it.
if
target_test
(
r
)
{
...
...
@@ -238,7 +246,9 @@ pub(super) fn report_error(
)
{
debug!
(
"report_error(fr={:?}, outlived_fr={:?})"
,
fr
,
outlived_fr
);
let
(
category
,
_
,
span
)
=
self
.best_blame_constraint
(
mir
,
fr
,
|
r
|
r
==
outlived_fr
);
let
(
category
,
_
,
span
)
=
self
.best_blame_constraint
(
mir
,
fr
,
|
r
|
{
self
.provides_universal_region
(
r
,
fr
,
outlived_fr
)
});
// Check if we can use one of the "nice region errors".
if
let
(
Some
(
f
),
Some
(
o
))
=
(
self
.to_error_region
(
fr
),
self
.to_error_region
(
outlived_fr
))
{
...
...
@@ -296,6 +306,33 @@ pub(super) fn report_error(
};
}
/// We have a constraint `fr1: fr2` that is not satisfied, where
/// `fr2` represents some universal region. Here, `r` is some
/// region where we know that `fr1: r` and this function has the
/// job of determining whether `r` is "to blame" for the fact that
/// `fr1: fr2` is required.
///
/// This is true under two conditions:
///
/// - `r == fr2`
/// - `fr2` is `'static` and `r` is some placeholder in a universe
/// that cannot be named by `fr1`; in that case, we will require
/// that `fr1: 'static` because it is the only way to `fr1: r` to
/// be satisfied. (See `add_incompatible_universe`.)
fn
provides_universal_region
(
&
self
,
r
:
RegionVid
,
fr1
:
RegionVid
,
fr2
:
RegionVid
)
->
bool
{
debug!
(
"provides_universal_region(r={:?}, fr1={:?}, fr2={:?})"
,
r
,
fr1
,
fr2
);
let
result
=
{
r
==
fr2
||
{
fr2
==
self
.universal_regions.fr_static
&&
self
.cannot_name_placeholder
(
fr1
,
r
)
}
};
debug!
(
"provides_universal_region: result = {:?}"
,
result
);
result
}
/// Report a specialized error when `FnMut` closures return a reference to a captured variable.
/// This function expects `fr` to be local and `outlived_fr` to not be local.
///
...
...
@@ -636,11 +673,37 @@ fn add_static_impl_trait_suggestion(
// `elem`.
crate
fn
find_sub_region_live_at
(
&
self
,
fr1
:
RegionVid
,
elem
:
Location
)
->
RegionVid
{
debug!
(
"find_sub_region_live_at(fr1={:?}, elem={:?})"
,
fr1
,
elem
);
// Find all paths
let
(
_
path
,
r
)
=
self
.find_constraint_paths_between_regions
(
fr1
,
|
r
|
{
self
.find_constraint_paths_between_regions
(
fr1
,
|
r
|
{
// First look for some `r` such that `fr1: r` and `r` is live at `elem`
debug!
(
"find_sub_region_live_at: liveness_constraints for {:?} are {:?}"
,
r
,
self
.liveness_constraints
.region_value_str
(
r
),
);
self
.liveness_constraints
.contains
(
r
,
elem
)
})
.unwrap
();
r
})
.or_else
(||
{
// If we fail to find that, we may find some `r` such that
// `fr1: r` and `r` is a placeholder from some universe
// `fr1` cannot name. This would force `fr1` to be
// `'static`.
self
.find_constraint_paths_between_regions
(
fr1
,
|
r
|
{
self
.cannot_name_placeholder
(
fr1
,
r
)
})
})
.or_else
(||
{
// If we fail to find THAT, it may be that `fr1` is a
// placeholder that cannot "fit" into its SCC. In that
// case, there should be some `r` where `fr1: r`, both
// `fr1` and `r` are in the same SCC, and `fr1` is a
// placeholder that `r` cannot name. We can blame that
// edge.
self
.find_constraint_paths_between_regions
(
fr1
,
|
r
|
{
self
.constraint_sccs
.scc
(
fr1
)
==
self
.constraint_sccs
.scc
(
r
)
&&
self
.cannot_name_placeholder
(
r
,
fr1
)
})
})
.map
(|(
_
path
,
r
)|
r
)
.unwrap
()
}
// Finds a good span to blame for the fact that `fr1` outlives `fr2`.
...
...
@@ -650,7 +713,8 @@ fn add_static_impl_trait_suggestion(
fr1
:
RegionVid
,
fr2
:
RegionVid
,
)
->
(
ConstraintCategory
,
Span
)
{
let
(
category
,
_
,
span
)
=
self
.best_blame_constraint
(
mir
,
fr1
,
|
r
|
r
==
fr2
);
let
(
category
,
_
,
span
)
=
self
.best_blame_constraint
(
mir
,
fr1
,
|
r
|
self
.provides_universal_region
(
r
,
fr1
,
fr2
));
(
category
,
span
)
}
...
...
@@ -684,4 +748,24 @@ fn retrieve_closure_constraint_info(
false
}
/// If `r2` represents a placeholder region, then this returns
/// true if `r1` cannot name that placeholder in its
/// value. Otherwise, returns false.
fn
cannot_name_placeholder
(
&
self
,
r1
:
RegionVid
,
r2
:
RegionVid
)
->
bool
{
debug!
(
"cannot_name_value_of(r1={:?}, r2={:?})"
,
r1
,
r2
);
match
self
.definitions
[
r2
]
.origin
{
NLLRegionVariableOrigin
::
Placeholder
(
placeholder
)
=>
{
let
universe1
=
self
.definitions
[
r1
]
.universe
;
debug!
(
"cannot_name_value_of: universe1={:?} placeholder={:?}"
,
universe1
,
placeholder
);
universe1
.cannot_name
(
placeholder
.universe
)
}
NLLRegionVariableOrigin
::
FreeRegion
|
NLLRegionVariableOrigin
::
Existential
=>
false
,
}
}
}
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
浏览文件 @
740117f9
...
...
@@ -345,6 +345,13 @@ fn init_free_and_bound_regions(&mut self) {
if
scc_universe
.can_name
(
placeholder
.universe
)
{
self
.scc_values
.add_element
(
scc
,
placeholder
);
}
else
{
debug!
(
"init_free_and_bound_regions: placeholder {:?} is
\
not compatible with universe {:?} of its SCC {:?}"
,
placeholder
,
scc_universe
,
scc
,
);
self
.add_incompatible_universe
(
scc
);
}
}
...
...
@@ -471,6 +478,9 @@ fn propagate_constraints(&mut self, _mir: &Mir<'tcx>) {
let
mut
constraints
:
Vec
<
_
>
=
self
.constraints
.iter
()
.collect
();
constraints
.sort
();
constraints
.into_iter
()
.map
(|
c
|
(
c
,
self
.constraint_sccs
.scc
(
c
.sup
),
self
.constraint_sccs
.scc
(
c
.sub
)))
.collect
::
<
Vec
<
_
>>
()
});
// To propagate constraints, we walk the DAG induced by the
...
...
@@ -560,6 +570,8 @@ fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccInd
/// `'a` with `'b` and not `'static`. But it will have to do for
/// now.
fn
add_incompatible_universe
(
&
mut
self
,
scc
:
ConstraintSccIndex
)
{
debug!
(
"add_incompatible_universe(scc={:?})"
,
scc
);
let
fr_static
=
self
.universal_regions.fr_static
;
self
.scc_values
.add_all_points
(
scc
);
self
.scc_values
.add_element
(
scc
,
fr_static
);
...
...
src/librustc_mir/borrow_check/nll/type_check/mod.rs
浏览文件 @
740117f9
...
...
@@ -782,7 +782,7 @@ fn placeholder_region(
Some
(
&
v
)
=>
v
,
None
=>
{
let
origin
=
NLLRegionVariableOrigin
::
Placeholder
(
placeholder
);
let
region
=
infcx
.next_nll_region_var
(
origin
);
let
region
=
infcx
.next_nll_region_var
_in_universe
(
origin
,
placeholder
.universe
);
self
.placeholder_index_to_region
.push
(
region
);
region
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录