@@ -6,10 +6,42 @@ use rustc::traits::{
6
6
} ;
7
7
use rustc:: ty;
8
8
use rustc:: ty:: subst:: { InternalSubsts , Subst } ;
9
+ use rustc:: hir;
9
10
use rustc:: hir:: def_id:: DefId ;
10
11
use crate :: lowering:: Lower ;
11
12
use crate :: generic_types;
12
13
14
+ /// Returns a predicate of the form
15
+ /// `Implemented(ty: Trait) :- Implemented(nested: Trait)...`
16
+ /// where `Trait` is specified by `trait_def_id`.
17
+ fn builtin_impl_clause (
18
+ tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
19
+ ty : ty:: Ty < ' tcx > ,
20
+ nested : & [ ty:: Ty < ' tcx > ] ,
21
+ trait_def_id : DefId
22
+ ) -> ProgramClause < ' tcx > {
23
+ ProgramClause {
24
+ goal : ty:: TraitPredicate {
25
+ trait_ref : ty:: TraitRef {
26
+ def_id : trait_def_id,
27
+ substs : tcx. mk_substs_trait ( ty, & [ ] ) ,
28
+ } ,
29
+ } . lower ( ) ,
30
+ hypotheses : tcx. mk_goals (
31
+ nested. iter ( )
32
+ . cloned ( )
33
+ . map ( |nested_ty| ty:: TraitRef {
34
+ def_id : trait_def_id,
35
+ substs : tcx. mk_substs_trait ( nested_ty, & [ ] ) ,
36
+ } )
37
+ . map ( |trait_ref| ty:: TraitPredicate { trait_ref } )
38
+ . map ( |pred| GoalKind :: DomainGoal ( pred. lower ( ) ) )
39
+ . map ( |goal_kind| tcx. mk_goal ( goal_kind) )
40
+ ) ,
41
+ category : ProgramClauseCategory :: Other ,
42
+ }
43
+ }
44
+
13
45
crate fn assemble_builtin_unsize_impls < ' tcx > (
14
46
tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
15
47
unsize_def_id : DefId ,
@@ -93,26 +125,7 @@ crate fn assemble_builtin_sized_impls<'tcx>(
93
125
clauses : & mut Vec < Clause < ' tcx > >
94
126
) {
95
127
let mut push_builtin_impl = |ty : ty:: Ty < ' tcx > , nested : & [ ty:: Ty < ' tcx > ] | {
96
- let clause = ProgramClause {
97
- goal : ty:: TraitPredicate {
98
- trait_ref : ty:: TraitRef {
99
- def_id : sized_def_id,
100
- substs : tcx. mk_substs_trait ( ty, & [ ] ) ,
101
- } ,
102
- } . lower ( ) ,
103
- hypotheses : tcx. mk_goals (
104
- nested. iter ( )
105
- . cloned ( )
106
- . map ( |nested_ty| ty:: TraitRef {
107
- def_id : sized_def_id,
108
- substs : tcx. mk_substs_trait ( nested_ty, & [ ] ) ,
109
- } )
110
- . map ( |trait_ref| ty:: TraitPredicate { trait_ref } )
111
- . map ( |pred| GoalKind :: DomainGoal ( pred. lower ( ) ) )
112
- . map ( |goal_kind| tcx. mk_goal ( goal_kind) )
113
- ) ,
114
- category : ProgramClauseCategory :: Other ,
115
- } ;
128
+ let clause = builtin_impl_clause ( tcx, ty, nested, sized_def_id) ;
116
129
// Bind innermost bound vars that may exist in `ty` and `nested`.
117
130
clauses. push ( Clause :: ForAll ( ty:: Binder :: bind ( clause) ) ) ;
118
131
} ;
@@ -206,3 +219,99 @@ crate fn assemble_builtin_sized_impls<'tcx>(
206
219
ty:: GeneratorWitness ( ..) => bug ! ( "unexpected type {:?}" , ty) ,
207
220
}
208
221
}
222
+
223
+ crate fn assemble_builtin_copy_clone_impls < ' tcx > (
224
+ tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
225
+ trait_def_id : DefId ,
226
+ ty : ty:: Ty < ' tcx > ,
227
+ clauses : & mut Vec < Clause < ' tcx > >
228
+ ) {
229
+ let mut push_builtin_impl = |ty : ty:: Ty < ' tcx > , nested : & [ ty:: Ty < ' tcx > ] | {
230
+ let clause = builtin_impl_clause ( tcx, ty, nested, trait_def_id) ;
231
+ // Bind innermost bound vars that may exist in `ty` and `nested`.
232
+ clauses. push ( Clause :: ForAll ( ty:: Binder :: bind ( clause) ) ) ;
233
+ } ;
234
+
235
+ match & ty. sty {
236
+ // Implementations provided in libcore.
237
+ ty:: Bool |
238
+ ty:: Char |
239
+ ty:: Int ( ..) |
240
+ ty:: Uint ( ..) |
241
+ ty:: Float ( ..) |
242
+ ty:: RawPtr ( ..) |
243
+ ty:: Never |
244
+ ty:: Ref ( _, _, hir:: MutImmutable ) => ( ) ,
245
+
246
+ // Non parametric primitive type.
247
+ ty:: Error => push_builtin_impl ( ty, & [ ] ) ,
248
+
249
+ // These implement `Copy`/`Clone` if their element types do.
250
+ & ty:: Array ( _, length) => {
251
+ let element_ty = generic_types:: bound ( tcx, 0 ) ;
252
+ push_builtin_impl ( tcx. mk_ty ( ty:: Array ( element_ty, length) ) , & [ element_ty] ) ;
253
+ }
254
+ & ty:: Tuple ( type_list) => {
255
+ let type_list = generic_types:: type_list ( tcx, type_list. len ( ) ) ;
256
+ push_builtin_impl ( tcx. mk_ty ( ty:: Tuple ( type_list) ) , & * * type_list) ;
257
+ }
258
+ & ty:: Closure ( def_id, ..) => {
259
+ let closure_ty = generic_types:: closure ( tcx, def_id) ;
260
+ let upvar_tys: Vec < _ > = match & closure_ty. sty {
261
+ ty:: Closure ( _, substs) => substs. upvar_tys ( def_id, tcx) . collect ( ) ,
262
+ _ => bug ! ( ) ,
263
+ } ;
264
+ push_builtin_impl ( closure_ty, & upvar_tys) ;
265
+ }
266
+
267
+ // These ones are always `Clone`.
268
+ ty:: FnPtr ( fn_ptr) => {
269
+ let fn_ptr = fn_ptr. skip_binder ( ) ;
270
+ let fn_ptr = generic_types:: fn_ptr (
271
+ tcx,
272
+ fn_ptr. inputs_and_output . len ( ) ,
273
+ fn_ptr. c_variadic ,
274
+ fn_ptr. unsafety ,
275
+ fn_ptr. abi
276
+ ) ;
277
+ push_builtin_impl ( fn_ptr, & [ ] ) ;
278
+ }
279
+ & ty:: FnDef ( def_id, ..) => {
280
+ push_builtin_impl ( generic_types:: fn_def ( tcx, def_id) , & [ ] ) ;
281
+ }
282
+
283
+ // These depend on whatever user-defined impls might exist.
284
+ ty:: Adt ( _, _) => ( ) ,
285
+
286
+ // int vars and float vars are always `Copy`.
287
+ // Other vars will trigger an ambiguity.
288
+ ty:: Infer ( ..) => {
289
+ push_builtin_impl ( tcx. types . i32 , & [ ] ) ;
290
+ push_builtin_impl ( tcx. types . u32 , & [ ] ) ;
291
+ push_builtin_impl ( tcx. types . f32 , & [ ] ) ;
292
+ push_builtin_impl ( tcx. types . f64 , & [ ] ) ;
293
+ }
294
+
295
+ ty:: Projection ( _projection_ty) => {
296
+ // FIXME: add builtin impls from the associated type values found in
297
+ // trait impls of `projection_ty.trait_ref(tcx)`.
298
+ }
299
+
300
+ // The `Copy`/`Clone` bound can only come from the environment.
301
+ ty:: Param ( ..) |
302
+ ty:: Placeholder ( ..) |
303
+ ty:: UnnormalizedProjection ( ..) |
304
+ ty:: Opaque ( ..) => ( ) ,
305
+
306
+ // Definitely not `Copy`/`Clone`.
307
+ ty:: Dynamic ( ..) |
308
+ ty:: Foreign ( ..) |
309
+ ty:: Generator ( ..) |
310
+ ty:: Str |
311
+ ty:: Slice ( ..) |
312
+ ty:: Ref ( _, _, hir:: MutMutable ) => ( ) ,
313
+
314
+ ty:: Bound ( ..) |
315
+ ty:: GeneratorWitness ( ..) => bug ! ( "unexpected type {:?}" , ty) ,
316
+ }
317
+ }
0 commit comments