Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5e6027c6
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,发现更多精彩内容 >>
提交
5e6027c6
编写于
3月 07, 2021
作者:
M
Matthew Jasper
提交者:
Rémy Rakic
8月 15, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Track causes for universes created during borrowck
上级
e271383c
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
329 addition
and
129 deletion
+329
-129
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_infer/src/infer/mod.rs
+1
-1
compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs
...c_mir/src/borrow_check/diagnostics/bound_region_errors.rs
+110
-0
compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
+2
-0
compiler/rustc_mir/src/borrow_check/nll.rs
compiler/rustc_mir/src/borrow_check/nll.rs
+2
-0
compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
+6
-1
compiler/rustc_mir/src/borrow_check/type_check/canonical.rs
compiler/rustc_mir/src/borrow_check/type_check/canonical.rs
+158
-0
compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
...ler/rustc_mir/src/borrow_check/type_check/input_output.rs
+1
-1
compiler/rustc_mir/src/borrow_check/type_check/mod.rs
compiler/rustc_mir/src/borrow_check/type_check/mod.rs
+29
-123
compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs
compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs
+20
-3
未找到文件。
compiler/rustc_infer/src/infer/mod.rs
浏览文件 @
5e6027c6
...
...
@@ -1506,7 +1506,7 @@ pub fn clear_caches(&self) {
self
.inner
.borrow_mut
()
.projection_cache
()
.clear
();
}
fn
universe
(
&
self
)
->
ty
::
UniverseIndex
{
pub
fn
universe
(
&
self
)
->
ty
::
UniverseIndex
{
self
.universe
.get
()
}
...
...
compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs
0 → 100644
浏览文件 @
5e6027c6
use
rustc_infer
::
infer
::
canonical
::
Canonical
;
use
rustc_middle
::
ty
::{
self
,
Ty
,
TypeFoldable
};
use
rustc_span
::
Span
;
use
rustc_trait_selection
::
traits
::
query
::
type_op
;
use
std
::
fmt
;
use
std
::
rc
::
Rc
;
use
crate
::
borrow_check
::
region_infer
::
values
::
RegionElement
;
use
crate
::
borrow_check
::
MirBorrowckCtxt
;
#[derive(Clone)]
crate
struct
UniverseInfo
<
'tcx
>
(
UniverseInfoInner
<
'tcx
>
);
/// What operation a universe was created for.
#[derive(Clone)]
enum
UniverseInfoInner
<
'tcx
>
{
/// Relating two types which have binders.
RelateTys
{
expected
:
Ty
<
'tcx
>
,
found
:
Ty
<
'tcx
>
},
/// Created from performing a `TypeOp`.
TypeOp
(
Rc
<
dyn
TypeOpInfo
<
'tcx
>
+
'tcx
>
),
/// Any other reason.
Other
,
}
impl
UniverseInfo
<
'tcx
>
{
crate
fn
other
()
->
UniverseInfo
<
'tcx
>
{
UniverseInfo
(
UniverseInfoInner
::
Other
)
}
crate
fn
relate
(
expected
:
Ty
<
'tcx
>
,
found
:
Ty
<
'tcx
>
)
->
UniverseInfo
<
'tcx
>
{
UniverseInfo
(
UniverseInfoInner
::
RelateTys
{
expected
,
found
})
}
crate
fn
_
report_error
(
&
self
,
_
mbcx
:
&
mut
MirBorrowckCtxt
<
'_
,
'tcx
>
,
_
placeholder
:
ty
::
PlaceholderRegion
,
_
error_element
:
RegionElement
,
_
span
:
Span
,
)
{
todo!
();
}
}
crate
trait
ToUniverseInfo
<
'tcx
>
{
fn
to_universe_info
(
self
,
base_universe
:
ty
::
UniverseIndex
)
->
UniverseInfo
<
'tcx
>
;
}
impl
<
'tcx
>
ToUniverseInfo
<
'tcx
>
for
Canonical
<
'tcx
,
ty
::
ParamEnvAnd
<
'tcx
,
type_op
::
prove_predicate
::
ProvePredicate
<
'tcx
>>>
{
fn
to_universe_info
(
self
,
base_universe
:
ty
::
UniverseIndex
)
->
UniverseInfo
<
'tcx
>
{
UniverseInfo
(
UniverseInfoInner
::
TypeOp
(
Rc
::
new
(
PredicateQuery
{
_
canonical_query
:
self
,
_
base_universe
:
base_universe
,
})))
}
}
impl
<
'tcx
,
T
:
Copy
+
fmt
::
Display
+
TypeFoldable
<
'tcx
>
+
'tcx
>
ToUniverseInfo
<
'tcx
>
for
Canonical
<
'tcx
,
ty
::
ParamEnvAnd
<
'tcx
,
type_op
::
Normalize
<
T
>>>
{
fn
to_universe_info
(
self
,
base_universe
:
ty
::
UniverseIndex
)
->
UniverseInfo
<
'tcx
>
{
UniverseInfo
(
UniverseInfoInner
::
TypeOp
(
Rc
::
new
(
NormalizeQuery
{
_
canonical_query
:
self
,
_
base_universe
:
base_universe
,
})))
}
}
impl
<
'tcx
>
ToUniverseInfo
<
'tcx
>
for
Canonical
<
'tcx
,
ty
::
ParamEnvAnd
<
'tcx
,
type_op
::
AscribeUserType
<
'tcx
>>>
{
fn
to_universe_info
(
self
,
_
base_universe
:
ty
::
UniverseIndex
)
->
UniverseInfo
<
'tcx
>
{
// Ascribe user type isn't usually called on types that have different
// bound regions.
UniverseInfo
::
other
()
}
}
impl
<
'tcx
,
F
,
G
>
ToUniverseInfo
<
'tcx
>
for
Canonical
<
'tcx
,
type_op
::
custom
::
CustomTypeOp
<
F
,
G
>>
{
fn
to_universe_info
(
self
,
_
base_universe
:
ty
::
UniverseIndex
)
->
UniverseInfo
<
'tcx
>
{
// We can't rerun custom type ops.
UniverseInfo
::
other
()
}
}
#[allow(unused_lifetimes)]
trait
TypeOpInfo
<
'tcx
>
{
// TODO: Methods for rerunning type op and reporting an error
}
struct
PredicateQuery
<
'tcx
>
{
_
canonical_query
:
Canonical
<
'tcx
,
ty
::
ParamEnvAnd
<
'tcx
,
type_op
::
prove_predicate
::
ProvePredicate
<
'tcx
>>>
,
_
base_universe
:
ty
::
UniverseIndex
,
}
impl
TypeOpInfo
<
'tcx
>
for
PredicateQuery
<
'tcx
>
{}
struct
NormalizeQuery
<
'tcx
,
T
>
{
_
canonical_query
:
Canonical
<
'tcx
,
ty
::
ParamEnvAnd
<
'tcx
,
type_op
::
Normalize
<
T
>>>
,
_
base_universe
:
ty
::
UniverseIndex
,
}
impl
<
T
>
TypeOpInfo
<
'tcx
>
for
NormalizeQuery
<
'tcx
,
T
>
where
T
:
Copy
+
fmt
::
Display
+
TypeFoldable
<
'tcx
>
+
'tcx
{
}
compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
浏览文件 @
5e6027c6
...
...
@@ -28,12 +28,14 @@
mod
region_name
;
mod
var_name
;
mod
bound_region_errors
;
mod
conflict_errors
;
mod
explain_borrow
;
mod
move_errors
;
mod
mutability_errors
;
mod
region_errors
;
crate
use
bound_region_errors
::{
ToUniverseInfo
,
UniverseInfo
};
crate
use
mutability_errors
::
AccessKind
;
crate
use
outlives_suggestion
::
OutlivesSuggestionBuilder
;
crate
use
region_errors
::{
ErrorConstraintInfo
,
RegionErrorKind
,
RegionErrors
};
...
...
compiler/rustc_mir/src/borrow_check/nll.rs
浏览文件 @
5e6027c6
...
...
@@ -239,6 +239,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
outlives_constraints
,
member_constraints
,
closure_bounds_mapping
,
universe_causes
,
type_tests
,
}
=
constraints
;
let
placeholder_indices
=
Rc
::
new
(
placeholder_indices
);
...
...
@@ -260,6 +261,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
outlives_constraints
,
member_constraints
,
closure_bounds_mapping
,
universe_causes
,
type_tests
,
liveness_constraints
,
elements
,
...
...
compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
浏览文件 @
5e6027c6
...
...
@@ -21,7 +21,7 @@
constraints
::{
graph
::
NormalConstraintGraph
,
ConstraintSccIndex
,
OutlivesConstraint
,
OutlivesConstraintSet
,
},
diagnostics
::{
RegionErrorKind
,
RegionErrors
},
diagnostics
::{
RegionErrorKind
,
RegionErrors
,
UniverseInfo
},
member_constraints
::{
MemberConstraintSet
,
NllMemberConstraintIndex
},
nll
::{
PoloniusOutput
,
ToRegionVid
},
region_infer
::
reverse_sccs
::
ReverseSccGraph
,
...
...
@@ -84,6 +84,9 @@ pub struct RegionInferenceContext<'tcx> {
closure_bounds_mapping
:
FxHashMap
<
Location
,
FxHashMap
<
(
RegionVid
,
RegionVid
),
(
ConstraintCategory
,
Span
)
>>
,
/// Map universe indexes to information on why we created it.
_u
niverse_causes
:
IndexVec
<
ty
::
UniverseIndex
,
UniverseInfo
<
'tcx
>>
,
/// Contains the minimum universe of any variable within the same
/// SCC. We will ensure that no SCC contains values that are not
/// visible from this index.
...
...
@@ -253,6 +256,7 @@ pub(in crate::borrow_check) fn new(
Location
,
FxHashMap
<
(
RegionVid
,
RegionVid
),
(
ConstraintCategory
,
Span
)
>
,
>
,
universe_causes
:
IndexVec
<
ty
::
UniverseIndex
,
UniverseInfo
<
'tcx
>>
,
type_tests
:
Vec
<
TypeTest
<
'tcx
>>
,
liveness_constraints
:
LivenessValues
<
RegionVid
>
,
elements
:
&
Rc
<
RegionValueElements
>
,
...
...
@@ -293,6 +297,7 @@ pub(in crate::borrow_check) fn new(
member_constraints
,
member_constraints_applied
:
Vec
::
new
(),
closure_bounds_mapping
,
_u
niverse_causes
:
universe_causes
,
scc_universes
,
scc_representatives
,
scc_values
,
...
...
compiler/rustc_mir/src/borrow_check/type_check/canonical.rs
0 → 100644
浏览文件 @
5e6027c6
use
std
::
fmt
;
use
rustc_hir
as
hir
;
use
rustc_infer
::
infer
::
canonical
::
Canonical
;
use
rustc_infer
::
traits
::
query
::
NoSolution
;
use
rustc_middle
::
mir
::
ConstraintCategory
;
use
rustc_middle
::
ty
::{
self
,
ToPredicate
,
TypeFoldable
};
use
rustc_span
::
Span
;
use
rustc_trait_selection
::
traits
::
query
::
type_op
::{
self
,
TypeOpOutput
};
use
rustc_trait_selection
::
traits
::
query
::
Fallible
;
use
crate
::
borrow_check
::
diagnostics
::{
ToUniverseInfo
,
UniverseInfo
};
use
super
::{
Locations
,
NormalizeLocation
,
TypeChecker
};
impl
<
'a
,
'tcx
>
TypeChecker
<
'a
,
'tcx
>
{
/// Given some operation `op` that manipulates types, proves
/// predicates, or otherwise uses the inference context, executes
/// `op` and then executes all the further obligations that `op`
/// returns. This will yield a set of outlives constraints amongst
/// regions which are extracted and stored as having occurred at
/// `locations`.
///
/// **Any `rustc_infer::infer` operations that might generate region
/// constraints should occur within this method so that those
/// constraints can be properly localized!**
pub
(
super
)
fn
fully_perform_op
<
R
,
Op
>
(
&
mut
self
,
locations
:
Locations
,
category
:
ConstraintCategory
,
op
:
Op
,
)
->
Fallible
<
R
>
where
Op
:
type_op
::
TypeOp
<
'tcx
,
Output
=
R
>
,
Canonical
<
'tcx
,
Op
>
:
ToUniverseInfo
<
'tcx
>
,
{
let
old_universe
=
self
.infcx
.universe
();
let
TypeOpOutput
{
output
,
constraints
,
canonicalized_query
}
=
op
.fully_perform
(
self
.infcx
)
?
;
if
let
Some
(
data
)
=
&
constraints
{
self
.push_region_constraints
(
locations
,
category
,
data
);
}
let
universe
=
self
.infcx
.universe
();
if
old_universe
!=
universe
{
let
universe_info
=
match
canonicalized_query
{
Some
(
canonicalized_query
)
=>
canonicalized_query
.to_universe_info
(
old_universe
),
None
=>
UniverseInfo
::
other
(),
};
for
u
in
old_universe
..
universe
{
let
info_universe
=
self
.borrowck_context.constraints.universe_causes
.push
(
universe_info
.clone
());
assert_eq!
(
u
.as_u32
()
+
1
,
info_universe
.as_u32
());
}
}
Ok
(
output
)
}
pub
(
super
)
fn
instantiate_canonical_with_fresh_inference_vars
<
T
>
(
&
mut
self
,
span
:
Span
,
canonical
:
&
Canonical
<
'tcx
,
T
>
,
)
->
T
where
T
:
TypeFoldable
<
'tcx
>
,
{
let
(
instantiated
,
_
)
=
self
.infcx
.instantiate_canonical_with_fresh_inference_vars
(
span
,
canonical
);
for
_
in
0
..
canonical
.max_universe
.as_u32
()
{
let
info
=
UniverseInfo
::
other
();
self
.borrowck_context.constraints.universe_causes
.push
(
info
);
}
instantiated
}
pub
(
super
)
fn
prove_trait_ref
(
&
mut
self
,
trait_ref
:
ty
::
TraitRef
<
'tcx
>
,
locations
:
Locations
,
category
:
ConstraintCategory
,
)
{
self
.prove_predicates
(
Some
(
ty
::
PredicateKind
::
Trait
(
ty
::
TraitPredicate
{
trait_ref
,
constness
:
hir
::
Constness
::
NotConst
,
})),
locations
,
category
,
);
}
pub
(
super
)
fn
normalize_and_prove_instantiated_predicates
(
&
mut
self
,
instantiated_predicates
:
ty
::
InstantiatedPredicates
<
'tcx
>
,
locations
:
Locations
,
)
{
for
predicate
in
instantiated_predicates
.predicates
{
let
predicate
=
self
.normalize
(
predicate
,
locations
);
self
.prove_predicate
(
predicate
,
locations
,
ConstraintCategory
::
Boring
);
}
}
pub
(
super
)
fn
prove_predicates
(
&
mut
self
,
predicates
:
impl
IntoIterator
<
Item
=
impl
ToPredicate
<
'tcx
>>
,
locations
:
Locations
,
category
:
ConstraintCategory
,
)
{
for
predicate
in
predicates
{
let
predicate
=
predicate
.to_predicate
(
self
.tcx
());
debug!
(
"prove_predicates(predicate={:?}, locations={:?})"
,
predicate
,
locations
,);
self
.prove_predicate
(
predicate
,
locations
,
category
);
}
}
pub
(
super
)
fn
prove_predicate
(
&
mut
self
,
predicate
:
ty
::
Predicate
<
'tcx
>
,
locations
:
Locations
,
category
:
ConstraintCategory
,
)
{
debug!
(
"prove_predicate(predicate={:?}, location={:?})"
,
predicate
,
locations
,);
let
param_env
=
self
.param_env
;
self
.fully_perform_op
(
locations
,
category
,
param_env
.and
(
type_op
::
prove_predicate
::
ProvePredicate
::
new
(
predicate
)),
)
.unwrap_or_else
(|
NoSolution
|
{
span_mirbug!
(
self
,
NoSolution
,
"could not prove {:?}"
,
predicate
);
})
}
pub
(
super
)
fn
normalize
<
T
>
(
&
mut
self
,
value
:
T
,
location
:
impl
NormalizeLocation
)
->
T
where
T
:
type_op
::
normalize
::
Normalizable
<
'tcx
>
+
fmt
::
Display
+
Copy
+
'tcx
,
{
debug!
(
"normalize(value={:?}, location={:?})"
,
value
,
location
);
let
param_env
=
self
.param_env
;
self
.fully_perform_op
(
location
.to_locations
(),
ConstraintCategory
::
Boring
,
param_env
.and
(
type_op
::
normalize
::
Normalize
::
new
(
value
)),
)
.unwrap_or_else
(|
NoSolution
|
{
span_mirbug!
(
self
,
NoSolution
,
"failed to normalize `{:?}`"
,
value
);
value
})
}
}
compiler/rustc_mir/src/borrow_check/type_check/input_output.rs
浏览文件 @
5e6027c6
...
...
@@ -44,7 +44,7 @@ pub(super) fn equate_inputs_and_outputs(
// Instantiate the canonicalized variables from
// user-provided signature (e.g., the `_` in the code
// above) with fresh variables.
let
(
poly_sig
,
_
)
=
self
.infcx
.instantiate_canonical_with_fresh_inference_vars
(
let
poly_sig
=
self
.instantiate_canonical_with_fresh_inference_vars
(
body
.span
,
&
user_provided_poly_sig
,
);
...
...
compiler/rustc_mir/src/borrow_check/type_check/mod.rs
浏览文件 @
5e6027c6
...
...
@@ -38,9 +38,8 @@
use
rustc_trait_selection
::
traits
::
error_reporting
::
InferCtxtExt
as
_
;
use
rustc_trait_selection
::
traits
::
query
::
type_op
;
use
rustc_trait_selection
::
traits
::
query
::
type_op
::
custom
::
CustomTypeOp
;
use
rustc_trait_selection
::
traits
::
query
::
{
Fallible
,
NoSolution
}
;
use
rustc_trait_selection
::
traits
::
query
::
Fallible
;
use
rustc_trait_selection
::
traits
::{
self
,
ObligationCause
,
PredicateObligations
};
use
type_op
::
TypeOpOutput
;
use
crate
::
dataflow
::
impls
::
MaybeInitializedPlaces
;
use
crate
::
dataflow
::
move_paths
::
MoveData
;
...
...
@@ -52,6 +51,7 @@
use
crate
::
borrow_check
::{
borrow_set
::
BorrowSet
,
constraints
::{
OutlivesConstraint
,
OutlivesConstraintSet
},
diagnostics
::
UniverseInfo
,
facts
::
AllFacts
,
location
::
LocationTable
,
member_constraints
::
MemberConstraintSet
,
...
...
@@ -90,6 +90,7 @@
})
}
mod
canonical
;
mod
constraint_conversion
;
pub
mod
free_region_relations
;
mod
input_output
;
...
...
@@ -143,6 +144,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
member_constraints
:
MemberConstraintSet
::
default
(),
closure_bounds_mapping
:
Default
::
default
(),
type_tests
:
Vec
::
default
(),
universe_causes
:
IndexVec
::
from_elem_n
(
UniverseInfo
::
other
(),
1
),
};
let
CreateResult
{
...
...
@@ -157,6 +159,11 @@ pub(crate) fn type_check<'mir, 'tcx>(
&
mut
constraints
,
);
for
_
in
ty
::
UniverseIndex
::
ROOT
..
infcx
.universe
()
{
let
info
=
UniverseInfo
::
other
();
constraints
.universe_causes
.push
(
info
);
}
let
mut
borrowck_context
=
BorrowCheckContext
{
universal_regions
,
location_table
,
...
...
@@ -377,8 +384,8 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
ty
,
san_ty
|
{
if
let
Err
(
terr
)
=
verifier
.cx
.eq_types
(
san_ty
,
ty
,
san_ty
,
location
.to_locations
(),
ConstraintCategory
::
Boring
,
)
{
...
...
@@ -426,8 +433,8 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
let
literal_ty
=
constant
.literal
.ty
()
.builtin_deref
(
true
)
.unwrap
()
.ty
;
if
let
Err
(
terr
)
=
self
.cx
.eq_types
(
normalized_ty
,
literal_ty
,
normalized_ty
,
locations
,
ConstraintCategory
::
Boring
,
)
{
...
...
@@ -543,7 +550,7 @@ fn sanitize_place(
return
PlaceTy
::
from_ty
(
self
.tcx
()
.ty_error
());
}
}
place_ty
=
self
.sanitize_projection
(
place_ty
,
elem
,
place
,
location
)
place_ty
=
self
.sanitize_projection
(
place_ty
,
elem
,
place
,
location
)
;
}
if
let
PlaceContext
::
NonMutatingUse
(
NonMutatingUseContext
::
Copy
)
=
context
{
...
...
@@ -917,6 +924,8 @@ struct BorrowCheckContext<'a, 'tcx> {
crate
closure_bounds_mapping
:
FxHashMap
<
Location
,
FxHashMap
<
(
RegionVid
,
RegionVid
),
(
ConstraintCategory
,
Span
)
>>
,
crate
universe_causes
:
IndexVec
<
ty
::
UniverseIndex
,
UniverseInfo
<
'tcx
>>
,
crate
type_tests
:
Vec
<
TypeTest
<
'tcx
>>
,
}
...
...
@@ -1044,8 +1053,7 @@ fn check_user_type_annotations(&mut self) {
);
for
user_annotation
in
self
.user_type_annotations
{
let
CanonicalUserTypeAnnotation
{
span
,
ref
user_ty
,
inferred_ty
}
=
*
user_annotation
;
let
(
annotation
,
_
)
=
self
.infcx
.instantiate_canonical_with_fresh_inference_vars
(
span
,
user_ty
);
let
annotation
=
self
.instantiate_canonical_with_fresh_inference_vars
(
span
,
user_ty
);
match
annotation
{
UserType
::
Ty
(
mut
ty
)
=>
{
ty
=
self
.normalize
(
ty
,
Locations
::
All
(
span
));
...
...
@@ -1098,31 +1106,6 @@ fn check_user_type_annotations(&mut self) {
}
}
/// Given some operation `op` that manipulates types, proves
/// predicates, or otherwise uses the inference context, executes
/// `op` and then executes all the further obligations that `op`
/// returns. This will yield a set of outlives constraints amongst
/// regions which are extracted and stored as having occurred at
/// `locations`.
///
/// **Any `rustc_infer::infer` operations that might generate region
/// constraints should occur within this method so that those
/// constraints can be properly localized!**
fn
fully_perform_op
<
R
>
(
&
mut
self
,
locations
:
Locations
,
category
:
ConstraintCategory
,
op
:
impl
type_op
::
TypeOp
<
'tcx
,
Output
=
R
>
,
)
->
Fallible
<
R
>
{
let
TypeOpOutput
{
output
,
constraints
,
..
}
=
op
.fully_perform
(
self
.infcx
)
?
;
if
let
Some
(
data
)
=
&
constraints
{
self
.push_region_constraints
(
locations
,
category
,
data
);
}
Ok
(
output
)
}
fn
push_region_constraints
(
&
mut
self
,
locations
:
Locations
,
...
...
@@ -1174,17 +1157,19 @@ fn sub_types(
locations
:
Locations
,
category
:
ConstraintCategory
,
)
->
Fallible
<
()
>
{
self
.relate_types
(
sub
,
ty
::
Variance
::
Covariant
,
sup
,
locations
,
category
)
// Use this order of parameters because the sup type is usually the
// "expected" type in diagnostics.
self
.relate_types
(
sup
,
ty
::
Variance
::
Contravariant
,
sub
,
locations
,
category
)
}
fn
eq_types
(
&
mut
self
,
a
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
,
expected
:
Ty
<
'tcx
>
,
found
:
Ty
<
'tcx
>
,
locations
:
Locations
,
category
:
ConstraintCategory
,
)
->
Fallible
<
()
>
{
self
.relate_types
(
a
,
ty
::
Variance
::
Invariant
,
b
,
locations
,
category
)
self
.relate_types
(
expected
,
ty
::
Variance
::
Invariant
,
found
,
locations
,
category
)
}
fn
relate_type_and_user_type
(
...
...
@@ -1223,7 +1208,7 @@ fn relate_type_and_user_type(
);
let
ty
=
curr_projected_ty
.ty
;
self
.relate_types
(
a
,
v
,
ty
,
locations
,
category
)
?
;
self
.relate_types
(
ty
,
v
.xform
(
ty
::
Variance
::
Contravariant
),
a
,
locations
,
category
)
?
;
Ok
(())
}
...
...
@@ -2054,8 +2039,8 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
let
ty_fn_ptr_from
=
tcx
.mk_fn_ptr
(
fn_sig
);
if
let
Err
(
terr
)
=
self
.eq_types
(
ty_fn_ptr_from
,
ty
,
ty_fn_ptr_from
,
location
.to_locations
(),
ConstraintCategory
::
Cast
,
)
{
...
...
@@ -2078,8 +2063,8 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
let
ty_fn_ptr_from
=
tcx
.mk_fn_ptr
(
tcx
.signature_unclosure
(
sig
,
*
unsafety
));
if
let
Err
(
terr
)
=
self
.eq_types
(
ty_fn_ptr_from
,
ty
,
ty_fn_ptr_from
,
location
.to_locations
(),
ConstraintCategory
::
Cast
,
)
{
...
...
@@ -2107,8 +2092,8 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
let
ty_fn_ptr_from
=
tcx
.safe_to_unsafe_fn_ty
(
fn_sig
);
if
let
Err
(
terr
)
=
self
.eq_types
(
ty_fn_ptr_from
,
ty
,
ty_fn_ptr_from
,
location
.to_locations
(),
ConstraintCategory
::
Cast
,
)
{
...
...
@@ -2295,20 +2280,18 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L
kind
:
TypeVariableOriginKind
::
MiscVariable
,
span
:
body
.source_info
(
location
)
.span
,
});
self
.relate_types
(
common_ty
,
ty
::
Variance
::
Contravariant
,
self
.sub_types
(
ty_left
,
common_ty
,
location
.to_locations
(),
ConstraintCategory
::
Boring
,
)
.unwrap_or_else
(|
err
|
{
bug!
(
"Could not equate type variable with {:?}: {:?}"
,
ty_left
,
err
)
});
if
let
Err
(
terr
)
=
self
.relate_types
(
common_ty
,
ty
::
Variance
::
Contravariant
,
if
let
Err
(
terr
)
=
self
.sub_types
(
ty_right
,
common_ty
,
location
.to_locations
(),
ConstraintCategory
::
Boring
,
)
{
...
...
@@ -2683,66 +2666,6 @@ fn prove_closure_bounds(
tcx
.predicates_of
(
def_id
)
.instantiate
(
tcx
,
substs
)
}
fn
prove_trait_ref
(
&
mut
self
,
trait_ref
:
ty
::
TraitRef
<
'tcx
>
,
locations
:
Locations
,
category
:
ConstraintCategory
,
)
{
self
.prove_predicates
(
Some
(
ty
::
PredicateKind
::
Trait
(
ty
::
TraitPredicate
{
trait_ref
,
constness
:
hir
::
Constness
::
NotConst
,
})),
locations
,
category
,
);
}
fn
normalize_and_prove_instantiated_predicates
(
&
mut
self
,
instantiated_predicates
:
ty
::
InstantiatedPredicates
<
'tcx
>
,
locations
:
Locations
,
)
{
for
predicate
in
instantiated_predicates
.predicates
{
let
predicate
=
self
.normalize
(
predicate
,
locations
);
self
.prove_predicate
(
predicate
,
locations
,
ConstraintCategory
::
Boring
);
}
}
fn
prove_predicates
(
&
mut
self
,
predicates
:
impl
IntoIterator
<
Item
=
impl
ToPredicate
<
'tcx
>>
,
locations
:
Locations
,
category
:
ConstraintCategory
,
)
{
for
predicate
in
predicates
{
let
predicate
=
predicate
.to_predicate
(
self
.tcx
());
debug!
(
"prove_predicates(predicate={:?}, locations={:?})"
,
predicate
,
locations
,);
self
.prove_predicate
(
predicate
,
locations
,
category
);
}
}
fn
prove_predicate
(
&
mut
self
,
predicate
:
ty
::
Predicate
<
'tcx
>
,
locations
:
Locations
,
category
:
ConstraintCategory
,
)
{
debug!
(
"prove_predicate(predicate={:?}, location={:?})"
,
predicate
,
locations
,);
let
param_env
=
self
.param_env
;
self
.fully_perform_op
(
locations
,
category
,
param_env
.and
(
type_op
::
prove_predicate
::
ProvePredicate
::
new
(
predicate
)),
)
.unwrap_or_else
(|
NoSolution
|
{
span_mirbug!
(
self
,
NoSolution
,
"could not prove {:?}"
,
predicate
);
})
}
fn
typeck_mir
(
&
mut
self
,
body
:
&
Body
<
'tcx
>
)
{
self
.last_span
=
body
.span
;
debug!
(
"run_on_mir: {:?}"
,
body
.span
);
...
...
@@ -2765,23 +2688,6 @@ fn typeck_mir(&mut self, body: &Body<'tcx>) {
self
.check_iscleanup
(
&
body
,
block_data
);
}
}
fn
normalize
<
T
>
(
&
mut
self
,
value
:
T
,
location
:
impl
NormalizeLocation
)
->
T
where
T
:
type_op
::
normalize
::
Normalizable
<
'tcx
>
+
Copy
+
'tcx
,
{
debug!
(
"normalize(value={:?}, location={:?})"
,
value
,
location
);
let
param_env
=
self
.param_env
;
self
.fully_perform_op
(
location
.to_locations
(),
ConstraintCategory
::
Boring
,
param_env
.and
(
type_op
::
normalize
::
Normalize
::
new
(
value
)),
)
.unwrap_or_else
(|
NoSolution
|
{
span_mirbug!
(
self
,
NoSolution
,
"failed to normalize `{:?}`"
,
value
);
value
})
}
}
trait
NormalizeLocation
:
fmt
::
Debug
+
Copy
{
...
...
compiler/rustc_mir/src/borrow_check/type_check/relate_tys.rs
浏览文件 @
5e6027c6
...
...
@@ -6,6 +6,7 @@
use
rustc_trait_selection
::
traits
::
query
::
Fallible
;
use
crate
::
borrow_check
::
constraints
::
OutlivesConstraint
;
use
crate
::
borrow_check
::
diagnostics
::
UniverseInfo
;
use
crate
::
borrow_check
::
type_check
::{
BorrowCheckContext
,
Locations
};
/// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`:
...
...
@@ -29,7 +30,14 @@ pub(super) fn relate_types<'tcx>(
debug!
(
"relate_types(a={:?}, v={:?}, b={:?}, locations={:?})"
,
a
,
v
,
b
,
locations
);
TypeRelating
::
new
(
infcx
,
NllTypeRelatingDelegate
::
new
(
infcx
,
borrowck_context
,
param_env
,
locations
,
category
),
NllTypeRelatingDelegate
::
new
(
infcx
,
borrowck_context
,
param_env
,
locations
,
category
,
UniverseInfo
::
relate
(
a
,
b
),
),
v
,
)
.relate
(
a
,
b
)
?
;
...
...
@@ -47,6 +55,10 @@ struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
/// What category do we assign the resulting `'a: 'b` relationships?
category
:
ConstraintCategory
,
/// Information so that error reporting knows what types we are relating
/// when reporting a bound region error.
universe_info
:
UniverseInfo
<
'tcx
>
,
}
impl
NllTypeRelatingDelegate
<
'me
,
'bccx
,
'tcx
>
{
...
...
@@ -56,8 +68,9 @@ fn new(
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
locations
:
Locations
,
category
:
ConstraintCategory
,
universe_info
:
UniverseInfo
<
'tcx
>
,
)
->
Self
{
Self
{
infcx
,
borrowck_context
,
param_env
,
locations
,
category
}
Self
{
infcx
,
borrowck_context
,
param_env
,
locations
,
category
,
universe_info
}
}
}
...
...
@@ -67,7 +80,11 @@ fn param_env(&self) -> ty::ParamEnv<'tcx> {
}
fn
create_next_universe
(
&
mut
self
)
->
ty
::
UniverseIndex
{
self
.infcx
.create_next_universe
()
let
info_universe
=
self
.borrowck_context.constraints.universe_causes
.push
(
self
.universe_info
.clone
());
let
universe
=
self
.infcx
.create_next_universe
();
assert_eq!
(
info_universe
,
universe
);
universe
}
fn
next_existential_region_var
(
&
mut
self
,
from_forall
:
bool
)
->
ty
::
Region
<
'tcx
>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录