Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
eca55b58
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
eca55b58
编写于
6月 18, 2019
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rename to "member constraints"
上级
e39f66a8
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
275 addition
and
261 deletion
+275
-261
src/librustc/infer/canonical/mod.rs
src/librustc/infer/canonical/mod.rs
+5
-5
src/librustc/infer/canonical/query_response.rs
src/librustc/infer/canonical/query_response.rs
+5
-5
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/error_reporting/mod.rs
+6
-6
src/librustc/infer/lexical_region_resolve/mod.rs
src/librustc/infer/lexical_region_resolve/mod.rs
+47
-42
src/librustc/infer/mod.rs
src/librustc/infer/mod.rs
+3
-3
src/librustc/infer/opaque_types/mod.rs
src/librustc/infer/opaque_types/mod.rs
+6
-6
src/librustc/infer/region_constraints/mod.rs
src/librustc/infer/region_constraints/mod.rs
+23
-23
src/librustc/ty/structural_impls.rs
src/librustc/ty/structural_impls.rs
+1
-1
src/librustc_mir/borrow_check/nll/mod.rs
src/librustc_mir/borrow_check/nll/mod.rs
+3
-3
src/librustc_mir/borrow_check/nll/pick_constraints.rs
src/librustc_mir/borrow_check/nll/pick_constraints.rs
+61
-58
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
..._mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+5
-5
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+97
-94
src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
..._mir/borrow_check/nll/type_check/constraint_conversion.rs
+9
-6
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
+4
-4
未找到文件。
src/librustc/infer/canonical/mod.rs
浏览文件 @
eca55b58
...
...
@@ -23,7 +23,7 @@
use
crate
::
infer
::{
InferCtxt
,
RegionVariableOrigin
,
TypeVariableOrigin
,
TypeVariableOriginKind
};
use
crate
::
infer
::{
ConstVariableOrigin
,
ConstVariableOriginKind
};
use
crate
::
infer
::
region_constraints
::
Pick
Constraint
;
use
crate
::
infer
::
region_constraints
::
Member
Constraint
;
use
crate
::
mir
::
interpret
::
ConstValue
;
use
rustc_data_structures
::
indexed_vec
::
IndexVec
;
use
rustc_macros
::
HashStable
;
...
...
@@ -198,14 +198,14 @@ pub struct QueryResponse<'tcx, R> {
#[derive(Clone,
Debug,
Default,
HashStable)]
pub
struct
QueryRegionConstraints
<
'tcx
>
{
pub
outlives
:
Vec
<
QueryOutlivesConstraint
<
'tcx
>>
,
pub
pick_constraints
:
Vec
<
Pick
Constraint
<
'tcx
>>
,
pub
member_constraints
:
Vec
<
Member
Constraint
<
'tcx
>>
,
}
impl
QueryRegionConstraints
<
'_
>
{
/// Represents an empty (trivially true) set of region
/// constraints.
pub
fn
is_empty
(
&
self
)
->
bool
{
self
.outlives
.is_empty
()
&&
self
.
pick
_constraints
.is_empty
()
self
.outlives
.is_empty
()
&&
self
.
member
_constraints
.is_empty
()
}
}
...
...
@@ -558,14 +558,14 @@ impl<'a, 'tcx, R> Lift<'tcx> for QueryResponse<'a, R> {
BraceStructTypeFoldableImpl!
{
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
QueryRegionConstraints
<
'tcx
>
{
outlives
,
pick
_constraints
outlives
,
member
_constraints
}
}
BraceStructLiftImpl!
{
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
QueryRegionConstraints
<
'a
>
{
type
Lifted
=
QueryRegionConstraints
<
'tcx
>
;
outlives
,
pick
_constraints
outlives
,
member
_constraints
}
}
...
...
src/librustc/infer/canonical/query_response.rs
浏览文件 @
eca55b58
...
...
@@ -351,9 +351,9 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
})
);
// ...also include the query
pick
constraints.
output_query_region_constraints
.
pick
_constraints
.extend
(
query_response
.value.region_constraints.
pick
_constraints
.iter
()
.map
(|
p_c
|
{
// ...also include the query
member
constraints.
output_query_region_constraints
.
member
_constraints
.extend
(
query_response
.value.region_constraints.
member
_constraints
.iter
()
.map
(|
p_c
|
{
substitute_value
(
self
.tcx
,
&
result_subst
,
p_c
)
})
);
...
...
@@ -663,7 +663,7 @@ pub fn make_query_region_constraints<'tcx>(
constraints
,
verifys
,
givens
,
pick
_constraints
,
member
_constraints
,
}
=
region_constraints
;
assert
!
(
verifys
.is_empty
());
...
...
@@ -694,5 +694,5 @@ pub fn make_query_region_constraints<'tcx>(
)
.collect
();
QueryRegionConstraints
{
outlives
,
pick_constraints
:
pick
_constraints
.clone
()
}
QueryRegionConstraints
{
outlives
,
member_constraints
:
member
_constraints
.clone
()
}
}
src/librustc/infer/error_reporting/mod.rs
浏览文件 @
eca55b58
...
...
@@ -377,12 +377,12 @@ pub fn report_region_errors(
}
}
RegionResolutionError
::
Pick
ConstraintFailure
{
RegionResolutionError
::
Member
ConstraintFailure
{
opaque_type_def_id
,
hidden_ty
,
pick
_region
,
member
_region
,
span
:
_
,
option
_regions
:
_
,
choice
_regions
:
_
,
}
=>
{
let
hidden_ty
=
self
.resolve_vars_if_possible
(
&
hidden_ty
);
opaque_types
::
unexpected_hidden_region_diagnostic
(
...
...
@@ -390,7 +390,7 @@ pub fn report_region_errors(
Some
(
region_scope_tree
),
opaque_type_def_id
,
hidden_ty
,
pick
_region
,
member
_region
,
)
.emit
();
}
}
...
...
@@ -430,7 +430,7 @@ fn process_errors(
RegionResolutionError
::
GenericBoundFailure
(
..
)
=>
true
,
RegionResolutionError
::
ConcreteFailure
(
..
)
|
RegionResolutionError
::
SubSupConflict
(
..
)
|
RegionResolutionError
::
Pick
ConstraintFailure
{
..
}
=>
false
,
|
RegionResolutionError
::
Member
ConstraintFailure
{
..
}
=>
false
,
};
let
mut
errors
=
if
errors
.iter
()
.all
(|
e
|
is_bound_failure
(
e
))
{
...
...
@@ -448,7 +448,7 @@ fn process_errors(
RegionResolutionError
::
ConcreteFailure
(
ref
sro
,
_
,
_
)
=>
sro
.span
(),
RegionResolutionError
::
GenericBoundFailure
(
ref
sro
,
_
,
_
)
=>
sro
.span
(),
RegionResolutionError
::
SubSupConflict
(
_
,
ref
rvo
,
_
,
_
,
_
,
_
)
=>
rvo
.span
(),
RegionResolutionError
::
Pick
ConstraintFailure
{
span
,
..
}
=>
span
,
RegionResolutionError
::
Member
ConstraintFailure
{
span
,
..
}
=>
span
,
});
errors
}
...
...
src/librustc/infer/lexical_region_resolve/mod.rs
浏览文件 @
eca55b58
...
...
@@ -3,7 +3,7 @@
use
crate
::
hir
::
def_id
::
DefId
;
use
crate
::
infer
::
region_constraints
::
Constraint
;
use
crate
::
infer
::
region_constraints
::
GenericKind
;
use
crate
::
infer
::
region_constraints
::
Pick
Constraint
;
use
crate
::
infer
::
region_constraints
::
Member
Constraint
;
use
crate
::
infer
::
region_constraints
::
RegionConstraintData
;
use
crate
::
infer
::
region_constraints
::
VarInfos
;
use
crate
::
infer
::
region_constraints
::
VerifyBound
;
...
...
@@ -84,15 +84,15 @@ pub enum RegionResolutionError<'tcx> {
Region
<
'tcx
>
,
),
/// Indicates a failure of a `
Pick
Constraint`. These arise during
/// Indicates a failure of a `
Member
Constraint`. These arise during
/// impl trait processing explicitly -- basically, the impl trait's hidden type
/// included some region that it was not supposed to.
Pick
ConstraintFailure
{
Member
ConstraintFailure
{
span
:
Span
,
opaque_type_def_id
:
DefId
,
hidden_ty
:
Ty
<
'tcx
>
,
pick
_region
:
Region
<
'tcx
>
,
option
_regions
:
Vec
<
Region
<
'tcx
>>
,
member
_region
:
Region
<
'tcx
>
,
choice
_regions
:
Vec
<
Region
<
'tcx
>>
,
},
}
...
...
@@ -133,7 +133,7 @@ fn infer_variable_values(
self
.expand_givens
(
&
graph
);
loop
{
self
.expansion
(
&
mut
var_data
);
if
!
self
.enforce_
pick
_constraints
(
&
graph
,
&
mut
var_data
)
{
if
!
self
.enforce_
member
_constraints
(
&
graph
,
&
mut
var_data
)
{
break
;
}
}
...
...
@@ -197,16 +197,16 @@ fn expand_givens(&mut self, graph: &RegionGraph<'_>) {
}
}
/// Enforce all
pick
constraints and return true if anything
/// changed. See `enforce_
pick
_constraint` for more details.
fn
enforce_
pick
_constraints
(
/// Enforce all
member
constraints and return true if anything
/// changed. See `enforce_
member
_constraint` for more details.
fn
enforce_
member
_constraints
(
&
self
,
graph
:
&
RegionGraph
<
'tcx
>
,
var_values
:
&
mut
LexicalRegionResolutions
<
'tcx
>
,
)
->
bool
{
let
mut
any_changed
=
false
;
for
pick_constraint
in
&
self
.data.pick
_constraints
{
if
self
.enforce_
pick_constraint
(
graph
,
pick
_constraint
,
var_values
)
{
for
member_constraint
in
&
self
.data.member
_constraints
{
if
self
.enforce_
member_constraint
(
graph
,
member
_constraint
,
var_values
)
{
any_changed
=
true
;
}
}
...
...
@@ -230,39 +230,44 @@ fn enforce_pick_constraints(
///
/// From that list, we look for a *minimal* option `'o_min`. If we
/// find one, then we can enforce that `'r: 'o_min`.
fn
enforce_
pick
_constraint
(
fn
enforce_
member
_constraint
(
&
self
,
graph
:
&
RegionGraph
<
'tcx
>
,
pick_constraint
:
&
Pick
Constraint
<
'tcx
>
,
member_constraint
:
&
Member
Constraint
<
'tcx
>
,
var_values
:
&
mut
LexicalRegionResolutions
<
'tcx
>
,
)
->
bool
{
debug!
(
"enforce_
pick_constraint(pick_constraint={:#?})"
,
pick
_constraint
);
debug!
(
"enforce_
member_constraint(member_constraint={:#?})"
,
member
_constraint
);
// the constraint is some inference variable (`vid`) which
// must be equal to one of the options
let
pick_vid
=
match
pick_constraint
.pick
_region
{
let
member_vid
=
match
member_constraint
.member
_region
{
ty
::
ReVar
(
vid
)
=>
*
vid
,
_
=>
return
false
,
};
// The current value of `vid` is a lower bound LB -- i.e., we
// know that `LB <= vid` must be true.
let
pick_lower_bound
:
ty
::
Region
<
'tcx
>
=
match
var_values
.value
(
pick
_vid
)
{
let
member_lower_bound
:
ty
::
Region
<
'tcx
>
=
match
var_values
.value
(
member
_vid
)
{
VarValue
::
ErrorValue
=>
return
false
,
VarValue
::
Value
(
r
)
=>
r
,
};
// find all the "upper bounds" -- that is, each region `b` such that
// `r0 <= b` must hold.
let
(
pick_upper_bounds
,
_
)
=
self
.collect_concrete_regions
(
graph
,
pick_vid
,
OUTGOING
,
None
);
let
(
member_upper_bounds
,
_
)
=
self
.collect_concrete_regions
(
graph
,
member_vid
,
OUTGOING
,
None
,
);
// get an iterator over the *available
options
* -- that is,
// each c
onstraint regions `o` where `lb <= o` and `o
<= ub` for all the
// get an iterator over the *available
choice
* -- that is,
// each c
hoice region `c` where `lb <= c` and `c
<= ub` for all the
// upper bounds `ub`.
debug!
(
"enforce_
pick_constraint: upper_bounds={:#?}"
,
pick
_upper_bounds
);
let
mut
options
=
pick_constraint
.option
_regions
.iter
()
.filter
(|
option
|
{
self
.sub_concrete_regions
(
pick
_lower_bound
,
option
)
&&
pick
_upper_bounds
debug!
(
"enforce_
member_constraint: upper_bounds={:#?}"
,
member
_upper_bounds
);
let
mut
options
=
member_constraint
.choice
_regions
.iter
()
.filter
(|
option
|
{
self
.sub_concrete_regions
(
member
_lower_bound
,
option
)
&&
member
_upper_bounds
.iter
()
.all
(|
upper_bound
|
self
.sub_concrete_regions
(
option
,
upper_bound
.region
))
});
...
...
@@ -274,23 +279,23 @@ fn enforce_pick_constraint(
Some
(
&
r
)
=>
r
,
None
=>
return
false
,
};
debug!
(
"enforce_
pick
_constraint: least_choice={:?}"
,
least_choice
);
debug!
(
"enforce_
member
_constraint: least_choice={:?}"
,
least_choice
);
for
&
option
in
options
{
debug!
(
"enforce_
pick
_constraint: option={:?}"
,
option
);
debug!
(
"enforce_
member
_constraint: option={:?}"
,
option
);
if
!
self
.sub_concrete_regions
(
least_choice
,
option
)
{
if
self
.sub_concrete_regions
(
option
,
least_choice
)
{
debug!
(
"enforce_
pick
_constraint: new least choice"
);
debug!
(
"enforce_
member
_constraint: new least choice"
);
least_choice
=
option
;
}
else
{
debug!
(
"enforce_
pick
_constraint: no least choice"
);
debug!
(
"enforce_
member
_constraint: no least choice"
);
return
false
;
}
}
}
debug!
(
"enforce_
pick
_constraint: final least choice = {:?}"
,
least_choice
);
if
least_choice
!=
pick
_lower_bound
{
*
var_values
.value_mut
(
pick
_vid
)
=
VarValue
::
Value
(
least_choice
);
debug!
(
"enforce_
member
_constraint: final least choice = {:?}"
,
least_choice
);
if
least_choice
!=
member
_lower_bound
{
*
var_values
.value_mut
(
member
_vid
)
=
VarValue
::
Value
(
least_choice
);
true
}
else
{
false
...
...
@@ -547,20 +552,20 @@ fn collect_errors(
}
}
for
pick_constraint
in
&
self
.data.pick
_constraints
{
let
pick_region
=
var_data
.normalize
(
self
.tcx
(),
pick_constraint
.pick
_region
);
let
option_regions
=
pick
_constraint
.
option
_regions
for
member_constraint
in
&
self
.data.member
_constraints
{
let
member_region
=
var_data
.normalize
(
self
.tcx
(),
member_constraint
.member
_region
);
let
choice_regions
=
member
_constraint
.
choice
_regions
.iter
()
.map
(|
&
option_region
|
var_data
.normalize
(
self
.tcx
(),
option
_region
));
if
!
option_regions
.clone
()
.any
(|
option_region
|
pick_region
==
option
_region
)
{
let
span
=
self
.tcx
()
.def_span
(
pick
_constraint
.opaque_type_def_id
);
errors
.push
(
RegionResolutionError
::
Pick
ConstraintFailure
{
.map
(|
&
choice_region
|
var_data
.normalize
(
self
.tcx
(),
choice
_region
));
if
!
choice_regions
.clone
()
.any
(|
choice_region
|
member_region
==
choice
_region
)
{
let
span
=
self
.tcx
()
.def_span
(
member
_constraint
.opaque_type_def_id
);
errors
.push
(
RegionResolutionError
::
Member
ConstraintFailure
{
span
,
opaque_type_def_id
:
pick
_constraint
.opaque_type_def_id
,
hidden_ty
:
pick
_constraint
.hidden_ty
,
pick
_region
,
option_regions
:
option
_regions
.collect
(),
opaque_type_def_id
:
member
_constraint
.opaque_type_def_id
,
hidden_ty
:
member
_constraint
.hidden_ty
,
member
_region
,
choice_regions
:
choice
_regions
.collect
(),
});
}
}
...
...
src/librustc/infer/mod.rs
浏览文件 @
eca55b58
...
...
@@ -907,7 +907,7 @@ pub fn sub_regions(
/// Require that the region `r` be equal to one of the regions in
/// the set `regions`.
pub
fn
pick
_constraint
(
pub
fn
member
_constraint
(
&
self
,
opaque_type_def_id
:
DefId
,
definition_span
:
Span
,
...
...
@@ -915,9 +915,9 @@ pub fn pick_constraint(
region
:
ty
::
Region
<
'tcx
>
,
in_regions
:
&
Lrc
<
Vec
<
ty
::
Region
<
'tcx
>>>
,
)
{
debug!
(
"
pick
_constraint({:?} <: {:?})"
,
region
,
in_regions
);
debug!
(
"
member
_constraint({:?} <: {:?})"
,
region
,
in_regions
);
self
.borrow_region_constraints
()
.
pick
_constraint
(
opaque_type_def_id
,
definition_span
,
hidden_ty
,
region
,
in_regions
);
.
member
_constraint
(
opaque_type_def_id
,
definition_span
,
hidden_ty
,
region
,
in_regions
);
}
pub
fn
subtype_predicate
(
...
...
src/librustc/infer/opaque_types/mod.rs
浏览文件 @
eca55b58
...
...
@@ -393,7 +393,7 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
// we will create a "in bound" like `'r in
// ['a, 'b, 'c]`, where `'a..'c` are the
// regions that appear in the impl trait.
return
self
.generate_
pick
_constraint
(
return
self
.generate_
member
_constraint
(
concrete_ty
,
abstract_type_generics
,
opaque_defn
,
...
...
@@ -418,17 +418,17 @@ pub fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
/// related, we would generate a constraint `'r in ['a, 'b,
/// 'static]` for each region `'r` that appears in the hidden type
/// (i.e., it must be equal to `'a`, `'b`, or `'static`).
fn
generate_
pick
_constraint
(
fn
generate_
member
_constraint
(
&
self
,
concrete_ty
:
Ty
<
'tcx
>
,
abstract_type_generics
:
&
ty
::
Generics
,
opaque_defn
:
&
OpaqueTypeDecl
<
'tcx
>
,
opaque_type_def_id
:
DefId
,
)
{
// Create the set of
option
regions: each region in the hidden
// Create the set of
choice
regions: each region in the hidden
// type can be equal to any of the region parameters of the
// opaque type definition.
let
option
_regions
:
Lrc
<
Vec
<
ty
::
Region
<
'tcx
>>>
=
Lrc
::
new
(
let
choice
_regions
:
Lrc
<
Vec
<
ty
::
Region
<
'tcx
>>>
=
Lrc
::
new
(
abstract_type_generics
.params
.iter
()
...
...
@@ -443,12 +443,12 @@ fn generate_pick_constraint(
concrete_ty
.visit_with
(
&
mut
ConstrainOpaqueTypeRegionVisitor
{
tcx
:
self
.tcx
,
op
:
|
r
|
self
.
pick
_constraint
(
op
:
|
r
|
self
.
member
_constraint
(
opaque_type_def_id
,
opaque_defn
.definition_span
,
concrete_ty
,
r
,
&
option
_regions
,
&
choice
_regions
,
),
});
}
...
...
src/librustc/infer/region_constraints/mod.rs
浏览文件 @
eca55b58
...
...
@@ -81,10 +81,10 @@ pub struct RegionConstraintData<'tcx> {
/// be a region variable (or neither, as it happens).
pub
constraints
:
BTreeMap
<
Constraint
<
'tcx
>
,
SubregionOrigin
<
'tcx
>>
,
/// Constraints of the form `
pick R0 from
[R1, ..., Rn]`, meaning that
/// Constraints of the form `
R0 member of
[R1, ..., Rn]`, meaning that
/// `R0` must be equal to one of the regions `R1..Rn`. These occur
/// with `impl Trait` quite frequently.
pub
pick_constraints
:
Vec
<
Pick
Constraint
<
'tcx
>>
,
pub
member_constraints
:
Vec
<
Member
Constraint
<
'tcx
>>
,
/// A "verify" is something that we need to verify after inference
/// is done, but which does not directly affect inference in any
...
...
@@ -145,40 +145,40 @@ pub fn involves_placeholders(&self) -> bool {
}
}
/// Requires that `region` must be equal to one of the regions in `
option
_regions`.
/// Requires that `region` must be equal to one of the regions in `
choice
_regions`.
/// We often denote this using the syntax:
///
/// ```
///
pick R0 from
[O1..On]
///
R0 member of
[O1..On]
/// ```
#[derive(Debug,
Clone,
HashStable)]
pub
struct
Pick
Constraint
<
'tcx
>
{
pub
struct
Member
Constraint
<
'tcx
>
{
/// the def-id of the opaque type causing this constraint: used for error reporting
pub
opaque_type_def_id
:
DefId
,
/// the span where the hidden type was instantiated
pub
definition_span
:
Span
,
/// the hidden type in which `
pick
_region` appears: used for error reporting
/// the hidden type in which `
member
_region` appears: used for error reporting
pub
hidden_ty
:
Ty
<
'tcx
>
,
/// the region R0
pub
pick
_region
:
Region
<
'tcx
>
,
pub
member
_region
:
Region
<
'tcx
>
,
/// the options O1..On
pub
option
_regions
:
Lrc
<
Vec
<
Region
<
'tcx
>>>
,
pub
choice
_regions
:
Lrc
<
Vec
<
Region
<
'tcx
>>>
,
}
BraceStructTypeFoldableImpl!
{
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
Pick
Constraint
<
'tcx
>
{
opaque_type_def_id
,
definition_span
,
hidden_ty
,
pick_region
,
option
_regions
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
Member
Constraint
<
'tcx
>
{
opaque_type_def_id
,
definition_span
,
hidden_ty
,
member_region
,
choice
_regions
}
}
BraceStructLiftImpl!
{
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
Pick
Constraint
<
'a
>
{
type
Lifted
=
Pick
Constraint
<
'tcx
>
;
opaque_type_def_id
,
definition_span
,
hidden_ty
,
pick_region
,
option
_regions
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
Member
Constraint
<
'a
>
{
type
Lifted
=
Member
Constraint
<
'tcx
>
;
opaque_type_def_id
,
definition_span
,
hidden_ty
,
member_region
,
choice
_regions
}
}
...
...
@@ -688,26 +688,26 @@ pub fn make_eqregion(
}
}
pub
fn
pick
_constraint
(
pub
fn
member
_constraint
(
&
mut
self
,
opaque_type_def_id
:
DefId
,
definition_span
:
Span
,
hidden_ty
:
Ty
<
'tcx
>
,
pick
_region
:
ty
::
Region
<
'tcx
>
,
option
_regions
:
&
Lrc
<
Vec
<
ty
::
Region
<
'tcx
>>>
,
member
_region
:
ty
::
Region
<
'tcx
>
,
choice
_regions
:
&
Lrc
<
Vec
<
ty
::
Region
<
'tcx
>>>
,
)
{
debug!
(
"
pick_constraint({:?} in {:#?})"
,
pick_region
,
option
_regions
);
debug!
(
"
member_constraint({:?} in {:#?})"
,
member_region
,
choice
_regions
);
if
option_regions
.iter
()
.any
(|
&
r
|
r
==
pick
_region
)
{
if
choice_regions
.iter
()
.any
(|
&
r
|
r
==
member
_region
)
{
return
;
}
self
.data.
pick_constraints
.push
(
Pick
Constraint
{
self
.data.
member_constraints
.push
(
Member
Constraint
{
opaque_type_def_id
,
definition_span
,
hidden_ty
,
pick
_region
,
option_regions
:
option
_regions
.clone
()
member
_region
,
choice_regions
:
choice
_regions
.clone
()
});
}
...
...
@@ -975,12 +975,12 @@ impl<'tcx> RegionConstraintData<'tcx> {
pub
fn
is_empty
(
&
self
)
->
bool
{
let
RegionConstraintData
{
constraints
,
pick
_constraints
,
member
_constraints
,
verifys
,
givens
,
}
=
self
;
constraints
.is_empty
()
&&
pick
_constraints
.is_empty
()
&&
member
_constraints
.is_empty
()
&&
verifys
.is_empty
()
&&
givens
.is_empty
()
}
...
...
src/librustc/ty/structural_impls.rs
浏览文件 @
eca55b58
...
...
@@ -349,7 +349,7 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx
.lift
(
&
self
.0
)
.and_then
(|
a
|
{
tcx
.lift
(
&
self
.1
)
.and_then
(|
b
|
tcx
.lift
(
&
self
.2
)
.map
(|
c
|
(
a
,
b
,
c
)))
})
}
}
}
impl
<
'tcx
,
T
:
Lift
<
'tcx
>>
Lift
<
'tcx
>
for
Option
<
T
>
{
...
...
src/librustc_mir/borrow_check/nll/mod.rs
浏览文件 @
eca55b58
...
...
@@ -37,7 +37,7 @@
mod
universal_regions
;
mod
constraints
;
mod
pick
_constraints
;
mod
member
_constraints
;
use
self
::
facts
::
AllFacts
;
use
self
::
region_infer
::
RegionInferenceContext
;
...
...
@@ -130,7 +130,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
placeholder_index_to_region
:
_
,
mut
liveness_constraints
,
outlives_constraints
,
pick
_constraints
,
member
_constraints
,
closure_bounds_mapping
,
type_tests
,
}
=
constraints
;
...
...
@@ -152,7 +152,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
universal_region_relations
,
body
,
outlives_constraints
,
pick
_constraints
,
member
_constraints
,
closure_bounds_mapping
,
type_tests
,
liveness_constraints
,
...
...
src/librustc_mir/borrow_check/nll/pick_constraints.rs
浏览文件 @
eca55b58
use
crate
::
rustc
::
ty
::{
self
,
Ty
};
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
infer
::
region_constraints
::
Pick
Constraint
;
use
rustc
::
infer
::
region_constraints
::
Member
Constraint
;
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_data_structures
::
indexed_vec
::{
Idx
,
IndexVec
};
use
std
::
hash
::
Hash
;
use
std
::
ops
::
Index
;
use
syntax_pos
::
Span
;
/// Compactly stores a set of `
pick R0 in
[R1...Rn]` constraints,
/// Compactly stores a set of `
R0 member of
[R1...Rn]` constraints,
/// indexed by the region R0.
crate
struct
Pick
ConstraintSet
<
'tcx
,
R
>
crate
struct
Member
ConstraintSet
<
'tcx
,
R
>
where
R
:
Copy
+
Hash
+
Eq
,
{
/// Stores the first "
pick
" constraint for a given R0. This is an
/// Stores the first "
member
" constraint for a given R0. This is an
/// index into the `constraints` vector below.
first_constraints
:
FxHashMap
<
R
,
Nll
Pick
ConstraintIndex
>
,
first_constraints
:
FxHashMap
<
R
,
Nll
Member
ConstraintIndex
>
,
/// Stores the data about each `
pick R0 from
[R1..Rn]` constraint.
/// Stores the data about each `
R0 member of
[R1..Rn]` constraint.
/// These are organized into a linked list, so each constraint
/// contains the index of the next constraint with the same R0.
constraints
:
IndexVec
<
Nll
PickConstraintIndex
,
NllPick
Constraint
<
'tcx
>>
,
constraints
:
IndexVec
<
Nll
MemberConstraintIndex
,
NllMember
Constraint
<
'tcx
>>
,
/// Stores the `R1..Rn` regions for *all* sets. For any given
/// constraint, we keep two indices so that we can pull out a
/// slice.
option
_regions
:
Vec
<
ty
::
RegionVid
>
,
choice
_regions
:
Vec
<
ty
::
RegionVid
>
,
}
/// Represents a `
pick R0 in
[R1..Rn]` constraint
crate
struct
Nll
Pick
Constraint
<
'tcx
>
{
next_constraint
:
Option
<
Nll
Pick
ConstraintIndex
>
,
/// Represents a `
R0 member of
[R1..Rn]` constraint
crate
struct
Nll
Member
Constraint
<
'tcx
>
{
next_constraint
:
Option
<
Nll
Member
ConstraintIndex
>
,
/// The opaque type whose hidden type is being inferred. (Used in error reporting.)
crate
opaque_type_def_id
:
DefId
,
...
...
@@ -42,67 +42,70 @@
crate
hidden_ty
:
Ty
<
'tcx
>
,
/// The region R0.
crate
pick
_region_vid
:
ty
::
RegionVid
,
crate
member
_region_vid
:
ty
::
RegionVid
,
/// Index of `R1` in `
option_regions` vector from `Pick
ConstraintSet`.
/// Index of `R1` in `
choice_regions` vector from `Member
ConstraintSet`.
start_index
:
usize
,
/// Index of `Rn` in `
option_regions` vector from `Pick
ConstraintSet`.
/// Index of `Rn` in `
choice_regions` vector from `Member
ConstraintSet`.
end_index
:
usize
,
}
newtype_index!
{
crate
struct
Nll
Pick
ConstraintIndex
{
DEBUG_FORMAT
=
"
Pick
ConstraintIndex({})"
crate
struct
Nll
Member
ConstraintIndex
{
DEBUG_FORMAT
=
"
Member
ConstraintIndex({})"
}
}
impl
Default
for
Pick
ConstraintSet
<
'tcx
,
ty
::
RegionVid
>
{
impl
Default
for
Member
ConstraintSet
<
'tcx
,
ty
::
RegionVid
>
{
fn
default
()
->
Self
{
Self
{
first_constraints
:
Default
::
default
(),
constraints
:
Default
::
default
(),
option
_regions
:
Default
::
default
(),
choice
_regions
:
Default
::
default
(),
}
}
}
impl
<
'tcx
>
Pick
ConstraintSet
<
'tcx
,
ty
::
RegionVid
>
{
impl
<
'tcx
>
Member
ConstraintSet
<
'tcx
,
ty
::
RegionVid
>
{
crate
fn
push_constraint
(
&
mut
self
,
p_c
:
&
Pick
Constraint
<
'tcx
>
,
m_c
:
&
Member
Constraint
<
'tcx
>
,
mut
to_region_vid
:
impl
FnMut
(
ty
::
Region
<
'tcx
>
)
->
ty
::
RegionVid
,
)
{
debug!
(
"push_constraint(
p_c={:?})"
,
p
_c
);
let
pick_region_vid
:
ty
::
RegionVid
=
to_region_vid
(
p_c
.pick
_region
);
let
next_constraint
=
self
.first_constraints
.get
(
&
pick
_region_vid
)
.cloned
();
let
start_index
=
self
.
option
_regions
.len
();
let
end_index
=
start_index
+
p_c
.option
_regions
.len
();
debug!
(
"push_constraint:
pick_region_vid={:?}"
,
pick
_region_vid
);
let
constraint_index
=
self
.constraints
.push
(
Nll
Pick
Constraint
{
debug!
(
"push_constraint(
m_c={:?})"
,
m
_c
);
let
member_region_vid
:
ty
::
RegionVid
=
to_region_vid
(
m_c
.member
_region
);
let
next_constraint
=
self
.first_constraints
.get
(
&
member
_region_vid
)
.cloned
();
let
start_index
=
self
.
choice
_regions
.len
();
let
end_index
=
start_index
+
m_c
.choice
_regions
.len
();
debug!
(
"push_constraint:
member_region_vid={:?}"
,
member
_region_vid
);
let
constraint_index
=
self
.constraints
.push
(
Nll
Member
Constraint
{
next_constraint
,
pick
_region_vid
,
opaque_type_def_id
:
p
_c
.opaque_type_def_id
,
definition_span
:
p
_c
.definition_span
,
hidden_ty
:
p
_c
.hidden_ty
,
member
_region_vid
,
opaque_type_def_id
:
m
_c
.opaque_type_def_id
,
definition_span
:
m
_c
.definition_span
,
hidden_ty
:
m
_c
.hidden_ty
,
start_index
,
end_index
,
});
self
.first_constraints
.insert
(
pick
_region_vid
,
constraint_index
);
self
.
option_regions
.extend
(
p_c
.option
_regions
.iter
()
.map
(|
&
r
|
to_region_vid
(
r
)));
self
.first_constraints
.insert
(
member
_region_vid
,
constraint_index
);
self
.
choice_regions
.extend
(
m_c
.choice
_regions
.iter
()
.map
(|
&
r
|
to_region_vid
(
r
)));
}
}
impl
<
'tcx
,
R1
>
Pick
ConstraintSet
<
'tcx
,
R1
>
impl
<
'tcx
,
R1
>
Member
ConstraintSet
<
'tcx
,
R1
>
where
R1
:
Copy
+
Hash
+
Eq
,
{
/// Remap the "
pick
region" key using `map_fn`, producing a new
/// Remap the "
member
region" key using `map_fn`, producing a new
/// pick-constraint set. This is used in the NLL code to map from
/// the original `RegionVid` to an scc index. In some cases, we
/// may have multiple R1 values mapping to the same R2 key -- that
/// is ok, the two sets will be merged.
crate
fn
into_mapped
<
R2
>
(
self
,
mut
map_fn
:
impl
FnMut
(
R1
)
->
R2
)
->
PickConstraintSet
<
'tcx
,
R2
>
crate
fn
into_mapped
<
R2
>
(
self
,
mut
map_fn
:
impl
FnMut
(
R1
)
->
R2
,
)
->
MemberConstraintSet
<
'tcx
,
R2
>
where
R2
:
Copy
+
Hash
+
Eq
,
{
...
...
@@ -116,7 +119,7 @@ impl<'tcx, R1> PickConstraintSet<'tcx, R1>
// link from one list to point at the othe other (see
// `append_list`).
let
PickConstraintSet
{
first_constraints
,
mut
constraints
,
option
_regions
}
=
self
;
let
MemberConstraintSet
{
first_constraints
,
mut
constraints
,
choice
_regions
}
=
self
;
let
mut
first_constraints2
=
FxHashMap
::
default
();
first_constraints2
.reserve
(
first_constraints
.len
());
...
...
@@ -129,33 +132,33 @@ impl<'tcx, R1> PickConstraintSet<'tcx, R1>
first_constraints2
.insert
(
r2
,
start1
);
}
Pick
ConstraintSet
{
Member
ConstraintSet
{
first_constraints
:
first_constraints2
,
constraints
,
option
_regions
,
choice
_regions
,
}
}
}
impl
<
'tcx
,
R
>
Pick
ConstraintSet
<
'tcx
,
R
>
impl
<
'tcx
,
R
>
Member
ConstraintSet
<
'tcx
,
R
>
where
R
:
Copy
+
Hash
+
Eq
,
{
crate
fn
all_indices
(
&
self
,
)
->
impl
Iterator
<
Item
=
Nll
Pick
ConstraintIndex
>
{
)
->
impl
Iterator
<
Item
=
Nll
Member
ConstraintIndex
>
{
self
.constraints
.indices
()
}
/// Iterate down the constraint indices associated with a given
/// peek-region. You can then use `
option
_regions` and other
/// peek-region. You can then use `
choice
_regions` and other
/// methods to access data.
crate
fn
indices
(
&
self
,
pick
_region_vid
:
R
,
)
->
impl
Iterator
<
Item
=
Nll
Pick
ConstraintIndex
>
+
'_
{
let
mut
next
=
self
.first_constraints
.get
(
&
pick
_region_vid
)
.cloned
();
std
::
iter
::
from_fn
(
move
||
->
Option
<
Nll
Pick
ConstraintIndex
>
{
member
_region_vid
:
R
,
)
->
impl
Iterator
<
Item
=
Nll
Member
ConstraintIndex
>
+
'_
{
let
mut
next
=
self
.first_constraints
.get
(
&
member
_region_vid
)
.cloned
();
std
::
iter
::
from_fn
(
move
||
->
Option
<
Nll
Member
ConstraintIndex
>
{
if
let
Some
(
current
)
=
next
{
next
=
self
.constraints
[
current
]
.next_constraint
;
Some
(
current
)
...
...
@@ -165,25 +168,25 @@ impl<'tcx, R> PickConstraintSet<'tcx, R>
})
}
/// Returns the "
option regions" for a given pick constraint. This is the R1..Rn from
/// a constraint like:
/// Returns the "
choice regions" for a given member
///
constraint. This is the R1..Rn from
a constraint like:
///
/// ```
///
pick R0 in
[R1..Rn]
///
R0 member of
[R1..Rn]
/// ```
crate
fn
option_regions
(
&
self
,
pci
:
NllPick
ConstraintIndex
)
->
&
[
ty
::
RegionVid
]
{
let
Nll
Pick
Constraint
{
start_index
,
end_index
,
..
}
=
&
self
.constraints
[
pci
];
&
self
.
option
_regions
[
*
start_index
..*
end_index
]
crate
fn
choice_regions
(
&
self
,
pci
:
NllMember
ConstraintIndex
)
->
&
[
ty
::
RegionVid
]
{
let
Nll
Member
Constraint
{
start_index
,
end_index
,
..
}
=
&
self
.constraints
[
pci
];
&
self
.
choice
_regions
[
*
start_index
..*
end_index
]
}
}
impl
<
'tcx
,
R
>
Index
<
Nll
PickConstraintIndex
>
for
Pick
ConstraintSet
<
'tcx
,
R
>
impl
<
'tcx
,
R
>
Index
<
Nll
MemberConstraintIndex
>
for
Member
ConstraintSet
<
'tcx
,
R
>
where
R
:
Copy
+
Hash
+
Eq
,
{
type
Output
=
Nll
Pick
Constraint
<
'tcx
>
;
type
Output
=
Nll
Member
Constraint
<
'tcx
>
;
fn
index
(
&
self
,
i
:
Nll
PickConstraintIndex
)
->
&
NllPick
Constraint
<
'tcx
>
{
fn
index
(
&
self
,
i
:
Nll
MemberConstraintIndex
)
->
&
NllMember
Constraint
<
'tcx
>
{
&
self
.constraints
[
i
]
}
}
...
...
@@ -205,9 +208,9 @@ fn index(&self, i: NllPickConstraintIndex) -> &NllPickConstraint<'tcx> {
/// target_list: A -> B -> C -> D -> E -> F -> (None)
/// ```
fn
append_list
(
constraints
:
&
mut
IndexVec
<
Nll
PickConstraintIndex
,
NllPick
Constraint
<
'_
>>
,
target_list
:
Nll
Pick
ConstraintIndex
,
source_list
:
Nll
Pick
ConstraintIndex
,
constraints
:
&
mut
IndexVec
<
Nll
MemberConstraintIndex
,
NllMember
Constraint
<
'_
>>
,
target_list
:
Nll
Member
ConstraintIndex
,
source_list
:
Nll
Member
ConstraintIndex
,
)
{
let
mut
p
=
target_list
;
loop
{
...
...
src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
浏览文件 @
eca55b58
use
crate
::
borrow_check
::
nll
::
constraints
::
OutlivesConstraint
;
use
crate
::
borrow_check
::
nll
::
region_infer
::
Applied
Pick
Constraint
;
use
crate
::
borrow_check
::
nll
::
region_infer
::
Applied
Member
Constraint
;
use
crate
::
borrow_check
::
nll
::
region_infer
::
RegionInferenceContext
;
use
crate
::
borrow_check
::
nll
::
type_check
::
Locations
;
use
crate
::
borrow_check
::
nll
::
universal_regions
::
DefiningTy
;
...
...
@@ -224,13 +224,13 @@ fn find_constraint_paths_between_regions(
// But pick-constraints can also give rise to `'r: 'x`
// edges that were not part of the graph initially, so
// watch out for those.
let
outgoing_edges_from_picks
=
self
.applied_
pick
_constraints
(
r
)
let
outgoing_edges_from_picks
=
self
.applied_
member
_constraints
(
r
)
.iter
()
.map
(|
&
Applied
PickConstraint
{
best_option
,
pick
_constraint_index
,
..
}|
{
let
p_c
=
&
self
.
pick_constraints
[
pick
_constraint_index
];
.map
(|
&
Applied
MemberConstraint
{
min_choice
,
member
_constraint_index
,
..
}|
{
let
p_c
=
&
self
.
member_constraints
[
member
_constraint_index
];
OutlivesConstraint
{
sup
:
r
,
sub
:
best_option
,
sub
:
min_choice
,
locations
:
Locations
::
All
(
p_c
.definition_span
),
category
:
ConstraintCategory
::
OpaqueType
,
}
...
...
src/librustc_mir/borrow_check/nll/region_infer/mod.rs
浏览文件 @
eca55b58
...
...
@@ -3,7 +3,7 @@
use
crate
::
borrow_check
::
nll
::
constraints
::{
ConstraintSccIndex
,
OutlivesConstraint
,
OutlivesConstraintSet
,
};
use
crate
::
borrow_check
::
nll
::
pick_constraints
::{
PickConstraintSet
,
NllPick
ConstraintIndex
};
use
crate
::
borrow_check
::
nll
::
member_constraints
::{
MemberConstraintSet
,
NllMember
ConstraintIndex
};
use
crate
::
borrow_check
::
nll
::
region_infer
::
values
::{
PlaceholderIndices
,
RegionElement
,
ToElementIndex
,
};
...
...
@@ -72,14 +72,14 @@ pub struct RegionInferenceContext<'tcx> {
/// exists if `B: A`. Computed lazilly.
rev_constraint_graph
:
Option
<
Rc
<
VecGraph
<
ConstraintSccIndex
>>>
,
/// The "
pick R0 from
[R1..Rn]" constraints, indexed by SCC.
pick_constraints
:
Rc
<
Pick
ConstraintSet
<
'tcx
,
ConstraintSccIndex
>>
,
/// The "
R0 member of
[R1..Rn]" constraints, indexed by SCC.
member_constraints
:
Rc
<
Member
ConstraintSet
<
'tcx
,
ConstraintSccIndex
>>
,
/// Records the pick-constraints that we applied to each scc.
/// This is useful for error reporting. Once constraint
/// propagation is done, this vector is sorted according to
/// `
pick
_region_scc`.
pick_constraints_applied
:
Vec
<
AppliedPick
Constraint
>
,
/// `
member
_region_scc`.
member_constraints_applied
:
Vec
<
AppliedMember
Constraint
>
,
/// Map closure bounds to a `Span` that should be used for error reporting.
closure_bounds_mapping
:
...
...
@@ -116,30 +116,30 @@ pub struct RegionInferenceContext<'tcx> {
universal_region_relations
:
Rc
<
UniversalRegionRelations
<
'tcx
>>
,
}
/// Each time that `apply_
pick
_constraint` is successful, it appends
/// one of these structs to the `
pick
_constraints_applied` field.
/// Each time that `apply_
member
_constraint` is successful, it appends
/// one of these structs to the `
member
_constraints_applied` field.
/// This is used in error reporting to trace out what happened.
///
/// The way that `apply_
pick
_constraint` works is that it effectively
/// The way that `apply_
member
_constraint` works is that it effectively
/// adds a new lower bound to the SCC it is analyzing: so you wind up
/// with `'R: 'O` where `'R` is the pick-region and `'O` is the
/// minimal viable option.
#[derive(Copy,
Clone,
Debug,
Eq,
PartialEq,
Ord,
PartialOrd)]
struct
Applied
Pick
Constraint
{
/// The SCC that was affected. (The "
pick
region".)
struct
Applied
Member
Constraint
{
/// The SCC that was affected. (The "
member
region".)
///
/// The vector if `Applied
Pick
Constraint` elements is kept sorted
/// The vector if `Applied
Member
Constraint` elements is kept sorted
/// by this field.
pick
_region_scc
:
ConstraintSccIndex
,
member
_region_scc
:
ConstraintSccIndex
,
/// The "best option" that `apply_
pick
_constraint` found -- this was
/// added as an "ad-hoc" lower-bound to `
pick
_region_scc`.
best_option
:
ty
::
RegionVid
,
/// The "best option" that `apply_
member
_constraint` found -- this was
/// added as an "ad-hoc" lower-bound to `
member
_region_scc`.
min_choice
:
ty
::
RegionVid
,
/// The "
pick
constraint index" -- we can find out details about
/// The "
member
constraint index" -- we can find out details about
/// the constraint from
/// `set.
pick_constraints[pick
_constraint_index]`.
pick_constraint_index
:
NllPick
ConstraintIndex
,
/// `set.
member_constraints[member
_constraint_index]`.
member_constraint_index
:
NllMember
ConstraintIndex
,
}
struct
RegionDefinition
<
'tcx
>
{
...
...
@@ -234,7 +234,7 @@ pub(crate) fn new(
universal_region_relations
:
Rc
<
UniversalRegionRelations
<
'tcx
>>
,
_
body
:
&
Body
<
'tcx
>
,
outlives_constraints
:
OutlivesConstraintSet
,
pick_constraints_in
:
Pick
ConstraintSet
<
'tcx
,
RegionVid
>
,
member_constraints_in
:
Member
ConstraintSet
<
'tcx
,
RegionVid
>
,
closure_bounds_mapping
:
FxHashMap
<
Location
,
FxHashMap
<
(
RegionVid
,
RegionVid
),
(
ConstraintCategory
,
Span
)
>
,
...
...
@@ -266,7 +266,8 @@ pub(crate) fn new(
let
scc_representatives
=
Self
::
compute_scc_representatives
(
&
constraint_sccs
,
&
definitions
);
let
pick_constraints
=
Rc
::
new
(
pick_constraints_in
.into_mapped
(|
r
|
constraint_sccs
.scc
(
r
)));
let
member_constraints
=
Rc
::
new
(
member_constraints_in
.into_mapped
(|
r
|
constraint_sccs
.scc
(
r
)));
let
mut
result
=
Self
{
definitions
,
...
...
@@ -275,8 +276,8 @@ pub(crate) fn new(
constraint_graph
,
constraint_sccs
,
rev_constraint_graph
:
None
,
pick
_constraints
,
pick
_constraints_applied
:
Vec
::
new
(),
member
_constraints
,
member
_constraints_applied
:
Vec
::
new
(),
closure_bounds_mapping
,
scc_universes
,
scc_representatives
,
...
...
@@ -447,12 +448,12 @@ pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
/// Once region solving has completed, this function will return
/// the pick-constraints that were applied to the value of a given
/// region `r`. See `Applied
Pick
Constraint`.
fn
applied_
pick_constraints
(
&
self
,
r
:
impl
ToRegionVid
)
->
&
[
AppliedPick
Constraint
]
{
/// region `r`. See `Applied
Member
Constraint`.
fn
applied_
member_constraints
(
&
self
,
r
:
impl
ToRegionVid
)
->
&
[
AppliedMember
Constraint
]
{
let
scc
=
self
.constraint_sccs
.scc
(
r
.to_region_vid
());
binary_search_util
::
binary_search_slice
(
&
self
.
pick
_constraints_applied
,
|
applied
|
applied
.
pick
_region_scc
,
&
self
.
member
_constraints_applied
,
|
applied
|
applied
.
member
_region_scc
,
&
scc
,
)
}
...
...
@@ -511,7 +512,7 @@ fn solve_inner(
errors_buffer
,
);
self
.check_
pick
_constraints
(
infcx
,
mir_def_id
,
errors_buffer
);
self
.check_
member
_constraints
(
infcx
,
mir_def_id
,
errors_buffer
);
let
outlives_requirements
=
outlives_requirements
.unwrap_or
(
vec!
[]);
...
...
@@ -548,9 +549,9 @@ fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
self
.propagate_constraint_sccs_if_new
(
scc_index
,
visited
);
}
// Sort the applied
pick
constraints so we can binary search
// Sort the applied
member
constraints so we can binary search
// through them later.
self
.
pick_constraints_applied
.sort_by_key
(|
applied
|
applied
.pick
_region_scc
);
self
.
member_constraints_applied
.sort_by_key
(|
applied
|
applied
.member
_region_scc
);
}
/// Computes the value of the SCC `scc_a` if it has not already
...
...
@@ -597,13 +598,13 @@ fn propagate_constraint_sccs_new(
}
}
// Now take
pick
constraints into account
let
pick_constraints
=
self
.pick
_constraints
.clone
();
for
p_c_i
in
pick
_constraints
.indices
(
scc_a
)
{
self
.apply_
pick
_constraint
(
// Now take
member
constraints into account
let
member_constraints
=
self
.member
_constraints
.clone
();
for
m_c_i
in
member
_constraints
.indices
(
scc_a
)
{
self
.apply_
member
_constraint
(
scc_a
,
p
_c_i
,
pick_constraints
.option_regions
(
p
_c_i
),
m
_c_i
,
member_constraints
.choice_regions
(
m
_c_i
),
);
}
...
...
@@ -614,9 +615,9 @@ fn propagate_constraint_sccs_new(
);
}
/// Invoked for each `
pick R0 from
[R1..Rn]` constraint.
/// Invoked for each `
member R0 of
[R1..Rn]` constraint.
///
/// `scc` is the SCC containing R0, and `
option
_regions` are the
/// `scc` is the SCC containing R0, and `
choice
_regions` are the
/// `R1..Rn` regions -- they are always known to be universal
/// regions (and if that's not true, we just don't attempt to
/// enforce the constraint).
...
...
@@ -625,34 +626,34 @@ fn propagate_constraint_sccs_new(
/// is considered a *lower bound*. If possible, we will modify
/// the constraint to set it equal to one of the option regions.
/// If we make any changes, returns true, else false.
fn
apply_
pick
_constraint
(
fn
apply_
member
_constraint
(
&
mut
self
,
scc
:
ConstraintSccIndex
,
pick_constraint_index
:
NllPick
ConstraintIndex
,
option
_regions
:
&
[
ty
::
RegionVid
],
member_constraint_index
:
NllMember
ConstraintIndex
,
choice
_regions
:
&
[
ty
::
RegionVid
],
)
->
bool
{
debug!
(
"apply_
pick_constraint(scc={:?}, option_regions={:#?})"
,
scc
,
option
_regions
,);
debug!
(
"apply_
member_constraint(scc={:?}, choice_regions={:#?})"
,
scc
,
choice
_regions
,);
if
let
Some
(
uh_oh
)
=
option
_regions
.iter
()
.find
(|
&&
r
|
!
self
.universal_regions
.is_universal_region
(
r
))
choice
_regions
.iter
()
.find
(|
&&
r
|
!
self
.universal_regions
.is_universal_region
(
r
))
{
// FIXME(#61773): This case can only occur with
// `impl_trait_in_bindings`, I believe, and we are just
// opting not to handle it for now. See #61773 for
// details.
bug!
(
"
pick
constraint for `{:?}` has an option region `{:?}`
\
"
member
constraint for `{:?}` has an option region `{:?}`
\
that is not a universal region"
,
self
.
pick_constraints
[
pick
_constraint_index
]
.opaque_type_def_id
,
self
.
member_constraints
[
member
_constraint_index
]
.opaque_type_def_id
,
uh_oh
,
);
}
// Create a mutable vector of the options. We'll try to winnow
// them down.
let
mut
option_regions
:
Vec
<
ty
::
RegionVid
>
=
option
_regions
.to_vec
();
let
mut
choice_regions
:
Vec
<
ty
::
RegionVid
>
=
choice
_regions
.to_vec
();
// The '
pick-region' in a pick-
constraint is part of the
// The '
member region' in a member
constraint is part of the
// hidden type, which must be in the root universe. Therefore,
// it cannot have any placeholders in its value.
assert
!
(
self
.scc_universes
[
scc
]
==
ty
::
UniverseIndex
::
ROOT
);
...
...
@@ -665,35 +666,37 @@ fn apply_pick_constraint(
// The existing value for `scc` is a lower-bound. This will
// consist of some set {P} + {LB} of points {P} and
// lower-bound free regions {LB}. As each
option
region O is a
// lower-bound free regions {LB}. As each
choice
region O is a
// free region, it will outlive the points. But we can only
// consider the option O if O: LB.
option
_regions
.retain
(|
&
o_r
|
{
choice
_regions
.retain
(|
&
o_r
|
{
self
.scc_values
.universal_regions_outlived_by
(
scc
)
.all
(|
lb
|
self
.universal_region_relations
.outlives
(
o_r
,
lb
))
});
debug!
(
"apply_
pick_constraint: after lb, option_regions={:?}"
,
option
_regions
);
debug!
(
"apply_
member_constraint: after lb, choice_regions={:?}"
,
choice
_regions
);
// Now find all the *upper bounds* -- that is, each UB is a free
// region that must outlive pick region R0 (`UB: R0`). Therefore,
// we need only keep an option O if `UB: O` for all UB.
if
option_regions
.len
()
>
1
{
// Now find all the *upper bounds* -- that is, each UB is a
// free region that must outlive the member region R0 (`UB:
// R0`). Therefore, we need only keep an option O if `UB: O`
// for all UB.
if
choice_regions
.len
()
>
1
{
let
universal_region_relations
=
self
.universal_region_relations
.clone
();
for
ub
in
self
.upper_bounds
(
scc
)
{
debug!
(
"apply_
pick
_constraint: ub={:?}"
,
ub
);
option
_regions
.retain
(|
&
o_r
|
universal_region_relations
.outlives
(
ub
,
o_r
));
debug!
(
"apply_
member
_constraint: ub={:?}"
,
ub
);
choice
_regions
.retain
(|
&
o_r
|
universal_region_relations
.outlives
(
ub
,
o_r
));
}
debug!
(
"apply_
pick_constraint: after ub, option_regions={:?}"
,
option
_regions
);
debug!
(
"apply_
member_constraint: after ub, choice_regions={:?}"
,
choice
_regions
);
}
// If we ruled everything out, we're done.
if
option
_regions
.is_empty
()
{
if
choice
_regions
.is_empty
()
{
return
false
;
}
// Otherwise, we need to find the minimum option, if any, and take that.
debug!
(
"apply_pick_constraint: option_regions remaining are {:#?}"
,
option_regions
);
// Otherwise, we need to find the minimum remaining choice, if
// any, and take that.
debug!
(
"apply_member_constraint: choice_regions remaining are {:#?}"
,
choice_regions
);
let
min
=
|
r1
:
ty
::
RegionVid
,
r2
:
ty
::
RegionVid
|
->
Option
<
ty
::
RegionVid
>
{
let
r1_outlives_r2
=
self
.universal_region_relations
.outlives
(
r1
,
r2
);
let
r2_outlives_r1
=
self
.universal_region_relations
.outlives
(
r2
,
r1
);
...
...
@@ -707,35 +710,35 @@ fn apply_pick_constraint(
None
}
};
let
mut
best_option
=
option
_regions
[
0
];
for
&
other_option
in
&
option
_regions
[
1
..
]
{
let
mut
min_choice
=
choice
_regions
[
0
];
for
&
other_option
in
&
choice
_regions
[
1
..
]
{
debug!
(
"apply_
pick_constraint: best_option
={:?} other_option={:?}"
,
best_option
,
other_option
,
"apply_
member_constraint: min_choice
={:?} other_option={:?}"
,
min_choice
,
other_option
,
);
match
min
(
best_option
,
other_option
)
{
Some
(
m
)
=>
best_option
=
m
,
match
min
(
min_choice
,
other_option
)
{
Some
(
m
)
=>
min_choice
=
m
,
None
=>
{
debug!
(
"apply_
pick_constraint: {:?} and {:?} are incomparable --> no best
choice"
,
best_option
,
other_option
,
"apply_
member_constraint: {:?} and {:?} are incomparable; no min
choice"
,
min_choice
,
other_option
,
);
return
false
;
}
}
}
let
best_option_scc
=
self
.constraint_sccs
.scc
(
best_option
);
let
min_choice_scc
=
self
.constraint_sccs
.scc
(
min_choice
);
debug!
(
"apply_
pick_constraint: best_choice={:?} best_option
_scc={:?}"
,
best_option
,
best_option
_scc
,
"apply_
member_constraint: min_choice={:?} best_choice
_scc={:?}"
,
min_choice
,
min_choice
_scc
,
);
if
self
.scc_values
.add_region
(
scc
,
best_option
_scc
)
{
self
.
pick_constraints_applied
.push
(
AppliedPick
Constraint
{
pick
_region_scc
:
scc
,
best_option
,
pick
_constraint_index
,
if
self
.scc_values
.add_region
(
scc
,
min_choice
_scc
)
{
self
.
member_constraints_applied
.push
(
AppliedMember
Constraint
{
member
_region_scc
:
scc
,
min_choice
,
member
_constraint_index
,
});
true
...
...
@@ -1542,42 +1545,42 @@ fn check_bound_universal_region(
diag
.emit
();
}
fn
check_
pick
_constraints
(
fn
check_
member
_constraints
(
&
self
,
infcx
:
&
InferCtxt
<
'_
,
'tcx
>
,
mir_def_id
:
DefId
,
errors_buffer
:
&
mut
Vec
<
Diagnostic
>
,
)
{
let
pick_constraints
=
self
.pick
_constraints
.clone
();
for
p_c_i
in
pick
_constraints
.all_indices
()
{
debug!
(
"check_
pick_constraint(p_c_i={:?})"
,
p
_c_i
);
let
p_c
=
&
pick_constraints
[
p
_c_i
];
let
pick_region_vid
=
p_c
.pick
_region_vid
;
let
member_constraints
=
self
.member
_constraints
.clone
();
for
m_c_i
in
member
_constraints
.all_indices
()
{
debug!
(
"check_
member_constraint(m_c_i={:?})"
,
m
_c_i
);
let
m_c
=
&
member_constraints
[
m
_c_i
];
let
member_region_vid
=
m_c
.member
_region_vid
;
debug!
(
"check_
pick_constraint: pick
_region_vid={:?} with value {}"
,
pick
_region_vid
,
self
.region_value_str
(
pick
_region_vid
),
"check_
member_constraint: member
_region_vid={:?} with value {}"
,
member
_region_vid
,
self
.region_value_str
(
member
_region_vid
),
);
let
option_regions
=
pick_constraints
.option_regions
(
p
_c_i
);
debug!
(
"check_
pick_constraint: option_regions={:?}"
,
option
_regions
);
let
choice_regions
=
member_constraints
.choice_regions
(
m
_c_i
);
debug!
(
"check_
member_constraint: choice_regions={:?}"
,
choice
_regions
);
// did the pick-region wind up equal to any of the option regions?
if
let
Some
(
o
)
=
option
_regions
.iter
()
.find
(|
&&
o_r
|
{
self
.eval_equal
(
o_r
,
p_c
.pick
_region_vid
)
if
let
Some
(
o
)
=
choice
_regions
.iter
()
.find
(|
&&
o_r
|
{
self
.eval_equal
(
o_r
,
m_c
.member
_region_vid
)
})
{
debug!
(
"check_
pick
_constraint: evaluated as equal to {:?}"
,
o
);
debug!
(
"check_
member
_constraint: evaluated as equal to {:?}"
,
o
);
continue
;
}
// if not, report an error
let
region_scope_tree
=
&
infcx
.tcx
.region_scope_tree
(
mir_def_id
);
let
pick_region
=
infcx
.tcx
.mk_region
(
ty
::
ReVar
(
pick
_region_vid
));
let
member_region
=
infcx
.tcx
.mk_region
(
ty
::
ReVar
(
member
_region_vid
));
opaque_types
::
unexpected_hidden_region_diagnostic
(
infcx
.tcx
,
Some
(
region_scope_tree
),
p
_c
.opaque_type_def_id
,
p
_c
.hidden_ty
,
pick
_region
,
m
_c
.opaque_type_def_id
,
m
_c
.hidden_ty
,
member
_region
,
)
.buffer
(
errors_buffer
);
}
...
...
src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
浏览文件 @
eca55b58
...
...
@@ -53,20 +53,23 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
pub
(
super
)
fn
convert_all
(
&
mut
self
,
query_constraints
:
&
QueryRegionConstraints
<
'tcx
>
)
{
debug!
(
"convert_all(query_constraints={:#?})"
,
query_constraints
);
let
QueryRegionConstraints
{
outlives
,
pick
_constraints
}
=
query_constraints
;
let
QueryRegionConstraints
{
outlives
,
member
_constraints
}
=
query_constraints
;
// Annoying: to invoke `self.to_region_vid`, we need access to
// `self.constraints`, but we also want to be mutating
// `self.
pick
_constraints`. For now, just swap out the value
// `self.
member
_constraints`. For now, just swap out the value
// we want and replace at the end.
let
mut
tmp
=
std
::
mem
::
replace
(
&
mut
self
.constraints.pick_constraints
,
Default
::
default
());
for
pick_constraint
in
pick_constraints
{
let
mut
tmp
=
std
::
mem
::
replace
(
&
mut
self
.constraints.member_constraints
,
Default
::
default
(),
);
for
member_constraint
in
member_constraints
{
tmp
.push_constraint
(
pick
_constraint
,
member
_constraint
,
|
r
|
self
.to_region_vid
(
r
),
);
}
self
.constraints.
pick
_constraints
=
tmp
;
self
.constraints.
member
_constraints
=
tmp
;
for
query_constraint
in
outlives
{
self
.convert
(
query_constraint
);
...
...
src/librustc_mir/borrow_check/nll/type_check/mod.rs
浏览文件 @
eca55b58
...
...
@@ -5,7 +5,7 @@
use
crate
::
borrow_check
::
borrow_set
::
BorrowSet
;
use
crate
::
borrow_check
::
location
::
LocationTable
;
use
crate
::
borrow_check
::
nll
::
constraints
::{
OutlivesConstraintSet
,
OutlivesConstraint
};
use
crate
::
borrow_check
::
nll
::
pick_constraints
::
Pick
ConstraintSet
;
use
crate
::
borrow_check
::
nll
::
member_constraints
::
Member
ConstraintSet
;
use
crate
::
borrow_check
::
nll
::
facts
::
AllFacts
;
use
crate
::
borrow_check
::
nll
::
region_infer
::
values
::
LivenessValues
;
use
crate
::
borrow_check
::
nll
::
region_infer
::
values
::
PlaceholderIndex
;
...
...
@@ -129,7 +129,7 @@ pub(crate) fn type_check<'tcx>(
placeholder_index_to_region
:
IndexVec
::
default
(),
liveness_constraints
:
LivenessValues
::
new
(
elements
.clone
()),
outlives_constraints
:
OutlivesConstraintSet
::
default
(),
pick_constraints
:
Pick
ConstraintSet
::
default
(),
member_constraints
:
Member
ConstraintSet
::
default
(),
closure_bounds_mapping
:
Default
::
default
(),
type_tests
:
Vec
::
default
(),
};
...
...
@@ -889,7 +889,7 @@ struct BorrowCheckContext<'a, 'tcx> {
crate
outlives_constraints
:
OutlivesConstraintSet
,
crate
pick_constraints
:
Pick
ConstraintSet
<
'tcx
,
RegionVid
>
,
crate
member_constraints
:
Member
ConstraintSet
<
'tcx
,
RegionVid
>
,
crate
closure_bounds_mapping
:
FxHashMap
<
Location
,
FxHashMap
<
(
RegionVid
,
RegionVid
),
(
ConstraintCategory
,
Span
)
>>
,
...
...
@@ -2525,7 +2525,7 @@ fn prove_closure_bounds(
// constraints only come from `-> impl Trait` and
// friends which don't appear (thus far...) in
// closures.
pick
_constraints
:
vec!
[],
member
_constraints
:
vec!
[],
};
let
bounds_mapping
=
closure_constraints
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录