@@ -10,6 +10,82 @@ use rustc::hir::def_id::DefId;
1010use crate :: lowering:: Lower ;
1111use crate :: generic_types;
1212
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+
1389crate fn assemble_builtin_sized_impls < ' tcx > (
1490 tcx : ty:: TyCtxt < ' _ , ' _ , ' tcx > ,
1591 sized_def_id : DefId ,
0 commit comments