Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
62df9732
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,发现更多精彩内容 >>
提交
62df9732
编写于
10月 10, 2018
作者:
S
scalexm
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use `Environment` instead of `ty::ParamEnv` in chalk context
上级
cbbd70d4
变更
11
显示空白变更内容
内联
并排
Showing
11 changed file
with
271 addition
and
103 deletion
+271
-103
src/librustc/dep_graph/dep_node.rs
src/librustc/dep_graph/dep_node.rs
+3
-1
src/librustc/ich/impls_ty.rs
src/librustc/ich/impls_ty.rs
+8
-0
src/librustc/traits/mod.rs
src/librustc/traits/mod.rs
+30
-0
src/librustc/traits/structural_impls.rs
src/librustc/traits/structural_impls.rs
+37
-1
src/librustc/ty/query/config.rs
src/librustc/ty/query/config.rs
+9
-2
src/librustc/ty/query/keys.rs
src/librustc/ty/query/keys.rs
+10
-0
src/librustc/ty/query/mod.rs
src/librustc/ty/query/mod.rs
+3
-1
src/librustc/ty/query/plumbing.rs
src/librustc/ty/query/plumbing.rs
+1
-0
src/librustc_traits/chalk_context.rs
src/librustc_traits/chalk_context.rs
+38
-33
src/librustc_traits/lowering/environment.rs
src/librustc_traits/lowering/environment.rs
+127
-0
src/librustc_traits/lowering/mod.rs
src/librustc_traits/lowering/mod.rs
+5
-65
未找到文件。
src/librustc/dep_graph/dep_node.rs
浏览文件 @
62df9732
...
...
@@ -70,6 +70,7 @@
use
std
::
fmt
;
use
std
::
hash
::
Hash
;
use
syntax_pos
::
symbol
::
InternedString
;
use
traits
;
use
traits
::
query
::{
CanonicalProjectionGoal
,
CanonicalTyGoal
,
CanonicalTypeOpEqGoal
,
CanonicalTypeOpSubtypeGoal
,
CanonicalPredicateGoal
,
CanonicalTypeOpProvePredicateGoal
,
CanonicalTypeOpNormalizeGoal
,
...
...
@@ -550,6 +551,7 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
[
anon
]
TraitSelect
,
[]
ParamEnv
(
DefId
),
[]
Environment
(
DefId
),
[]
DescribeDef
(
DefId
),
// FIXME(mw): DefSpans are not really inputs since they are derived from
...
...
@@ -669,7 +671,7 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
[
input
]
Features
,
[]
ProgramClausesFor
(
DefId
),
[]
ProgramClausesForEnv
(
ParamEnv
<
'tcx
>
),
[]
ProgramClausesForEnv
(
traits
::
Environment
<
'tcx
>
),
[]
WasmImportModuleMap
(
CrateNum
),
[]
ForeignModules
(
CrateNum
),
...
...
src/librustc/ich/impls_ty.rs
浏览文件 @
62df9732
...
...
@@ -1418,7 +1418,15 @@ fn hash_stable<W: StableHasherResult>(&self,
Existential
});
<<<<<<<
HEAD
impl_stable_hash_for!
(
struct
ty
::
subst
::
UserSubsts
<
'tcx
>
{
substs
,
user_self_ty
});
impl_stable_hash_for!
(
struct
ty
::
subst
::
UserSelfTy
<
'tcx
>
{
impl_def_id
,
self_ty
});
=======
impl_stable_hash_for!
(
impl
<
'tcx
>
for
struct
traits
::
Environment
<
'tcx
>
{
clauses
,
}
);
>>>>>>>
Use
`
Environment
`
instead
of
`
ty
::
ParamEnv
`
in
chalk
context
src/librustc/traits/mod.rs
浏览文件 @
62df9732
...
...
@@ -278,6 +278,8 @@ pub struct DerivedObligationCause<'tcx> {
/// * `DomainGoal`
/// * `Goal`
/// * `Clause`
/// * `Environment`
/// * `InEnvironment`
/// are used for representing the trait system in the form of
/// logic programming clauses. They are part of the interface
/// for the chalk SLG solver.
...
...
@@ -378,6 +380,33 @@ pub struct ProgramClause<'tcx> {
pub
hypotheses
:
Goals
<
'tcx
>
,
}
/// A set of clauses that we assume to be true.
#[derive(Copy,
Clone,
PartialEq,
Eq,
Hash,
Debug)]
pub
struct
Environment
<
'tcx
>
{
pub
clauses
:
Clauses
<
'tcx
>
,
}
impl
Environment
<
'tcx
>
{
pub
fn
with
<
G
>
(
self
,
goal
:
G
)
->
InEnvironment
<
'tcx
,
G
>
{
InEnvironment
{
environment
:
self
,
goal
,
}
}
}
/// Something (usually a goal), along with an environment.
#[derive(Copy,
Clone,
PartialEq,
Eq,
Hash,
Debug)]
pub
struct
InEnvironment
<
'tcx
,
G
>
{
pub
environment
:
Environment
<
'tcx
>
,
pub
goal
:
G
,
}
/// Compute the environment of the given item.
fn
environment
<
'a
,
'tcx
>
(
_
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
_
def_id
:
DefId
)
->
Environment
<
'tcx
>
{
panic!
()
}
pub
type
Selection
<
'tcx
>
=
Vtable
<
'tcx
,
PredicateObligation
<
'tcx
>>
;
#[derive(Clone,Debug)]
...
...
@@ -1080,6 +1109,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
codegen_fulfill_obligation
:
codegen
::
codegen_fulfill_obligation
,
vtable_methods
,
substitute_normalize_and_test_predicates
,
environment
,
..*
providers
};
}
...
...
src/librustc/traits/structural_impls.rs
浏览文件 @
62df9732
...
...
@@ -658,7 +658,43 @@ impl<'tcx> TypeFoldable<'tcx> for traits::Clause<'tcx> {
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
&
'tcx
ty
::
List
<
traits
::
Clause
<
'tcx
>>
{
BraceStructTypeFoldableImpl!
{
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
traits
::
Environment
<
'tcx
>
{
clauses
}
}
BraceStructTypeFoldableImpl!
{
impl
<
'tcx
,
G
>
TypeFoldable
<
'tcx
>
for
traits
::
InEnvironment
<
'tcx
,
G
>
{
environment
,
goal
}
where
G
:
TypeFoldable
<
'tcx
>
}
impl
<
'a
,
'tcx
>
Lift
<
'tcx
>
for
traits
::
Environment
<
'a
>
{
type
Lifted
=
traits
::
Environment
<
'tcx
>
;
fn
lift_to_tcx
<
'b
,
'gcx
>
(
&
self
,
tcx
:
TyCtxt
<
'b
,
'gcx
,
'tcx
>
)
->
Option
<
Self
::
Lifted
>
{
tcx
.lift
(
&
self
.clauses
)
.map
(|
clauses
|
{
traits
::
Environment
{
clauses
,
}
})
}
}
impl
<
'a
,
'tcx
,
G
:
Lift
<
'tcx
>>
Lift
<
'tcx
>
for
traits
::
InEnvironment
<
'a
,
G
>
{
type
Lifted
=
traits
::
InEnvironment
<
'tcx
,
G
::
Lifted
>
;
fn
lift_to_tcx
<
'b
,
'gcx
>
(
&
self
,
tcx
:
TyCtxt
<
'b
,
'gcx
,
'tcx
>
)
->
Option
<
Self
::
Lifted
>
{
tcx
.lift
(
&
self
.environment
)
.and_then
(|
environment
|
{
tcx
.lift
(
&
self
.goal
)
.map
(|
goal
|
{
traits
::
InEnvironment
{
environment
,
goal
,
}
})
})
}
}
impl
<
'tcx
>
TypeFoldable
<
'tcx
>
for
traits
::
Clauses
<
'tcx
>
{
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
let
v
=
self
.iter
()
.map
(|
t
|
t
.fold_with
(
folder
))
...
...
src/librustc/ty/query/config.rs
浏览文件 @
62df9732
...
...
@@ -12,6 +12,7 @@
use
dep_graph
::
DepNode
;
use
hir
::
def_id
::{
CrateNum
,
DefId
,
DefIndex
};
use
mir
::
interpret
::
GlobalId
;
use
traits
;
use
traits
::
query
::{
CanonicalPredicateGoal
,
CanonicalProjectionGoal
,
CanonicalTyGoal
,
CanonicalTypeOpEqGoal
,
CanonicalTypeOpNormalizeGoal
,
CanonicalTypeOpProvePredicateGoal
,
CanonicalTypeOpSubtypeGoal
,
...
...
@@ -826,8 +827,14 @@ fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
}
impl
<
'tcx
>
QueryDescription
<
'tcx
>
for
queries
::
program_clauses_for_env
<
'tcx
>
{
fn
describe
(
_
tcx
:
TyCtxt
<
'_
,
'_
,
'_
>
,
_
:
ty
::
ParamEnv
<
'tcx
>
)
->
Cow
<
'static
,
str
>
{
"generating chalk-style clauses for param env"
.into
()
fn
describe
(
_
tcx
:
TyCtxt
<
'_
,
'_
,
'_
>
,
_
:
traits
::
Environment
<
'tcx
>
)
->
Cow
<
'static
,
str
>
{
"generating chalk-style clauses for environment"
.into
()
}
}
impl
<
'tcx
>
QueryDescription
<
'tcx
>
for
queries
::
environment
<
'tcx
>
{
fn
describe
(
_
tcx
:
TyCtxt
<
'_
,
'_
,
'_
>
,
_
:
DefId
)
->
Cow
<
'static
,
str
>
{
"return a chalk-style environment"
.into
()
}
}
...
...
src/librustc/ty/query/keys.rs
浏览文件 @
62df9732
...
...
@@ -12,6 +12,7 @@
use
infer
::
canonical
::
Canonical
;
use
hir
::
def_id
::{
CrateNum
,
DefId
,
LOCAL_CRATE
,
DefIndex
};
use
traits
;
use
ty
::{
self
,
Ty
,
TyCtxt
};
use
ty
::
subst
::
Substs
;
use
ty
::
fast_reject
::
SimplifiedType
;
...
...
@@ -181,6 +182,15 @@ fn default_span(&self, tcx: TyCtxt<'_, '_, '_>) -> Span {
}
}
impl
<
'tcx
>
Key
for
traits
::
Environment
<
'tcx
>
{
fn
query_crate
(
&
self
)
->
CrateNum
{
LOCAL_CRATE
}
fn
default_span
(
&
self
,
_
:
TyCtxt
<
'_
,
'_
,
'_
>
)
->
Span
{
DUMMY_SP
}
}
impl
Key
for
InternedString
{
fn
query_crate
(
&
self
)
->
CrateNum
{
LOCAL_CRATE
...
...
src/librustc/ty/query/mod.rs
浏览文件 @
62df9732
...
...
@@ -377,6 +377,8 @@
// might want to use `reveal_all()` method to change modes.
[]
fn
param_env
:
ParamEnv
(
DefId
)
->
ty
::
ParamEnv
<
'tcx
>
,
[]
fn
environment
:
Environment
(
DefId
)
->
traits
::
Environment
<
'tcx
>
,
// Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
// `ty.is_copy()`, etc, since that will prune the environment where possible.
[]
fn
is_copy_raw
:
is_copy_dep_node
(
ty
::
ParamEnvAnd
<
'tcx
,
Ty
<
'tcx
>>
)
->
bool
,
...
...
@@ -664,7 +666,7 @@
[]
fn
program_clauses_for
:
ProgramClausesFor
(
DefId
)
->
Clauses
<
'tcx
>
,
[]
fn
program_clauses_for_env
:
ProgramClausesForEnv
(
t
y
::
ParamEnv
<
'tcx
>
t
raits
::
Environment
<
'tcx
>
)
->
Clauses
<
'tcx
>
,
},
...
...
src/librustc/ty/query/plumbing.rs
浏览文件 @
62df9732
...
...
@@ -1156,6 +1156,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind
::
CheckMatch
=>
{
force!
(
check_match
,
def_id!
());
}
DepKind
::
ParamEnv
=>
{
force!
(
param_env
,
def_id!
());
}
DepKind
::
Environment
=>
{
force!
(
environment
,
def_id!
());
}
DepKind
::
DescribeDef
=>
{
force!
(
describe_def
,
def_id!
());
}
DepKind
::
DefSpan
=>
{
force!
(
def_span
,
def_id!
());
}
DepKind
::
LookupStability
=>
{
force!
(
lookup_stability
,
def_id!
());
}
...
...
src/librustc_traits/chalk_context.rs
浏览文件 @
62df9732
...
...
@@ -23,7 +23,9 @@
Goal
,
GoalKind
,
ProgramClause
,
QuantifierKind
QuantifierKind
,
Environment
,
InEnvironment
,
};
use
rustc
::
ty
::
fold
::{
TypeFoldable
,
TypeFolder
,
TypeVisitor
};
use
rustc
::
ty
::
subst
::
Kind
;
...
...
@@ -68,10 +70,10 @@ impl<'tcx> TypeFoldable<'tcx> for ConstrainedSubst<'tcx> {
impl
context
::
Context
for
ChalkArenas
<
'tcx
>
{
type
CanonicalExClause
=
Canonical
<
'tcx
,
ExClause
<
Self
>>
;
type
CanonicalGoalInEnvironment
=
Canonical
<
'tcx
,
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>>
;
type
CanonicalGoalInEnvironment
=
Canonical
<
'tcx
,
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>>
;
// u-canonicalization not yet implemented
type
UCanonicalGoalInEnvironment
=
Canonical
<
'tcx
,
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>>
;
type
UCanonicalGoalInEnvironment
=
Canonical
<
'tcx
,
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>>
;
type
CanonicalConstrainedSubst
=
Canonical
<
'tcx
,
ConstrainedSubst
<
'tcx
>>
;
...
...
@@ -82,13 +84,13 @@ impl context::Context for ChalkArenas<'tcx> {
type
InferenceNormalizedSubst
=
CanonicalVarValues
<
'tcx
>
;
type
GoalInEnvironment
=
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>
;
type
GoalInEnvironment
=
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>
;
type
RegionConstraint
=
QueryRegionConstraint
<
'tcx
>
;
type
Substitution
=
CanonicalVarValues
<
'tcx
>
;
type
Environment
=
ty
::
ParamEnv
<
'tcx
>
;
type
Environment
=
Environment
<
'tcx
>
;
type
Goal
=
Goal
<
'tcx
>
;
...
...
@@ -105,17 +107,17 @@ impl context::Context for ChalkArenas<'tcx> {
type
UnificationResult
=
InferOk
<
'tcx
,
()
>
;
fn
goal_in_environment
(
env
:
&
ty
::
ParamEnv
<
'tcx
>
,
env
:
&
Environment
<
'tcx
>
,
goal
:
Goal
<
'tcx
>
,
)
->
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>
{
env
.
and
(
goal
)
)
->
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>
{
env
.
with
(
goal
)
}
}
impl
context
::
AggregateOps
<
ChalkArenas
<
'gcx
>>
for
ChalkContext
<
'cx
,
'gcx
>
{
fn
make_solution
(
&
self
,
_
root_goal
:
&
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
,
_
root_goal
:
&
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
,
_
simplified_answers
:
impl
context
::
AnswerStream
<
ChalkArenas
<
'gcx
>>
,
)
->
Option
<
Canonical
<
'gcx
,
QueryResponse
<
'gcx
,
()
>>>
{
unimplemented!
()
...
...
@@ -124,7 +126,10 @@ fn make_solution(
impl
context
::
ContextOps
<
ChalkArenas
<
'gcx
>>
for
ChalkContext
<
'cx
,
'gcx
>
{
/// True if this is a coinductive goal -- e.g., proving an auto trait.
fn
is_coinductive
(
&
self
,
_
goal
:
&
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
)
->
bool
{
fn
is_coinductive
(
&
self
,
_
goal
:
&
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
)
->
bool
{
unimplemented!
()
}
...
...
@@ -142,7 +147,7 @@ fn is_coinductive(&self, _goal: &Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx
/// - the environment and goal found by substitution `S` into `arg`
fn
instantiate_ucanonical_goal
<
R
>
(
&
self
,
_
arg
:
&
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
,
_
arg
:
&
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
,
_
op
:
impl
context
::
WithInstantiatedUCanonicalGoal
<
ChalkArenas
<
'gcx
>
,
Output
=
R
>
,
)
->
R
{
unimplemented!
()
...
...
@@ -175,19 +180,19 @@ fn inference_normalized_subst_from_subst(
}
fn
canonical
(
u_canon
:
&
'a
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
,
)
->
&
'a
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
{
u_canon
:
&
'a
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
,
)
->
&
'a
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
{
u_canon
}
fn
is_trivial_substitution
(
_u_
canon
:
&
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
,
_u_
canon
:
&
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
,
_
canonical_subst
:
&
Canonical
<
'gcx
,
ConstrainedSubst
<
'gcx
>>
,
)
->
bool
{
unimplemented!
()
}
fn
num_universes
(
_
:
&
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
)
->
usize
{
fn
num_universes
(
_
:
&
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
)
->
usize
{
0
// FIXME
}
...
...
@@ -196,8 +201,8 @@ fn num_universes(_: &Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>>) -> usiz
/// but for the universes of universally quantified names.
fn
map_goal_from_canonical
(
_
map
:
&
UniverseMap
,
value
:
&
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
,
)
->
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
{
value
:
&
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
,
)
->
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
{
*
value
// FIXME universe maps not implemented yet
}
...
...
@@ -267,10 +272,10 @@ fn into_hh_goal(&mut self, goal: Goal<'tcx>) -> ChalkHhGoal<'tcx> {
fn
add_clauses
(
&
mut
self
,
_
env
:
&
ty
::
ParamEnv
<
'tcx
>
,
_
env
:
&
Environment
<
'tcx
>
,
_
clauses
:
Vec
<
ProgramClause
<
'tcx
>>
,
)
->
ty
::
ParamEnv
<
'tcx
>
{
panic!
(
"FIXME no method to add clauses to
ParamEnv
yet"
)
)
->
Environment
<
'tcx
>
{
panic!
(
"FIXME no method to add clauses to
Environment
yet"
)
}
}
...
...
@@ -279,7 +284,7 @@ impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
{
fn
resolvent_clause
(
&
mut
self
,
_
environment
:
&
ty
::
ParamEnv
<
'tcx
>
,
_
environment
:
&
Environment
<
'tcx
>
,
_
goal
:
&
DomainGoal
<
'tcx
>
,
_
subst
:
&
CanonicalVarValues
<
'tcx
>
,
_
clause
:
&
ProgramClause
<
'tcx
>
,
...
...
@@ -290,8 +295,8 @@ fn resolvent_clause(
fn
apply_answer_subst
(
&
mut
self
,
_
ex_clause
:
ChalkExClause
<
'tcx
>
,
_
selected_goal
:
&
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>
,
_
answer_table_goal
:
&
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
,
_
selected_goal
:
&
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>
,
_
answer_table_goal
:
&
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
,
_
canonical_answer_subst
:
&
Canonical
<
'gcx
,
ConstrainedSubst
<
'gcx
>>
,
)
->
chalk_engine
::
fallible
::
Fallible
<
ChalkExClause
<
'tcx
>>
{
panic!
()
...
...
@@ -303,8 +308,8 @@ impl context::TruncateOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
{
fn
truncate_goal
(
&
mut
self
,
subgoal
:
&
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>
,
)
->
Option
<
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>>
{
subgoal
:
&
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>
,
)
->
Option
<
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>>
{
Some
(
*
subgoal
)
// FIXME we should truncate at some point!
}
...
...
@@ -321,7 +326,7 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
{
fn
program_clauses
(
&
self
,
_
environment
:
&
ty
::
ParamEnv
<
'tcx
>
,
_
environment
:
&
Environment
<
'tcx
>
,
goal
:
&
DomainGoal
<
'tcx
>
,
)
->
Vec
<
ProgramClause
<
'tcx
>>
{
use
rustc
::
traits
::
WhereClause
::
*
;
...
...
@@ -389,8 +394,8 @@ fn debug_ex_clause(&mut self, value: &'v ChalkExClause<'tcx>) -> Box<dyn Debug +
fn
canonicalize_goal
(
&
mut
self
,
value
:
&
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>
,
)
->
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
{
value
:
&
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>
,
)
->
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
{
let
mut
_
orig_values
=
OriginalQueryValues
::
default
();
self
.infcx
.canonicalize_query
(
value
,
&
mut
_
orig_values
)
}
...
...
@@ -412,9 +417,9 @@ fn canonicalize_constrained_subst(
fn
u_canonicalize_goal
(
&
mut
self
,
value
:
&
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
,
value
:
&
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
,
)
->
(
Canonical
<
'gcx
,
ty
::
ParamEnvAnd
<
'gcx
,
Goal
<
'gcx
>>>
,
Canonical
<
'gcx
,
InEnvironment
<
'gcx
,
Goal
<
'gcx
>>>
,
UniverseMap
,
)
{
(
value
.clone
(),
UniverseMap
)
...
...
@@ -422,14 +427,14 @@ fn u_canonicalize_goal(
fn
invert_goal
(
&
mut
self
,
_
value
:
&
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>
,
)
->
Option
<
ty
::
ParamEnvAnd
<
'tcx
,
Goal
<
'tcx
>>>
{
_
value
:
&
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>
,
)
->
Option
<
InEnvironment
<
'tcx
,
Goal
<
'tcx
>>>
{
panic!
(
"goal inversion not yet implemented"
)
}
fn
unify_parameters
(
&
mut
self
,
_
environment
:
&
ty
::
ParamEnv
<
'tcx
>
,
_
environment
:
&
Environment
<
'tcx
>
,
_
a
:
&
Kind
<
'tcx
>
,
_
b
:
&
Kind
<
'tcx
>
,
)
->
ChalkEngineFallible
<
InferOk
<
'tcx
,
()
>>
{
...
...
src/librustc_traits/lowering/environment.rs
0 → 100644
浏览文件 @
62df9732
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
rustc
::
traits
::{
Clause
,
Clauses
,
DomainGoal
,
FromEnv
,
Goal
,
ProgramClause
,
Environment
,
};
use
rustc
::
ty
::{
TyCtxt
,
Ty
};
use
rustc_data_structures
::
fx
::
FxHashSet
;
struct
ClauseVisitor
<
'set
,
'a
,
'tcx
:
'a
>
{
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
round
:
&
'set
mut
FxHashSet
<
Clause
<
'tcx
>>
,
}
impl
ClauseVisitor
<
'set
,
'a
,
'tcx
>
{
fn
new
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
round
:
&
'set
mut
FxHashSet
<
Clause
<
'tcx
>>
)
->
Self
{
ClauseVisitor
{
tcx
,
round
,
}
}
fn
visit_ty
(
&
mut
self
,
_
ty
:
Ty
<
'tcx
>
)
{
}
fn
visit_from_env
(
&
mut
self
,
from_env
:
FromEnv
<
'tcx
>
)
{
match
from_env
{
FromEnv
::
Trait
(
predicate
)
=>
{
self
.round
.extend
(
self
.tcx
.program_clauses_for
(
predicate
.def_id
())
.iter
()
.cloned
()
);
}
FromEnv
::
Ty
(
ty
)
=>
self
.visit_ty
(
ty
),
}
}
fn
visit_domain_goal
(
&
mut
self
,
domain_goal
:
DomainGoal
<
'tcx
>
)
{
if
let
DomainGoal
::
FromEnv
(
from_env
)
=
domain_goal
{
self
.visit_from_env
(
from_env
);
}
}
fn
visit_goal
(
&
mut
self
,
goal
:
Goal
<
'tcx
>
)
{
match
goal
{
Goal
::
Implies
(
clauses
,
goal
)
=>
{
for
clause
in
clauses
{
self
.visit_clause
(
*
clause
);
}
self
.visit_goal
(
*
goal
);
}
Goal
::
And
(
goal1
,
goal2
)
=>
{
self
.visit_goal
(
*
goal1
);
self
.visit_goal
(
*
goal2
);
}
Goal
::
Not
(
goal
)
=>
self
.visit_goal
(
*
goal
),
Goal
::
DomainGoal
(
domain_goal
)
=>
self
.visit_domain_goal
(
domain_goal
),
Goal
::
Quantified
(
_
,
goal
)
=>
self
.visit_goal
(
**
goal
.skip_binder
()),
Goal
::
CannotProve
=>
(),
}
}
fn
visit_program_clause
(
&
mut
self
,
clause
:
ProgramClause
<
'tcx
>
)
{
self
.visit_domain_goal
(
clause
.goal
);
for
goal
in
clause
.hypotheses
{
self
.visit_goal
(
*
goal
);
}
}
fn
visit_clause
(
&
mut
self
,
clause
:
Clause
<
'tcx
>
)
{
match
clause
{
Clause
::
Implies
(
clause
)
=>
self
.visit_program_clause
(
clause
),
Clause
::
ForAll
(
clause
)
=>
self
.visit_program_clause
(
*
clause
.skip_binder
()),
}
}
}
crate
fn
program_clauses_for_env
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
environment
:
Environment
<
'tcx
>
,
)
->
Clauses
<
'tcx
>
{
debug!
(
"program_clauses_for_env(environment={:?})"
,
environment
);
let
mut
last_round
=
FxHashSet
();
{
let
mut
visitor
=
ClauseVisitor
::
new
(
tcx
,
&
mut
last_round
);
for
clause
in
environment
.clauses
{
visitor
.visit_clause
(
*
clause
);
}
}
let
mut
closure
=
last_round
.clone
();
let
mut
next_round
=
FxHashSet
();
while
!
last_round
.is_empty
()
{
let
mut
visitor
=
ClauseVisitor
::
new
(
tcx
,
&
mut
next_round
);
for
clause
in
last_round
{
visitor
.visit_clause
(
clause
);
}
last_round
=
next_round
.drain
()
.filter
(|
&
clause
|
closure
.insert
(
clause
))
.collect
();
}
debug!
(
"program_clauses_for_env: closure = {:#?}"
,
closure
);
return
tcx
.mk_clauses
(
closure
.into_iter
()
);
}
src/librustc_traits/lowering.rs
→
src/librustc_traits/lowering
/mod
.rs
浏览文件 @
62df9732
...
...
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod
environment
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
hir
::
intravisit
::{
self
,
NestedVisitorMap
,
Visitor
};
use
rustc
::
hir
::
map
::
definitions
::
DefPathData
;
...
...
@@ -25,8 +27,6 @@
};
use
rustc
::
ty
::
query
::
Providers
;
use
rustc
::
ty
::{
self
,
List
,
TyCtxt
};
use
rustc_data_structures
::
fx
::
FxHashSet
;
use
std
::
mem
;
use
syntax
::
ast
;
use
std
::
iter
;
...
...
@@ -34,7 +34,7 @@
crate
fn
provide
(
p
:
&
mut
Providers
)
{
*
p
=
Providers
{
program_clauses_for
,
program_clauses_for_env
,
program_clauses_for_env
:
environment
::
program_clauses_for_env
,
..*
p
};
}
...
...
@@ -173,66 +173,6 @@ fn into_well_formed_goal(self) -> DomainGoal<'tcx> {
}
}
crate
fn
program_clauses_for_env
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
)
->
Clauses
<
'tcx
>
{
debug!
(
"program_clauses_for_env(param_env={:?})"
,
param_env
);
let
mut
last_round
=
FxHashSet
();
last_round
.extend
(
param_env
.caller_bounds
.iter
()
.flat_map
(|
&
p
|
predicate_def_id
(
p
)),
);
let
mut
closure
=
last_round
.clone
();
let
mut
next_round
=
FxHashSet
();
while
!
last_round
.is_empty
()
{
next_round
.extend
(
last_round
.drain
()
.flat_map
(|
def_id
|
{
tcx
.predicates_of
(
def_id
)
.instantiate_identity
(
tcx
)
.predicates
})
.flat_map
(|
p
|
predicate_def_id
(
p
))
.filter
(|
&
def_id
|
closure
.insert
(
def_id
)),
);
mem
::
swap
(
&
mut
next_round
,
&
mut
last_round
);
}
debug!
(
"program_clauses_for_env: closure = {:#?}"
,
closure
);
return
tcx
.mk_clauses
(
closure
.into_iter
()
.flat_map
(|
def_id
|
tcx
.program_clauses_for
(
def_id
)
.iter
()
.cloned
()),
);
/// Given that `predicate` is in the environment, returns the
/// def-id of something (e.g., a trait, associated item, etc)
/// whose predicates can also be assumed to be true. We will
/// compute the transitive closure of such things.
fn
predicate_def_id
<
'tcx
>
(
predicate
:
ty
::
Predicate
<
'tcx
>
)
->
Option
<
DefId
>
{
match
predicate
{
ty
::
Predicate
::
Trait
(
predicate
)
=>
Some
(
predicate
.def_id
()),
ty
::
Predicate
::
Projection
(
projection
)
=>
Some
(
projection
.item_def_id
()),
ty
::
Predicate
::
WellFormed
(
..
)
|
ty
::
Predicate
::
RegionOutlives
(
..
)
|
ty
::
Predicate
::
TypeOutlives
(
..
)
|
ty
::
Predicate
::
ObjectSafe
(
..
)
|
ty
::
Predicate
::
ClosureKind
(
..
)
|
ty
::
Predicate
::
Subtype
(
..
)
|
ty
::
Predicate
::
ConstEvaluatable
(
..
)
=>
None
,
}
}
}
fn
program_clauses_for_trait
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
def_id
:
DefId
,
...
...
@@ -595,8 +535,8 @@ fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
}
if
attr
.check_name
(
"rustc_dump_env_program_clauses"
)
{
let
param_env
=
self
.tcx
.param_env
(
def_id
);
clauses
=
Some
(
self
.tcx
.program_clauses_for_env
(
param_env
));
let
environment
=
self
.tcx
.environment
(
def_id
);
clauses
=
Some
(
self
.tcx
.program_clauses_for_env
(
environment
));
}
if
let
Some
(
clauses
)
=
clauses
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录