@@ -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
} ;
@@ -124,6 +137,8 @@ crate fn assemble_builtin_sized_impls<'tcx>(
124
137
ty:: Int ( ..) |
125
138
ty:: Uint ( ..) |
126
139
ty:: Float ( ..) |
140
+ ty:: Infer ( ty:: IntVar ( _) ) |
141
+ ty:: Infer ( ty:: FloatVar ( _) ) |
127
142
ty:: Error |
128
143
ty:: Never => push_builtin_impl ( ty, & [ ] ) ,
129
144
@@ -175,14 +190,11 @@ crate fn assemble_builtin_sized_impls<'tcx>(
175
190
push_builtin_impl ( adt, & sized_constraint) ;
176
191
}
177
192
178
- // Artificially trigger an ambiguity.
179
- ty:: Infer ( ..) => {
180
- // Everybody can find at least two types to unify against:
181
- // general ty vars, int vars and float vars.
193
+ // Artificially trigger an ambiguity by adding two possible types to
194
+ // unify against.
195
+ ty:: Infer ( ty:: TyVar ( _) ) => {
182
196
push_builtin_impl ( tcx. types . i32 , & [ ] ) ;
183
- push_builtin_impl ( tcx. types . u32 , & [ ] ) ;
184
197
push_builtin_impl ( tcx. types . f32 , & [ ] ) ;
185
- push_builtin_impl ( tcx. types . f64 , & [ ] ) ;
186
198
}
187
199
188
200
ty:: Projection ( _projection_ty) => {
@@ -203,6 +215,108 @@ crate fn assemble_builtin_sized_impls<'tcx>(
203
215
ty:: Opaque ( ..) => ( ) ,
204
216
205
217
ty:: Bound ( ..) |
206
- ty:: GeneratorWitness ( ..) => bug ! ( "unexpected type {:?}" , ty) ,
218
+ ty:: GeneratorWitness ( ..) |
219
+ ty:: Infer ( ty:: FreshTy ( _) ) |
220
+ ty:: Infer ( ty:: FreshIntTy ( _) ) |
221
+ ty:: Infer ( ty:: FreshFloatTy ( _) ) => bug ! ( "unexpected type {:?}" , ty) ,
222
+ }
223
+ }
224
+
225
+ crate fn assemble_builtin_copy_clone_impls < ' tcx > (
226
+ tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
227
+ trait_def_id : DefId ,
228
+ ty : ty:: Ty < ' tcx > ,
229
+ clauses : & mut Vec < Clause < ' tcx > >
230
+ ) {
231
+ let mut push_builtin_impl = |ty : ty:: Ty < ' tcx > , nested : & [ ty:: Ty < ' tcx > ] | {
232
+ let clause = builtin_impl_clause ( tcx, ty, nested, trait_def_id) ;
233
+ // Bind innermost bound vars that may exist in `ty` and `nested`.
234
+ clauses. push ( Clause :: ForAll ( ty:: Binder :: bind ( clause) ) ) ;
235
+ } ;
236
+
237
+ match & ty. sty {
238
+ // Implementations provided in libcore.
239
+ ty:: Bool |
240
+ ty:: Char |
241
+ ty:: Int ( ..) |
242
+ ty:: Uint ( ..) |
243
+ ty:: Float ( ..) |
244
+ ty:: RawPtr ( ..) |
245
+ ty:: Never |
246
+ ty:: Ref ( _, _, hir:: MutImmutable ) => ( ) ,
247
+
248
+ // Non parametric primitive types.
249
+ ty:: Infer ( ty:: IntVar ( _) ) |
250
+ ty:: Infer ( ty:: FloatVar ( _) ) |
251
+ ty:: Error => push_builtin_impl ( ty, & [ ] ) ,
252
+
253
+ // These implement `Copy`/`Clone` if their element types do.
254
+ & ty:: Array ( _, length) => {
255
+ let element_ty = generic_types:: bound ( tcx, 0 ) ;
256
+ push_builtin_impl ( tcx. mk_ty ( ty:: Array ( element_ty, length) ) , & [ element_ty] ) ;
257
+ }
258
+ & ty:: Tuple ( type_list) => {
259
+ let type_list = generic_types:: type_list ( tcx, type_list. len ( ) ) ;
260
+ push_builtin_impl ( tcx. mk_ty ( ty:: Tuple ( type_list) ) , & * * type_list) ;
261
+ }
262
+ & ty:: Closure ( def_id, ..) => {
263
+ let closure_ty = generic_types:: closure ( tcx, def_id) ;
264
+ let upvar_tys: Vec < _ > = match & closure_ty. sty {
265
+ ty:: Closure ( _, substs) => substs. upvar_tys ( def_id, tcx) . collect ( ) ,
266
+ _ => bug ! ( ) ,
267
+ } ;
268
+ push_builtin_impl ( closure_ty, & upvar_tys) ;
269
+ }
270
+
271
+ // These ones are always `Clone`.
272
+ ty:: FnPtr ( fn_ptr) => {
273
+ let fn_ptr = fn_ptr. skip_binder ( ) ;
274
+ let fn_ptr = generic_types:: fn_ptr (
275
+ tcx,
276
+ fn_ptr. inputs_and_output . len ( ) ,
277
+ fn_ptr. c_variadic ,
278
+ fn_ptr. unsafety ,
279
+ fn_ptr. abi
280
+ ) ;
281
+ push_builtin_impl ( fn_ptr, & [ ] ) ;
282
+ }
283
+ & ty:: FnDef ( def_id, ..) => {
284
+ push_builtin_impl ( generic_types:: fn_def ( tcx, def_id) , & [ ] ) ;
285
+ }
286
+
287
+ // These depend on whatever user-defined impls might exist.
288
+ ty:: Adt ( _, _) => ( ) ,
289
+
290
+ // Artificially trigger an ambiguity by adding two possible types to
291
+ // unify against.
292
+ ty:: Infer ( ty:: TyVar ( _) ) => {
293
+ push_builtin_impl ( tcx. types . i32 , & [ ] ) ;
294
+ push_builtin_impl ( tcx. types . f32 , & [ ] ) ;
295
+ }
296
+
297
+ ty:: Projection ( _projection_ty) => {
298
+ // FIXME: add builtin impls from the associated type values found in
299
+ // trait impls of `projection_ty.trait_ref(tcx)`.
300
+ }
301
+
302
+ // The `Copy`/`Clone` bound can only come from the environment.
303
+ ty:: Param ( ..) |
304
+ ty:: Placeholder ( ..) |
305
+ ty:: UnnormalizedProjection ( ..) |
306
+ ty:: Opaque ( ..) => ( ) ,
307
+
308
+ // Definitely not `Copy`/`Clone`.
309
+ ty:: Dynamic ( ..) |
310
+ ty:: Foreign ( ..) |
311
+ ty:: Generator ( ..) |
312
+ ty:: Str |
313
+ ty:: Slice ( ..) |
314
+ ty:: Ref ( _, _, hir:: MutMutable ) => ( ) ,
315
+
316
+ ty:: Bound ( ..) |
317
+ ty:: GeneratorWitness ( ..) |
318
+ ty:: Infer ( ty:: FreshTy ( _) ) |
319
+ ty:: Infer ( ty:: FreshIntTy ( _) ) |
320
+ ty:: Infer ( ty:: FreshFloatTy ( _) ) => bug ! ( "unexpected type {:?}" , ty) ,
207
321
}
208
322
}
0 commit comments