Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4b09209e
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,发现更多精彩内容 >>
提交
4b09209e
编写于
2月 02, 2015
作者:
F
Flavio Percoco
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Ensure default trait impls hold
上级
58a8103d
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
239 addition
and
20 deletion
+239
-20
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/mod.rs
+34
-3
src/librustc/middle/traits/select.rs
src/librustc/middle/traits/select.rs
+152
-8
src/librustc/middle/traits/util.rs
src/librustc/middle/traits/util.rs
+40
-7
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+3
-1
src/librustc/middle/ty_fold.rs
src/librustc/middle/ty_fold.rs
+10
-1
未找到文件。
src/librustc/middle/traits/mod.rs
浏览文件 @
4b09209e
...
...
@@ -222,7 +222,7 @@ pub enum Vtable<'tcx, N> {
VtableImpl
(
VtableImplData
<
'tcx
,
N
>
),
/// Vtable for default trait implementations
VtableDefaultTrait
(
ast
::
DefId
),
VtableDefaultTrait
(
VtableDefaultTraitData
<
N
>
),
/// Successful resolution to an obligation provided by the caller
/// for some type parameter. The `Vec<N>` represents the
...
...
@@ -262,6 +262,12 @@ pub struct VtableImplData<'tcx, N> {
pub
nested
:
subst
::
VecPerParamSpace
<
N
>
}
#[derive(Debug,Clone)]
pub
struct
VtableDefaultTraitData
<
N
>
{
pub
trait_def_id
:
ast
::
DefId
,
pub
nested
:
subst
::
VecPerParamSpace
<
N
>
}
#[derive(Debug,Clone)]
pub
struct
VtableBuiltinData
<
N
>
{
pub
nested
:
subst
::
VecPerParamSpace
<
N
>
...
...
@@ -527,7 +533,7 @@ pub fn iter_nested(&self) -> Iter<N> {
pub
fn
map_nested
<
M
,
F
>
(
&
self
,
op
:
F
)
->
Vtable
<
'tcx
,
M
>
where
F
:
FnMut
(
&
N
)
->
M
{
match
*
self
{
VtableImpl
(
ref
i
)
=>
VtableImpl
(
i
.map_nested
(
op
)),
VtableDefaultTrait
(
t
)
=>
VtableDefaultTrait
(
t
),
VtableDefaultTrait
(
ref
t
)
=>
VtableDefaultTrait
(
t
.map_nested
(
op
)
),
VtableFnPointer
(
ref
sig
)
=>
VtableFnPointer
((
*
sig
)
.clone
()),
VtableClosure
(
d
,
ref
s
)
=>
VtableClosure
(
d
,
s
.clone
()),
VtableParam
(
ref
n
)
=>
VtableParam
(
n
.iter
()
.map
(
op
)
.collect
()),
...
...
@@ -543,7 +549,7 @@ pub fn map_move_nested<M, F>(self, op: F) -> Vtable<'tcx, M> where
VtableImpl
(
i
)
=>
VtableImpl
(
i
.map_move_nested
(
op
)),
VtableFnPointer
(
sig
)
=>
VtableFnPointer
(
sig
),
VtableClosure
(
d
,
s
)
=>
VtableClosure
(
d
,
s
),
VtableDefaultTrait
(
t
)
=>
VtableDefaultTrait
(
t
),
VtableDefaultTrait
(
t
)
=>
VtableDefaultTrait
(
t
.map_move_nested
(
op
)
),
VtableParam
(
n
)
=>
VtableParam
(
n
.into_iter
()
.map
(
op
)
.collect
()),
VtableObject
(
p
)
=>
VtableObject
(
p
),
VtableBuiltin
(
no
)
=>
VtableBuiltin
(
no
.map_move_nested
(
op
)),
...
...
@@ -578,6 +584,31 @@ pub fn map_move_nested<M, F>(self, op: F) -> VtableImplData<'tcx, M> where
}
}
impl
<
N
>
VtableDefaultTraitData
<
N
>
{
pub
fn
iter_nested
(
&
self
)
->
Iter
<
N
>
{
self
.nested
.iter
()
}
pub
fn
map_nested
<
M
,
F
>
(
&
self
,
op
:
F
)
->
VtableDefaultTraitData
<
M
>
where
F
:
FnMut
(
&
N
)
->
M
,
{
VtableDefaultTraitData
{
trait_def_id
:
self
.trait_def_id
,
nested
:
self
.nested
.map
(
op
)
}
}
pub
fn
map_move_nested
<
M
,
F
>
(
self
,
op
:
F
)
->
VtableDefaultTraitData
<
M
>
where
F
:
FnMut
(
N
)
->
M
,
{
let
VtableDefaultTraitData
{
trait_def_id
,
nested
}
=
self
;
VtableDefaultTraitData
{
trait_def_id
:
trait_def_id
,
nested
:
nested
.map_move
(
op
)
}
}
}
impl
<
N
>
VtableBuiltinData
<
N
>
{
pub
fn
iter_nested
(
&
self
)
->
Iter
<
N
>
{
self
.nested
.iter
()
...
...
src/librustc/middle/traits/select.rs
浏览文件 @
4b09209e
...
...
@@ -21,13 +21,13 @@
use
super
::{
project
};
use
super
::
project
::
Normalized
;
use
super
::{
PredicateObligation
,
TraitObligation
,
ObligationCause
};
use
super
::{
ObligationCauseCode
,
BuiltinDerivedObligation
};
use
super
::{
ObligationCauseCode
,
BuiltinDerivedObligation
,
ImplDerivedObligation
};
use
super
::{
SelectionError
,
Unimplemented
,
Overflow
,
OutputTypeParameterMismatch
};
use
super
::{
Selection
};
use
super
::{
SelectionResult
};
use
super
::{
VtableBuiltin
,
VtableImpl
,
VtableParam
,
VtableClosure
,
VtableFnPointer
,
VtableObject
,
VtableDefaultTrait
};
use
super
::{
VtableImplData
,
VtableObjectData
,
VtableBuiltinData
};
use
super
::{
VtableImplData
,
VtableObjectData
,
VtableBuiltinData
,
VtableDefaultTraitData
};
use
super
::
object_safety
;
use
super
::{
util
};
...
...
@@ -1535,7 +1535,7 @@ fn builtin_bound(&mut self,
ty
::
struct_fields
(
self
.tcx
(),
def_id
,
substs
)
.iter
()
.map
(|
f
|
f
.mt.ty
)
.collect
();
nominal
(
self
,
bound
,
def_i
d
,
types
)
nominal
(
boun
d
,
types
)
}
ty
::
ty_enum
(
def_id
,
substs
)
=>
{
...
...
@@ -1545,7 +1545,7 @@ fn builtin_bound(&mut self,
.flat_map
(|
variant
|
variant
.args
.iter
())
.cloned
()
.collect
();
nominal
(
self
,
bound
,
def_i
d
,
types
)
nominal
(
boun
d
,
types
)
}
ty
::
ty_projection
(
_
)
|
...
...
@@ -1594,9 +1594,7 @@ fn builtin_bound(&mut self,
}
};
fn
nominal
<
'cx
,
'tcx
>
(
this
:
&
mut
SelectionContext
<
'cx
,
'tcx
>
,
bound
:
ty
::
BuiltinBound
,
def_id
:
ast
::
DefId
,
fn
nominal
<
'cx
,
'tcx
>
(
bound
:
ty
::
BuiltinBound
,
types
:
Vec
<
Ty
<
'tcx
>>
)
->
Result
<
BuiltinBoundConditions
<
'tcx
>
,
SelectionError
<
'tcx
>>
{
...
...
@@ -1615,6 +1613,89 @@ fn nominal<'cx, 'tcx>(this: &mut SelectionContext<'cx, 'tcx>,
}
}
fn
constituent_types
(
&
self
,
t
:
Ty
<
'tcx
>
)
->
Vec
<
Ty
<
'tcx
>>
{
match
t
.sty
{
ty
::
ty_uint
(
_
)
|
ty
::
ty_int
(
_
)
|
ty
::
ty_bool
|
ty
::
ty_float
(
_
)
|
ty
::
ty_bare_fn
(
..
)
|
ty
::
ty_str
|
ty
::
ty_err
|
ty
::
ty_char
=>
{
Vec
::
new
()
}
ty
::
ty_projection
(
..
)
|
ty
::
ty_param
(
..
)
|
ty
::
ty_infer
(
..
)
=>
{
self
.tcx
()
.sess
.bug
(
&
format!
(
"asked to assemble constituent types of unexpected type: {}"
,
t
.repr
(
self
.tcx
()))[]);
}
ty
::
ty_uniq
(
referent_ty
)
=>
{
// Box<T>
vec!
[
referent_ty
]
}
ty
::
ty_trait
(
ref
data
)
=>
{
// Recursively check all supertraits to find out if any further
// bounds are required and thus we must fulfill.
let
principal
=
data
.principal_trait_ref_with_self_ty
(
self
.tcx
(),
self
.tcx
()
.types.err
);
util
::
supertraits
(
self
.tcx
(),
principal
)
.map
(|
tr
|
tr
.self_ty
())
.collect
()
}
ty
::
ty_open
(
element_ty
)
=>
{
vec!
[
element_ty
]},
ty
::
ty_ptr
(
ty
::
mt
{
ty
:
element_ty
,
..
})
|
ty
::
ty_rptr
(
_
,
ty
::
mt
{
ty
:
element_ty
,
..
})
=>
{
vec!
[
element_ty
]
},
ty
::
ty_vec
(
element_ty
,
_
)
=>
{
vec!
[
element_ty
]
}
ty
::
ty_tup
(
ref
tys
)
=>
{
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
tys
.clone
()
}
ty
::
ty_closure
(
def_id
,
_
,
substs
)
=>
{
assert_eq!
(
def_id
.krate
,
ast
::
LOCAL_CRATE
);
match
self
.closure_typer
.closure_upvars
(
def_id
,
substs
)
{
Some
(
upvars
)
=>
{
upvars
.iter
()
.map
(|
c
|
c
.ty
)
.collect
()
}
None
=>
{
Vec
::
new
()
}
}
}
ty
::
ty_struct
(
def_id
,
substs
)
=>
{
ty
::
struct_fields
(
self
.tcx
(),
def_id
,
substs
)
.iter
()
.map
(|
f
|
f
.mt.ty
)
.collect
()
}
ty
::
ty_enum
(
def_id
,
substs
)
=>
{
ty
::
substd_enum_variants
(
self
.tcx
(),
def_id
,
substs
)
.iter
()
.flat_map
(|
variant
|
variant
.args
.iter
())
.map
(|
&
ty
|
ty
)
.collect
()
}
}
}
///////////////////////////////////////////////////////////////////////////
// CONFIRMATION
//
...
...
@@ -1648,7 +1729,8 @@ fn confirm_candidate(&mut self,
}
DefaultTraitCandidate
(
trait_def_id
)
=>
{
Ok
(
VtableDefaultTrait
(
trait_def_id
))
let
data
=
try!
(
self
.confirm_default_impl_candidate
(
obligation
,
trait_def_id
));
Ok
(
VtableDefaultTrait
(
data
))
}
ImplCandidate
(
impl_def_id
)
=>
{
...
...
@@ -1783,6 +1865,68 @@ fn vtable_builtin_data(&mut self,
VtableBuiltinData
{
nested
:
obligations
}
}
fn
confirm_default_impl_candidate
(
&
mut
self
,
obligation
:
&
TraitObligation
<
'tcx
>
,
impl_def_id
:
ast
::
DefId
)
->
Result
<
VtableDefaultTraitData
<
PredicateObligation
<
'tcx
>>
,
SelectionError
<
'tcx
>>
{
debug!
(
"confirm_default_impl_candidate({}, {})"
,
obligation
.repr
(
self
.tcx
()),
impl_def_id
.repr
(
self
.tcx
()));
let
self_ty
=
self
.infcx
.shallow_resolve
(
obligation
.predicate
.0
.self_ty
());
let
types
=
self
.constituent_types
(
self_ty
);
Ok
(
self
.vtable_default_impl
(
obligation
,
impl_def_id
,
types
))
}
fn
vtable_default_impl
(
&
mut
self
,
obligation
:
&
TraitObligation
<
'tcx
>
,
trait_def_id
:
ast
::
DefId
,
nested
:
Vec
<
Ty
<
'tcx
>>
)
->
VtableDefaultTraitData
<
PredicateObligation
<
'tcx
>>
{
let
derived_cause
=
self
.derived_cause
(
obligation
,
ImplDerivedObligation
);
let
obligations
=
nested
.iter
()
.map
(|
&
nested_ty
|
{
// the obligation might be higher-ranked, e.g. for<'a> &'a
// int : Copy. In that case, we will wind up with
// late-bound regions in the `nested` vector. So for each
// one we instantiate to a skolemized region, do our work
// to produce something like `&'0 int : Copy`, and then
// re-bind it. This is a bit of busy-work but preserves
// the invariant that we only manipulate free regions, not
// bound ones.
self
.infcx
.try
(|
snapshot
|
{
let
(
skol_ty
,
skol_map
)
=
self
.infcx
()
.skolemize_late_bound_regions
(
&
ty
::
Binder
(
nested_ty
),
snapshot
);
let
skol_predicate
=
util
::
predicate_for_default_trait_impl
(
self
.tcx
(),
derived_cause
.clone
(),
trait_def_id
,
obligation
.recursion_depth
+
1
,
skol_ty
);
match
skol_predicate
{
Ok
(
skol_predicate
)
=>
Ok
(
self
.infcx
()
.plug_leaks
(
skol_map
,
snapshot
,
&
skol_predicate
)),
Err
(
ErrorReported
)
=>
Err
(
ErrorReported
)
}
})
})
.collect
::
<
Result
<
_
,
_
>>
();
let
obligations
=
match
obligations
{
Ok
(
o
)
=>
o
,
Err
(
ErrorReported
)
=>
Vec
::
new
()
};
let
obligations
=
VecPerParamSpace
::
new
(
obligations
,
Vec
::
new
(),
Vec
::
new
());
debug!
(
"vtable_default_impl_data: obligations={}"
,
obligations
.repr
(
self
.tcx
()));
VtableDefaultTraitData
{
trait_def_id
:
trait_def_id
,
nested
:
obligations
}
}
fn
confirm_impl_candidate
(
&
mut
self
,
obligation
:
&
TraitObligation
<
'tcx
>
,
impl_def_id
:
ast
::
DefId
)
...
...
src/librustc/middle/traits/util.rs
浏览文件 @
4b09209e
...
...
@@ -20,7 +20,7 @@
use
util
::
ppaux
::
Repr
;
use
super
::{
Obligation
,
ObligationCause
,
PredicateObligation
,
VtableImpl
,
VtableParam
,
VtableImplData
};
VtableImpl
,
VtableParam
,
VtableImplData
,
VtableDefaultTraitData
};
struct
PredicateSet
<
'a
,
'tcx
:
'a
>
{
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
,
...
...
@@ -323,15 +323,13 @@ pub fn trait_ref_for_builtin_bound<'tcx>(
}
}
pub
fn
predicate_for_
builtin_bound
<
'tcx
>
(
pub
fn
predicate_for_
trait_ref
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
cause
:
ObligationCause
<
'tcx
>
,
builtin_bound
:
ty
::
BuiltinBound
,
recursion_depth
:
uint
,
param_ty
:
Ty
<
'tcx
>
)
trait_ref
:
Rc
<
ty
::
TraitRef
<
'tcx
>>
,
recursion_depth
:
uint
)
->
Result
<
PredicateObligation
<
'tcx
>
,
ErrorReported
>
{
let
trait_ref
=
try!
(
trait_ref_for_builtin_bound
(
tcx
,
builtin_bound
,
param_ty
));
Ok
(
Obligation
{
cause
:
cause
,
recursion_depth
:
recursion_depth
,
...
...
@@ -339,6 +337,33 @@ pub fn predicate_for_builtin_bound<'tcx>(
})
}
pub
fn
predicate_for_default_trait_impl
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
cause
:
ObligationCause
<
'tcx
>
,
trait_def_id
:
ast
::
DefId
,
recursion_depth
:
uint
,
param_ty
:
Ty
<
'tcx
>
)
->
Result
<
PredicateObligation
<
'tcx
>
,
ErrorReported
>
{
let
trait_ref
=
Rc
::
new
(
ty
::
TraitRef
{
def_id
:
trait_def_id
,
substs
:
tcx
.mk_substs
(
Substs
::
empty
()
.with_self_ty
(
param_ty
))
});
predicate_for_trait_ref
(
tcx
,
cause
,
trait_ref
,
recursion_depth
)
}
pub
fn
predicate_for_builtin_bound
<
'tcx
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
cause
:
ObligationCause
<
'tcx
>
,
builtin_bound
:
ty
::
BuiltinBound
,
recursion_depth
:
uint
,
param_ty
:
Ty
<
'tcx
>
)
->
Result
<
PredicateObligation
<
'tcx
>
,
ErrorReported
>
{
let
trait_ref
=
try!
(
trait_ref_for_builtin_bound
(
tcx
,
builtin_bound
,
param_ty
));
predicate_for_trait_ref
(
tcx
,
cause
,
trait_ref
,
recursion_depth
)
}
/// Cast a trait reference into a reference to one of its super
/// traits; returns `None` if `target_trait_def_id` is not a
/// supertrait.
...
...
@@ -445,7 +470,7 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
v
.repr
(
tcx
),
super
::
VtableDefaultTrait
(
ref
t
)
=>
format!
(
"VtableDefaultTrait({:?})"
,
t
),
t
.repr
(
tcx
),
super
::
VtableClosure
(
ref
d
,
ref
s
)
=>
format!
(
"VtableClosure({},{})"
,
...
...
@@ -486,6 +511,14 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
}
}
impl
<
'tcx
,
N
:
Repr
<
'tcx
>>
Repr
<
'tcx
>
for
super
::
VtableDefaultTraitData
<
N
>
{
fn
repr
(
&
self
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
)
->
String
{
format!
(
"VtableDefaultTraitData(trait_def_id={}, nested={})"
,
self
.trait_def_id
.repr
(
tcx
),
self
.nested
.repr
(
tcx
))
}
}
impl
<
'tcx
>
Repr
<
'tcx
>
for
super
::
VtableObjectData
<
'tcx
>
{
fn
repr
(
&
self
,
tcx
:
&
ty
::
ctxt
<
'tcx
>
)
->
String
{
format!
(
"VtableObject(object_ty={})"
,
...
...
src/librustc/middle/ty.rs
浏览文件 @
4b09209e
...
...
@@ -5175,6 +5175,9 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
&
None
=>
None
}
}
ast
::
ItemDefTrait
(
_
,
ref
ast_trait_ref
)
=>
{
Some
(
ty
::
node_id_to_trait_ref
(
cx
,
ast_trait_ref
.ref_id
))
}
_
=>
None
}
}
...
...
@@ -5999,7 +6002,6 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
/// Records a trait-to-implementation mapping.
pub
fn
record_default_trait_implementation
(
tcx
:
&
ctxt
,
trait_def_id
:
DefId
)
{
//assert!(did.krate != ast::LOCAL_CRATE);
if
tcx
.default_trait_impls
.borrow
()
.contains
(
&
trait_def_id
)
{
return
;
}
...
...
src/librustc/middle/ty_fold.rs
浏览文件 @
4b09209e
...
...
@@ -507,6 +507,15 @@ fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableImplDat
}
}
impl
<
'tcx
,
N
:
TypeFoldable
<
'tcx
>>
TypeFoldable
<
'tcx
>
for
traits
::
VtableDefaultTraitData
<
N
>
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
traits
::
VtableDefaultTraitData
<
N
>
{
traits
::
VtableDefaultTraitData
{
trait_def_id
:
self
.trait_def_id
,
nested
:
self
.nested
.fold_with
(
folder
),
}
}
}
impl
<
'tcx
,
N
:
TypeFoldable
<
'tcx
>>
TypeFoldable
<
'tcx
>
for
traits
::
VtableBuiltinData
<
N
>
{
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
traits
::
VtableBuiltinData
<
N
>
{
traits
::
VtableBuiltinData
{
...
...
@@ -519,7 +528,7 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
fn
fold_with
<
F
:
TypeFolder
<
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
traits
::
Vtable
<
'tcx
,
N
>
{
match
*
self
{
traits
::
VtableImpl
(
ref
v
)
=>
traits
::
VtableImpl
(
v
.fold_with
(
folder
)),
traits
::
VtableDefaultTrait
(
t
)
=>
traits
::
VtableDefaultTrait
(
t
),
traits
::
VtableDefaultTrait
(
ref
t
)
=>
traits
::
VtableDefaultTrait
(
t
.fold_with
(
folder
)
),
traits
::
VtableClosure
(
d
,
ref
s
)
=>
{
traits
::
VtableClosure
(
d
,
s
.fold_with
(
folder
))
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录