Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
77c5f557
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,发现更多精彩内容 >>
未验证
提交
77c5f557
编写于
4月 26, 2019
作者:
M
Mazdak Farrokhzad
提交者:
GitHub
4月 26, 2019
浏览文件
操作
浏览文件
下载
差异文件
Rollup merge of #60183 - tmandry:chalk-builtin-copy-clone, r=scalexm
Chalkify: Add builtin Copy/Clone r? @nikomatsakis
上级
8bdb91d9
56ab3e70
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
208 addition
and
38 deletion
+208
-38
src/librustc/traits/select.rs
src/librustc/traits/select.rs
+4
-10
src/librustc_traits/chalk_context/program_clauses/builtin.rs
src/librustc_traits/chalk_context/program_clauses/builtin.rs
+141
-27
src/librustc_traits/chalk_context/program_clauses/mod.rs
src/librustc_traits/chalk_context/program_clauses/mod.rs
+20
-1
src/test/run-pass/chalkify/builtin-copy-clone.rs
src/test/run-pass/chalkify/builtin-copy-clone.rs
+43
-0
未找到文件。
src/librustc/traits/select.rs
浏览文件 @
77c5f557
...
...
@@ -2505,16 +2505,10 @@ fn copy_clone_conditions(
}
ty
::
Closure
(
def_id
,
substs
)
=>
{
let
trait_id
=
obligation
.predicate
.def_id
();
let
is_copy_trait
=
Some
(
trait_id
)
==
self
.tcx
()
.lang_items
()
.copy_trait
();
let
is_clone_trait
=
Some
(
trait_id
)
==
self
.tcx
()
.lang_items
()
.clone_trait
();
if
is_copy_trait
||
is_clone_trait
{
Where
(
ty
::
Binder
::
bind
(
substs
.upvar_tys
(
def_id
,
self
.tcx
())
.collect
(),
))
}
else
{
None
}
// (*) binder moved here
Where
(
ty
::
Binder
::
bind
(
substs
.upvar_tys
(
def_id
,
self
.tcx
())
.collect
(),
))
}
ty
::
Adt
(
..
)
|
ty
::
Projection
(
..
)
|
ty
::
Param
(
..
)
|
ty
::
Opaque
(
..
)
=>
{
...
...
src/librustc_traits/chalk_context/program_clauses/builtin.rs
浏览文件 @
77c5f557
...
...
@@ -6,10 +6,42 @@
};
use
rustc
::
ty
;
use
rustc
::
ty
::
subst
::{
InternalSubsts
,
Subst
};
use
rustc
::
hir
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
crate
::
lowering
::
Lower
;
use
crate
::
generic_types
;
/// Returns a predicate of the form
/// `Implemented(ty: Trait) :- Implemented(nested: Trait)...`
/// where `Trait` is specified by `trait_def_id`.
fn
builtin_impl_clause
(
tcx
:
ty
::
TyCtxt
<
'_
,
'_
,
'tcx
>
,
ty
:
ty
::
Ty
<
'tcx
>
,
nested
:
&
[
ty
::
Ty
<
'tcx
>
],
trait_def_id
:
DefId
)
->
ProgramClause
<
'tcx
>
{
ProgramClause
{
goal
:
ty
::
TraitPredicate
{
trait_ref
:
ty
::
TraitRef
{
def_id
:
trait_def_id
,
substs
:
tcx
.mk_substs_trait
(
ty
,
&
[]),
},
}
.lower
(),
hypotheses
:
tcx
.mk_goals
(
nested
.iter
()
.cloned
()
.map
(|
nested_ty
|
ty
::
TraitRef
{
def_id
:
trait_def_id
,
substs
:
tcx
.mk_substs_trait
(
nested_ty
,
&
[]),
})
.map
(|
trait_ref
|
ty
::
TraitPredicate
{
trait_ref
})
.map
(|
pred
|
GoalKind
::
DomainGoal
(
pred
.lower
()))
.map
(|
goal_kind
|
tcx
.mk_goal
(
goal_kind
))
),
category
:
ProgramClauseCategory
::
Other
,
}
}
crate
fn
assemble_builtin_unsize_impls
<
'tcx
>
(
tcx
:
ty
::
TyCtxt
<
'_
,
'_
,
'tcx
>
,
unsize_def_id
:
DefId
,
...
...
@@ -93,26 +125,7 @@
clauses
:
&
mut
Vec
<
Clause
<
'tcx
>>
)
{
let
mut
push_builtin_impl
=
|
ty
:
ty
::
Ty
<
'tcx
>
,
nested
:
&
[
ty
::
Ty
<
'tcx
>
]|
{
let
clause
=
ProgramClause
{
goal
:
ty
::
TraitPredicate
{
trait_ref
:
ty
::
TraitRef
{
def_id
:
sized_def_id
,
substs
:
tcx
.mk_substs_trait
(
ty
,
&
[]),
},
}
.lower
(),
hypotheses
:
tcx
.mk_goals
(
nested
.iter
()
.cloned
()
.map
(|
nested_ty
|
ty
::
TraitRef
{
def_id
:
sized_def_id
,
substs
:
tcx
.mk_substs_trait
(
nested_ty
,
&
[]),
})
.map
(|
trait_ref
|
ty
::
TraitPredicate
{
trait_ref
})
.map
(|
pred
|
GoalKind
::
DomainGoal
(
pred
.lower
()))
.map
(|
goal_kind
|
tcx
.mk_goal
(
goal_kind
))
),
category
:
ProgramClauseCategory
::
Other
,
};
let
clause
=
builtin_impl_clause
(
tcx
,
ty
,
nested
,
sized_def_id
);
// Bind innermost bound vars that may exist in `ty` and `nested`.
clauses
.push
(
Clause
::
ForAll
(
ty
::
Binder
::
bind
(
clause
)));
};
...
...
@@ -124,6 +137,8 @@
ty
::
Int
(
..
)
|
ty
::
Uint
(
..
)
|
ty
::
Float
(
..
)
|
ty
::
Infer
(
ty
::
IntVar
(
_
))
|
ty
::
Infer
(
ty
::
FloatVar
(
_
))
|
ty
::
Error
|
ty
::
Never
=>
push_builtin_impl
(
ty
,
&
[]),
...
...
@@ -175,14 +190,11 @@
push_builtin_impl
(
adt
,
&
sized_constraint
);
}
// Artificially trigger an ambiguity.
ty
::
Infer
(
..
)
=>
{
// Everybody can find at least two types to unify against:
// general ty vars, int vars and float vars.
// Artificially trigger an ambiguity by adding two possible types to
// unify against.
ty
::
Infer
(
ty
::
TyVar
(
_
))
=>
{
push_builtin_impl
(
tcx
.types.i32
,
&
[]);
push_builtin_impl
(
tcx
.types.u32
,
&
[]);
push_builtin_impl
(
tcx
.types.f32
,
&
[]);
push_builtin_impl
(
tcx
.types.f64
,
&
[]);
}
ty
::
Projection
(
_
projection_ty
)
=>
{
...
...
@@ -203,6 +215,108 @@
ty
::
Opaque
(
..
)
=>
(),
ty
::
Bound
(
..
)
|
ty
::
GeneratorWitness
(
..
)
=>
bug!
(
"unexpected type {:?}"
,
ty
),
ty
::
GeneratorWitness
(
..
)
|
ty
::
Infer
(
ty
::
FreshTy
(
_
))
|
ty
::
Infer
(
ty
::
FreshIntTy
(
_
))
|
ty
::
Infer
(
ty
::
FreshFloatTy
(
_
))
=>
bug!
(
"unexpected type {:?}"
,
ty
),
}
}
crate
fn
assemble_builtin_copy_clone_impls
<
'tcx
>
(
tcx
:
ty
::
TyCtxt
<
'_
,
'_
,
'tcx
>
,
trait_def_id
:
DefId
,
ty
:
ty
::
Ty
<
'tcx
>
,
clauses
:
&
mut
Vec
<
Clause
<
'tcx
>>
)
{
let
mut
push_builtin_impl
=
|
ty
:
ty
::
Ty
<
'tcx
>
,
nested
:
&
[
ty
::
Ty
<
'tcx
>
]|
{
let
clause
=
builtin_impl_clause
(
tcx
,
ty
,
nested
,
trait_def_id
);
// Bind innermost bound vars that may exist in `ty` and `nested`.
clauses
.push
(
Clause
::
ForAll
(
ty
::
Binder
::
bind
(
clause
)));
};
match
&
ty
.sty
{
// Implementations provided in libcore.
ty
::
Bool
|
ty
::
Char
|
ty
::
Int
(
..
)
|
ty
::
Uint
(
..
)
|
ty
::
Float
(
..
)
|
ty
::
RawPtr
(
..
)
|
ty
::
Never
|
ty
::
Ref
(
_
,
_
,
hir
::
MutImmutable
)
=>
(),
// Non parametric primitive types.
ty
::
Infer
(
ty
::
IntVar
(
_
))
|
ty
::
Infer
(
ty
::
FloatVar
(
_
))
|
ty
::
Error
=>
push_builtin_impl
(
ty
,
&
[]),
// These implement `Copy`/`Clone` if their element types do.
&
ty
::
Array
(
_
,
length
)
=>
{
let
element_ty
=
generic_types
::
bound
(
tcx
,
0
);
push_builtin_impl
(
tcx
.mk_ty
(
ty
::
Array
(
element_ty
,
length
)),
&
[
element_ty
]);
}
&
ty
::
Tuple
(
type_list
)
=>
{
let
type_list
=
generic_types
::
type_list
(
tcx
,
type_list
.len
());
push_builtin_impl
(
tcx
.mk_ty
(
ty
::
Tuple
(
type_list
)),
&**
type_list
);
}
&
ty
::
Closure
(
def_id
,
..
)
=>
{
let
closure_ty
=
generic_types
::
closure
(
tcx
,
def_id
);
let
upvar_tys
:
Vec
<
_
>
=
match
&
closure_ty
.sty
{
ty
::
Closure
(
_
,
substs
)
=>
substs
.upvar_tys
(
def_id
,
tcx
)
.collect
(),
_
=>
bug!
(),
};
push_builtin_impl
(
closure_ty
,
&
upvar_tys
);
}
// These ones are always `Clone`.
ty
::
FnPtr
(
fn_ptr
)
=>
{
let
fn_ptr
=
fn_ptr
.skip_binder
();
let
fn_ptr
=
generic_types
::
fn_ptr
(
tcx
,
fn_ptr
.inputs_and_output
.len
(),
fn_ptr
.c_variadic
,
fn_ptr
.unsafety
,
fn_ptr
.abi
);
push_builtin_impl
(
fn_ptr
,
&
[]);
}
&
ty
::
FnDef
(
def_id
,
..
)
=>
{
push_builtin_impl
(
generic_types
::
fn_def
(
tcx
,
def_id
),
&
[]);
}
// These depend on whatever user-defined impls might exist.
ty
::
Adt
(
_
,
_
)
=>
(),
// Artificially trigger an ambiguity by adding two possible types to
// unify against.
ty
::
Infer
(
ty
::
TyVar
(
_
))
=>
{
push_builtin_impl
(
tcx
.types.i32
,
&
[]);
push_builtin_impl
(
tcx
.types.f32
,
&
[]);
}
ty
::
Projection
(
_
projection_ty
)
=>
{
// FIXME: add builtin impls from the associated type values found in
// trait impls of `projection_ty.trait_ref(tcx)`.
}
// The `Copy`/`Clone` bound can only come from the environment.
ty
::
Param
(
..
)
|
ty
::
Placeholder
(
..
)
|
ty
::
UnnormalizedProjection
(
..
)
|
ty
::
Opaque
(
..
)
=>
(),
// Definitely not `Copy`/`Clone`.
ty
::
Dynamic
(
..
)
|
ty
::
Foreign
(
..
)
|
ty
::
Generator
(
..
)
|
ty
::
Str
|
ty
::
Slice
(
..
)
|
ty
::
Ref
(
_
,
_
,
hir
::
MutMutable
)
=>
(),
ty
::
Bound
(
..
)
|
ty
::
GeneratorWitness
(
..
)
|
ty
::
Infer
(
ty
::
FreshTy
(
_
))
|
ty
::
Infer
(
ty
::
FreshIntTy
(
_
))
|
ty
::
Infer
(
ty
::
FreshFloatTy
(
_
))
=>
bug!
(
"unexpected type {:?}"
,
ty
),
}
}
src/librustc_traits/chalk_context/program_clauses/mod.rs
浏览文件 @
77c5f557
...
...
@@ -96,8 +96,27 @@ pub(super) fn program_clauses_impl(
);
}
if
Some
(
trait_predicate
.def_id
())
==
self
.infcx.tcx
.lang_items
()
.copy_trait
()
{
assemble_builtin_copy_clone_impls
(
self
.infcx.tcx
,
trait_predicate
.def_id
(),
trait_predicate
.self_ty
(),
&
mut
clauses
);
}
if
Some
(
trait_predicate
.def_id
())
==
self
.infcx.tcx
.lang_items
()
.clone_trait
()
{
// For all builtin impls, the conditions for `Copy` and
// `Clone` are the same.
assemble_builtin_copy_clone_impls
(
self
.infcx.tcx
,
trait_predicate
.def_id
(),
trait_predicate
.self_ty
(),
&
mut
clauses
);
}
// FIXME: we need to add special rules for other builtin impls:
// * `Copy` / `Clone`
// * `Generator`
// * `FnOnce` / `FnMut` / `Fn`
// * trait objects
...
...
src/test/run-pass/chalkify/builtin-copy-clone.rs
0 → 100644
浏览文件 @
77c5f557
// compile-flags: -Z chalk
// Test that `Clone` is correctly implemented for builtin types.
#[derive(Copy,
Clone)]
struct
S
(
i32
);
fn
test_clone
<
T
:
Clone
>
(
arg
:
T
)
{
let
_
=
arg
.clone
();
}
fn
test_copy
<
T
:
Copy
>
(
arg
:
T
)
{
let
_
=
arg
;
let
_
=
arg
;
}
fn
test_copy_clone
<
T
:
Copy
+
Clone
>
(
arg
:
T
)
{
test_copy
(
arg
);
test_clone
(
arg
);
}
fn
foo
()
{
}
fn
main
()
{
test_copy_clone
(
foo
);
let
f
:
fn
()
=
foo
;
test_copy_clone
(
f
);
// FIXME: add closures when they're considered WF
test_copy_clone
([
1
;
56
]);
test_copy_clone
((
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
));
test_copy_clone
((
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
true
,
'a'
,
1.1
));
test_copy_clone
(());
test_copy_clone
(((
1
,
1
),
(
1
,
1
,
1
),
(
1.1
,
1
,
1
,
'a'
),
()));
let
a
=
(
(
S
(
1
),
S
(
0
)),
(
(
S
(
0
),
S
(
0
),
S
(
1
)),
S
(
0
)
)
);
test_copy_clone
(
a
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录