@@ -6,10 +6,42 @@ use rustc::traits::{
66} ;
77use rustc:: ty;
88use rustc:: ty:: subst:: { InternalSubsts , Subst } ;
9+ use rustc:: hir;
910use rustc:: hir:: def_id:: DefId ;
1011use crate :: lowering:: Lower ;
1112use crate :: generic_types;
1213
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+
1345crate fn assemble_builtin_unsize_impls < ' tcx > (
1446 tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
1547 unsize_def_id : DefId ,
@@ -93,26 +125,7 @@ crate fn assemble_builtin_sized_impls<'tcx>(
93125 clauses : & mut Vec < Clause < ' tcx > >
94126) {
95127 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) ;
116129 // Bind innermost bound vars that may exist in `ty` and `nested`.
117130 clauses. push ( Clause :: ForAll ( ty:: Binder :: bind ( clause) ) ) ;
118131 } ;
@@ -124,6 +137,8 @@ crate fn assemble_builtin_sized_impls<'tcx>(
124137 ty:: Int ( ..) |
125138 ty:: Uint ( ..) |
126139 ty:: Float ( ..) |
140+ ty:: Infer ( ty:: IntVar ( _) ) |
141+ ty:: Infer ( ty:: FloatVar ( _) ) |
127142 ty:: Error |
128143 ty:: Never => push_builtin_impl ( ty, & [ ] ) ,
129144
@@ -175,14 +190,11 @@ crate fn assemble_builtin_sized_impls<'tcx>(
175190 push_builtin_impl ( adt, & sized_constraint) ;
176191 }
177192
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 ( _) ) => {
182196 push_builtin_impl ( tcx. types . i32 , & [ ] ) ;
183- push_builtin_impl ( tcx. types . u32 , & [ ] ) ;
184197 push_builtin_impl ( tcx. types . f32 , & [ ] ) ;
185- push_builtin_impl ( tcx. types . f64 , & [ ] ) ;
186198 }
187199
188200 ty:: Projection ( _projection_ty) => {
@@ -203,6 +215,108 @@ crate fn assemble_builtin_sized_impls<'tcx>(
203215 ty:: Opaque ( ..) => ( ) ,
204216
205217 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) ,
207321 }
208322}
0 commit comments