Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a0d2d9f3
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,发现更多精彩内容 >>
提交
a0d2d9f3
编写于
6月 29, 2022
作者:
L
lcnr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implied bounds byebye nested hir ids
上级
e78e0e2a
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
28 addition
and
129 deletion
+28
-129
compiler/rustc_infer/src/infer/outlives/env.rs
compiler/rustc_infer/src/infer/outlives/env.rs
+10
-78
compiler/rustc_infer/src/infer/outlives/obligations.rs
compiler/rustc_infer/src/infer/outlives/obligations.rs
+10
-19
compiler/rustc_trait_selection/src/traits/auto_trait.rs
compiler/rustc_trait_selection/src/traits/auto_trait.rs
+1
-9
compiler/rustc_trait_selection/src/traits/coherence.rs
compiler/rustc_trait_selection/src/traits/coherence.rs
+3
-12
compiler/rustc_typeck/src/check/check.rs
compiler/rustc_typeck/src/check/check.rs
+1
-2
compiler/rustc_typeck/src/check/compare_method.rs
compiler/rustc_typeck/src/check/compare_method.rs
+2
-6
compiler/rustc_typeck/src/check/wfcheck.rs
compiler/rustc_typeck/src/check/wfcheck.rs
+1
-3
未找到文件。
compiler/rustc_infer/src/infer/outlives/env.rs
浏览文件 @
a0d2d9f3
use
crate
::
infer
::
free_regions
::
FreeRegionMap
;
use
crate
::
infer
::{
GenericKind
,
InferCtxt
};
use
crate
::
traits
::
query
::
OutlivesBound
;
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_hir
as
hir
;
use
rustc_middle
::
ty
::{
self
,
ReEarlyBound
,
ReFree
,
ReVar
,
Region
};
use
super
::
explicit_outlives_bounds
;
...
...
@@ -31,9 +29,7 @@ pub struct OutlivesEnvironment<'tcx> {
pub
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
free_region_map
:
FreeRegionMap
<
'tcx
>
,
// Contains, for each body B that we are checking (that is, the fn
// item, but also any nested closures), the set of implied region
// bounds that are in scope in that particular body.
// Contains the implied region bounds in scope for our current body.
//
// Example:
//
...
...
@@ -43,24 +39,15 @@ pub struct OutlivesEnvironment<'tcx> {
// } // body B0
// ```
//
// Here,
for
body B0, the list would be `[T: 'a]`, because we
// Here,
when checking the
body B0, the list would be `[T: 'a]`, because we
// infer that `T` must outlive `'a` from the implied bounds on the
// fn declaration.
//
// For the body B1, the list would be `[T: 'a, T: 'b]`, because we
// For the body B1
however
, the list would be `[T: 'a, T: 'b]`, because we
// also can see that -- within the closure body! -- `T` must
// outlive `'b`. This is not necessarily true outside the closure
// body, since the closure may never be called.
//
// We collect this map as we descend the tree. We then use the
// results when proving outlives obligations like `T: 'x` later
// (e.g., if `T: 'x` must be proven within the body B1, then we
// know it is true if either `'a: 'x` or `'b: 'x`).
region_bound_pairs_map
:
FxHashMap
<
hir
::
HirId
,
RegionBoundPairs
<
'tcx
>>
,
// Used to compute `region_bound_pairs_map`: contains the set of
// in-scope region-bound pairs thus far.
region_bound_pairs_accum
:
RegionBoundPairs
<
'tcx
>
,
region_bound_pairs
:
RegionBoundPairs
<
'tcx
>
,
}
/// "Region-bound pairs" tracks outlives relations that are known to
...
...
@@ -73,8 +60,7 @@ pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
let
mut
env
=
OutlivesEnvironment
{
param_env
,
free_region_map
:
Default
::
default
(),
region_bound_pairs_map
:
Default
::
default
(),
region_bound_pairs_accum
:
vec!
[],
region_bound_pairs
:
Default
::
default
(),
};
env
.add_outlives_bounds
(
None
,
explicit_outlives_bounds
(
param_env
));
...
...
@@ -87,62 +73,9 @@ pub fn free_region_map(&self) -> &FreeRegionMap<'tcx> {
&
self
.free_region_map
}
/// Borrows current value of the `region_bound_pairs`.
pub
fn
region_bound_pairs_map
(
&
self
)
->
&
FxHashMap
<
hir
::
HirId
,
RegionBoundPairs
<
'tcx
>>
{
&
self
.region_bound_pairs_map
}
/// This is a hack to support the old-school regionck, which
/// processes region constraints from the main function and the
/// closure together. In that context, when we enter a closure, we
/// want to be able to "save" the state of the surrounding a
/// function. We can then add implied bounds and the like from the
/// closure arguments into the environment -- these should only
/// apply in the closure body, so once we exit, we invoke
/// `pop_snapshot_post_typeck_child` to remove them.
///
/// Example:
///
/// ```ignore (pseudo-rust)
/// fn foo<T>() {
/// callback(for<'a> |x: &'a T| {
/// // ^^^^^^^ not legal syntax, but probably should be
/// // within this closure body, `T: 'a` holds
/// })
/// }
/// ```
///
/// This "containment" of closure's effects only works so well. In
/// particular, we (intentionally) leak relationships between free
/// regions that are created by the closure's bounds. The case
/// where this is useful is when you have (e.g.) a closure with a
/// signature like `for<'a, 'b> fn(x: &'a &'b u32)` -- in this
/// case, we want to keep the relationship `'b: 'a` in the
/// free-region-map, so that later if we have to take `LUB('b,
/// 'a)` we can get the result `'b`.
///
/// I have opted to keep **all modifications** to the
/// free-region-map, however, and not just those that concern free
/// variables bound in the closure. The latter seems more correct,
/// but it is not the existing behavior, and I could not find a
/// case where the existing behavior went wrong. In any case, it
/// seems like it'd be readily fixed if we wanted. There are
/// similar leaks around givens that seem equally suspicious, to
/// be honest. --nmatsakis
pub
fn
push_snapshot_pre_typeck_child
(
&
self
)
->
usize
{
self
.region_bound_pairs_accum
.len
()
}
/// See `push_snapshot_pre_typeck_child`.
pub
fn
pop_snapshot_post_typeck_child
(
&
mut
self
,
len
:
usize
)
{
self
.region_bound_pairs_accum
.truncate
(
len
);
}
/// Save the current set of region-bound pairs under the given `body_id`.
pub
fn
save_implied_bounds
(
&
mut
self
,
body_id
:
hir
::
HirId
)
{
let
old
=
self
.region_bound_pairs_map
.insert
(
body_id
,
self
.region_bound_pairs_accum
.clone
());
assert
!
(
old
.is_none
());
/// Borrows current `region_bound_pairs`.
pub
fn
region_bound_pairs
(
&
self
)
->
&
RegionBoundPairs
<
'tcx
>
{
&
self
.region_bound_pairs
}
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
...
...
@@ -164,11 +97,10 @@ pub fn add_outlives_bounds<I>(
debug!
(
"add_outlives_bounds: outlives_bound={:?}"
,
outlives_bound
);
match
outlives_bound
{
OutlivesBound
::
RegionSubParam
(
r_a
,
param_b
)
=>
{
self
.region_bound_pairs
_accum
.push
((
r_a
,
GenericKind
::
Param
(
param_b
)));
self
.region_bound_pairs
.push
((
r_a
,
GenericKind
::
Param
(
param_b
)));
}
OutlivesBound
::
RegionSubProjection
(
r_a
,
projection_b
)
=>
{
self
.region_bound_pairs_accum
.push
((
r_a
,
GenericKind
::
Projection
(
projection_b
)));
self
.region_bound_pairs
.push
((
r_a
,
GenericKind
::
Projection
(
projection_b
)));
}
OutlivesBound
::
RegionSubRegion
(
r_a
,
r_b
)
=>
{
if
let
(
ReEarlyBound
(
_
)
|
ReFree
(
_
),
ReVar
(
vid_b
))
=
(
r_a
.kind
(),
r_b
.kind
())
{
...
...
compiler/rustc_infer/src/infer/outlives/obligations.rs
浏览文件 @
a0d2d9f3
...
...
@@ -60,19 +60,17 @@
//! imply that `'b: 'a`.
use
crate
::
infer
::
outlives
::
components
::{
push_outlives_components
,
Component
};
use
crate
::
infer
::
outlives
::
env
::
OutlivesEnvironment
;
use
crate
::
infer
::
outlives
::
env
::
RegionBoundPairs
;
use
crate
::
infer
::
outlives
::
verify
::
VerifyBoundCx
;
use
crate
::
infer
::{
self
,
GenericKind
,
InferCtxt
,
RegionObligation
,
SubregionOrigin
,
UndoLog
,
VerifyBound
,
};
use
crate
::
traits
::{
ObligationCause
,
ObligationCauseCode
};
use
rustc_middle
::
ty
::
subst
::
GenericArgKind
;
use
rustc_middle
::
ty
::{
self
,
Region
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
crate
::
infer
::
outlives
::
env
::
OutlivesEnvironment
;
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_data_structures
::
undo_log
::
UndoLogs
;
use
rustc_hir
as
hir
;
use
rustc_middle
::
ty
::
subst
::
GenericArgKind
;
use
rustc_middle
::
ty
::{
self
,
Region
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
smallvec
::
smallvec
;
impl
<
'cx
,
'tcx
>
InferCtxt
<
'cx
,
'tcx
>
{
...
...
@@ -145,10 +143,10 @@ pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionOblig
/// - `param_env` is the parameter environment for the enclosing function.
/// - `body_id` is the body-id whose region obligations are being
/// processed.
#[instrument(level
=
"debug"
,
skip(self,
region_bound_pairs
_map
))]
#[instrument(level
=
"debug"
,
skip(self,
region_bound_pairs))]
pub
fn
process_registered_region_obligations
(
&
self
,
region_bound_pairs
_map
:
&
FxHashMap
<
hir
::
HirId
,
RegionBoundPairs
<
'tcx
>
>
,
region_bound_pairs
:
&
RegionBoundPairs
<
'tcx
>
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
)
{
assert
!
(
...
...
@@ -158,7 +156,7 @@ pub fn process_registered_region_obligations(
let
my_region_obligations
=
self
.take_registered_region_obligations
();
for
(
body_id
,
RegionObligation
{
sup_type
,
sub_region
,
origin
})
in
my_region_obligations
{
for
(
_
body_id
,
RegionObligation
{
sup_type
,
sub_region
,
origin
})
in
my_region_obligations
{
debug!
(
"process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}"
,
sup_type
,
sub_region
,
origin
...
...
@@ -166,16 +164,9 @@ pub fn process_registered_region_obligations(
let
sup_type
=
self
.resolve_vars_if_possible
(
sup_type
);
if
let
Some
(
region_bound_pairs
)
=
region_bound_pairs_map
.get
(
&
body_id
)
{
let
outlives
=
&
mut
TypeOutlives
::
new
(
self
,
self
.tcx
,
&
region_bound_pairs
,
None
,
param_env
);
outlives
.type_must_outlive
(
origin
,
sup_type
,
sub_region
);
}
else
{
self
.tcx.sess
.delay_span_bug
(
origin
.span
(),
&
format!
(
"no region-bound-pairs for {:?}"
,
body_id
),
);
}
let
outlives
=
&
mut
TypeOutlives
::
new
(
self
,
self
.tcx
,
&
region_bound_pairs
,
None
,
param_env
);
outlives
.type_must_outlive
(
origin
,
sup_type
,
sub_region
);
}
}
...
...
@@ -184,7 +175,7 @@ pub fn check_region_obligations_and_report_errors(
outlives_env
:
&
OutlivesEnvironment
<
'tcx
>
,
)
{
self
.process_registered_region_obligations
(
outlives_env
.region_bound_pairs
_map
(),
outlives_env
.region_bound_pairs
(),
outlives_env
.param_env
,
);
...
...
compiler/rustc_trait_selection/src/traits/auto_trait.rs
浏览文件 @
a0d2d9f3
...
...
@@ -212,15 +212,7 @@ pub fn find_auto_trait_generics<A>(
panic!
(
"Unable to fulfill trait {:?} for '{:?}': {:?}"
,
trait_did
,
ty
,
errors
);
}
let
body_id_map
:
FxHashMap
<
_
,
_
>
=
infcx
.inner
.borrow
()
.region_obligations
()
.iter
()
.map
(|
&
(
id
,
_
)|
(
id
,
vec!
[]))
.collect
();
infcx
.process_registered_region_obligations
(
&
body_id_map
,
full_env
);
infcx
.process_registered_region_obligations
(
&
Default
::
default
(),
full_env
);
let
region_data
=
infcx
.inner
...
...
compiler/rustc_trait_selection/src/traits/coherence.rs
浏览文件 @
a0d2d9f3
...
...
@@ -16,7 +16,6 @@
//use rustc_data_structures::fx::FxHashMap;
use
rustc_errors
::
Diagnostic
;
use
rustc_hir
::
def_id
::{
DefId
,
LOCAL_CRATE
};
use
rustc_hir
::
CRATE_HIR_ID
;
use
rustc_infer
::
infer
::{
InferCtxt
,
TyCtxtInferExt
};
use
rustc_infer
::
traits
::{
util
,
TraitEngine
};
use
rustc_middle
::
traits
::
specialization_graph
::
OverlapMode
;
...
...
@@ -394,17 +393,9 @@ fn resolve_negative_obligation<'cx, 'tcx>(
return
false
;
}
let
mut
outlives_env
=
OutlivesEnvironment
::
new
(
param_env
);
// FIXME -- add "assumed to be well formed" types into the `outlives_env`
// "Save" the accumulated implied bounds into the outlives environment
// (due to the FIXME above, there aren't any, but this step is still needed).
// The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used
// by the "dummy" causes elsewhere (body-id is only relevant when checking
// function bodies with closures).
outlives_env
.save_implied_bounds
(
CRATE_HIR_ID
);
infcx
.process_registered_region_obligations
(
outlives_env
.region_bound_pairs_map
(),
param_env
);
// FIXME -- also add "assumed to be well formed" types into the `outlives_env`
let
outlives_env
=
OutlivesEnvironment
::
new
(
param_env
);
infcx
.process_registered_region_obligations
(
outlives_env
.region_bound_pairs
(),
param_env
);
let
errors
=
infcx
.resolve_regions
(
&
outlives_env
);
...
...
compiler/rustc_typeck/src/check/check.rs
浏览文件 @
a0d2d9f3
...
...
@@ -737,8 +737,7 @@ fn check_opaque_meets_bounds<'tcx>(
hir
::
OpaqueTyOrigin
::
FnReturn
(
..
)
|
hir
::
OpaqueTyOrigin
::
AsyncFn
(
..
)
=>
{}
// Can have different predicates to their defining use
hir
::
OpaqueTyOrigin
::
TyAlias
=>
{
let
mut
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
outlives_environment
.save_implied_bounds
(
hir_id
);
let
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
infcx
.check_region_obligations_and_report_errors
(
&
outlives_environment
);
}
}
...
...
compiler/rustc_typeck/src/check/compare_method.rs
浏览文件 @
a0d2d9f3
...
...
@@ -403,7 +403,6 @@ fn compare_predicate_entailment<'tcx>(
// lifetime parameters.
let
mut
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
outlives_environment
.add_implied_bounds
(
infcx
,
wf_tys
,
impl_m_hir_id
);
outlives_environment
.save_implied_bounds
(
impl_m_hir_id
);
infcx
.check_region_obligations_and_report_errors
(
&
outlives_environment
);
Ok
(())
...
...
@@ -1159,8 +1158,7 @@ pub(crate) fn compare_const_impl<'tcx>(
return
;
}
let
mut
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
outlives_environment
.save_implied_bounds
(
impl_c_hir_id
);
let
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
infcx
.resolve_regions_and_report_errors
(
&
outlives_environment
);
});
}
...
...
@@ -1279,8 +1277,7 @@ fn compare_type_predicate_entailment<'tcx>(
// Finally, resolve all regions. This catches wily misuses of
// lifetime parameters.
let
mut
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
outlives_environment
.save_implied_bounds
(
impl_ty_hir_id
);
let
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
infcx
.check_region_obligations_and_report_errors
(
&
outlives_environment
);
Ok
(())
...
...
@@ -1514,7 +1511,6 @@ pub fn check_type_bounds<'tcx>(
};
let
mut
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
outlives_environment
.add_implied_bounds
(
infcx
,
implied_bounds
,
impl_ty_hir_id
);
outlives_environment
.save_implied_bounds
(
impl_ty_hir_id
);
infcx
.check_region_obligations_and_report_errors
(
&
outlives_environment
);
Ok
(())
...
...
compiler/rustc_typeck/src/check/wfcheck.rs
浏览文件 @
a0d2d9f3
...
...
@@ -65,7 +65,6 @@ pub(super) fn with_fcx<F>(&mut self, f: F)
let
mut
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
outlives_environment
.add_implied_bounds
(
&
fcx
.infcx
,
wf_tys
,
id
);
outlives_environment
.save_implied_bounds
(
id
);
fcx
.infcx
.check_region_obligations_and_report_errors
(
&
outlives_environment
);
});
}
...
...
@@ -660,8 +659,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
tcx
.infer_ctxt
()
.enter
(|
infcx
|
{
let
mut
outlives_environment
=
OutlivesEnvironment
::
new
(
param_env
);
outlives_environment
.add_implied_bounds
(
&
infcx
,
wf_tys
.clone
(),
id
);
outlives_environment
.save_implied_bounds
(
id
);
let
region_bound_pairs
=
outlives_environment
.region_bound_pairs_map
()
.get
(
&
id
)
.unwrap
();
let
region_bound_pairs
=
outlives_environment
.region_bound_pairs
();
add_constraints
(
&
infcx
,
region_bound_pairs
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录