@@ -157,17 +157,63 @@ let check_comptype (c : context) (ct : comptype) at =
157157 check_resulttype c ts1 at;
158158 check_resulttype c ts2 at
159159
160- (* TODO: Make sure the describes and descriptor clauses match. *)
161160let check_desctype (c : context ) (dt : desctype ) at =
162- match dt with
163- | DescT (ht1 , ht2 , ct ) -> check_comptype c ct at
164-
165- let check_desctype_sub (c : context ) (dt : desctype ) (dti : desctype ) x xi at =
166- (* TODO: check rules *)
161+ (match dt with
162+ | DescT (None, None, _ ) -> ()
163+ | DescT (_ , _ , StructT _ ) -> ()
164+ | DescT (_ , Some _ , _ ) ->
165+ error at " descriptor type must be a struct"
166+ | DescT (Some _ , _ , _ ) ->
167+ error at " described type must be a struct" );
167168 let DescT (_, _, ct) = dt in
168- let DescT (_, _, cti) = dti in
169- require (match_comptype c.types ct cti) at (" sub type " ^ I32. to_string_u x ^
170- " does not match super type " ^ I32. to_string_u xi)
169+ check_comptype c ct at
170+
171+ let check_desctype_sub (c : context ) (dt : desctype ) (dt' : desctype ) x x' at =
172+ let DefT (rt, _) = type_ c (x @@ at) in
173+ let DefT (rt', _) = type_ c (x' @@ at) in
174+ let DescT (ut1, ut2, ct) = dt in
175+ let DescT (ut1', ut2', ct') = dt' in
176+ match ut1, ut1' with
177+ | (Some ut1 , Some ut1' ) ->
178+ require (match_typeuse c.types ut1 ut1' rt rt') at (" described type " ^
179+ string_of_typeuse ut1 ^ " does not match " ^ string_of_typeuse ut1')
180+ | (Some _ , None ) | (None, Some _ ) ->
181+ error at (" sub type " ^ I32. to_string_u x ^ " does not match super type " ^
182+ I32. to_string_u x')
183+ | (None, None) -> () ;
184+ match ut2, ut2' with
185+ | (Some ut2 , Some ut2' ) ->
186+ require (match_typeuse c.types ut2 ut2' rt rt') at (" descriptor type " ^
187+ string_of_typeuse ut2 ^ " does not match " ^ string_of_typeuse ut2')
188+ | (None, Some _ ) ->
189+ error at (" sub type " ^ I32. to_string_u x ^ " does not match super type " ^
190+ I32. to_string_u x')
191+ | (Some _ , None ) | (None, None) -> () ;
192+ require (match_comptype c.types ct ct') at (" sub type " ^ I32. to_string_u x ^
193+ " does not match super type " ^ I32. to_string_u x')
194+
195+ let check_descriptors (dts : deftype list ) at =
196+ List. iter (fun dt ->
197+ let DefT ((RecT dts), x) = dt in
198+ let SubT (_, _, DescT (ut1, ut2, _)) = Lib.List32. nth dts x in
199+ Option. iter (fun ut ->
200+ match ut with
201+ | Rec x' ->
202+ let SubT (_, _, DescT (_, ut', _)) = Lib.List32. nth dts x' in
203+ require (ut' = Some (Rec x)) at
204+ " described type is not described by descriptor" ;
205+ require (x' < x) at " forward use of described type"
206+ | _ -> error at " described type is outside rec group"
207+ ) ut1;
208+ Option. iter (fun ut ->
209+ match ut with
210+ | Rec x' ->
211+ let SubT (_, _, DescT (ut', _, _)) = Lib.List32. nth dts x' in
212+ require (ut' = Some (Rec x)) at
213+ " type is not described by its descriptor" ;
214+ | _ -> error at " descriptor type is outside rec group"
215+ ) ut2
216+ ) dts
171217
172218let check_subtype (c : context ) (sut : subtype ) at =
173219 let SubT (_fin, uts, dt) = sut in
@@ -189,7 +235,9 @@ let check_subtype_sub (c : context) (sut : subtype) x at =
189235let check_rectype (c : context ) (rt : rectype ) at : context =
190236 let RecT sts = rt in
191237 let x = Lib.List32. length c.types in
192- let c' = {c with types = c.types @ roll_deftypes x rt} in
238+ let dts = roll_deftypes x rt in
239+ check_descriptors dts at;
240+ let c' = {c with types = c.types @ dts} in
193241 List. iter (fun st -> check_subtype c' st at) sts;
194242 Lib.List32. iteri
195243 (fun i st -> check_subtype_sub c' st (Int32. add x i) at) sts;
0 commit comments