@@ -10,6 +10,82 @@ use rustc::hir::def_id::DefId;
10
10
use crate :: lowering:: Lower ;
11
11
use crate :: generic_types;
12
12
13
+ crate fn assemble_builtin_unsize_impls < ' tcx > (
14
+ tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
15
+ unsize_def_id : DefId ,
16
+ source : ty:: Ty < ' tcx > ,
17
+ target : ty:: Ty < ' tcx > ,
18
+ clauses : & mut Vec < Clause < ' tcx > >
19
+ ) {
20
+ match ( & source. sty , & target. sty ) {
21
+ ( ty:: Dynamic ( data_a, ..) , ty:: Dynamic ( data_b, ..) ) => {
22
+ if data_a. principal_def_id ( ) != data_b. principal_def_id ( )
23
+ || data_b. auto_traits ( ) . any ( |b| data_a. auto_traits ( ) . all ( |a| a != b) )
24
+ {
25
+ return ;
26
+ }
27
+
28
+ // FIXME: rules for trait upcast
29
+ }
30
+
31
+ ( _, & ty:: Dynamic ( ..) ) => {
32
+ // FIXME: basically, we should have something like:
33
+ // ```
34
+ // forall<T> {
35
+ // Implemented(T: Unsize< for<...> dyn Trait<...> >) :-
36
+ // for<...> Implemented(T: Trait<...>).
37
+ // }
38
+ // ```
39
+ // The question is: how to correctly handle the higher-ranked
40
+ // `for<...>` binder in order to have a generic rule?
41
+ // (Having generic rules is useful for caching, as we may be able
42
+ // to turn this function and others into tcx queries later on).
43
+ }
44
+
45
+ ( ty:: Array ( _, length) , ty:: Slice ( _) ) => {
46
+ let ty_param = generic_types:: bound ( tcx, 0 ) ;
47
+ let array_ty = tcx. mk_ty ( ty:: Array ( ty_param, length) ) ;
48
+ let slice_ty = tcx. mk_ty ( ty:: Slice ( ty_param) ) ;
49
+
50
+ // `forall<T> { Implemented([T; N]: Unsize<[T]>). }`
51
+ let clause = ProgramClause {
52
+ goal : ty:: TraitPredicate {
53
+ trait_ref : ty:: TraitRef {
54
+ def_id : unsize_def_id,
55
+ substs : tcx. mk_substs_trait ( array_ty, & [ slice_ty. into ( ) ] )
56
+ } ,
57
+ } . lower ( ) ,
58
+ hypotheses : ty:: List :: empty ( ) ,
59
+ category : ProgramClauseCategory :: Other ,
60
+ } ;
61
+
62
+ clauses. push ( Clause :: ForAll ( ty:: Binder :: bind ( clause) ) ) ;
63
+ }
64
+
65
+ ( ty:: Infer ( ty:: TyVar ( _) ) , _) | ( _, ty:: Infer ( ty:: TyVar ( _) ) ) => {
66
+ // FIXME: ambiguous
67
+ }
68
+
69
+ ( ty:: Adt ( def_id_a, ..) , ty:: Adt ( def_id_b, ..) ) => {
70
+ if def_id_a != def_id_b {
71
+ return ;
72
+ }
73
+
74
+ // FIXME: rules for struct unsizing
75
+ }
76
+
77
+ ( & ty:: Tuple ( tys_a) , & ty:: Tuple ( tys_b) ) => {
78
+ if tys_a. len ( ) != tys_b. len ( ) {
79
+ return ;
80
+ }
81
+
82
+ // FIXME: rules for tuple unsizing
83
+ }
84
+
85
+ _ => ( ) ,
86
+ }
87
+ }
88
+
13
89
crate fn assemble_builtin_sized_impls < ' tcx > (
14
90
tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
15
91
sized_def_id : DefId ,
0 commit comments