@@ -39,8 +39,6 @@ func (d *downcast) Cast(from super.Value, to super.Type) (super.Value, bool) {
3939}
4040
4141func (d * downcast ) downcast (typ super.Type , bytes scode.Bytes , to super.Type ) (super.Value , * super.Value ) {
42- //fmt.Println("DOWNCAST", sup.String(super.NewValue(typ, bytes)), "TO", sup.String(to))
43- // XXX typ, bytes = deunion(typ, bytes)
4442 if _ , ok := to .(* super.TypeUnion ); ! ok {
4543 if fusionType , ok := typ .(* super.TypeFusion ); ok {
4644 superBytes , subtype := fusionType .Deref (d .sctx , bytes )
@@ -187,7 +185,6 @@ func (d *downcast) toUnion(typ super.Type, bytes scode.Bytes, to *super.TypeUnio
187185 typ , bytes = deunion (typ , bytes )
188186 return d .downcast (typ , bytes , to )
189187 }
190- //fmt.Println("FAIL")
191188 return super.Value {}, d .errSubtype (typ , bytes , to )
192189 }
193190 val , errVal := d .downcast (typ , bytes , to .Types [tag ])
@@ -201,6 +198,19 @@ func (d *downcast) toUnion(typ super.Type, bytes scode.Bytes, to *super.TypeUnio
201198 return super .NewValue (to , b .Bytes ().Body ()), nil
202199}
203200
201+ // subTypeOf finds the tag in the union array types that this value should be
202+ // downcast to. If the child value is a fusion value, then the type must match
203+ // the subtype of the fusion value. Otherwise, the child wasn't fused, and by
204+ // definition of a fusion type, one of the union types must exactly match the
205+ // child type.
206+ func (d * downcast ) subTypeOf (typ super.Type , bytes scode.Bytes , types []super.Type ) (int , super.Type , []byte ) {
207+ if fusionType , ok := typ .(* super.TypeFusion ); ok {
208+ superBytes , subtype := fusionType .Deref (d .sctx , bytes )
209+ return slices .Index (types , subtype ), fusionType .Type , superBytes
210+ }
211+ return slices .Index (types , typ ), typ , bytes
212+ }
213+
204214func (d * downcast ) toError (typ super.Type , bytes scode.Bytes , to * super.TypeError ) (super.Value , * super.Value ) {
205215 if errorType , ok := typ .(* super.TypeError ); ok {
206216 body , errVal := d .downcast (errorType .Type , bytes , to .Type )
@@ -213,76 +223,20 @@ func (d *downcast) toError(typ super.Type, bytes scode.Bytes, to *super.TypeErro
213223}
214224
215225func (d * downcast ) toNamed (typ super.Type , bytes scode.Bytes , to * super.TypeNamed ) (super.Value , * super.Value ) {
216- //fmt.Println("TO NAMED", sup.String(super.NewValue(typ, bytes)), "TO", sup.String(to))
217- /*
218- fromType, ok := typ.(*super.TypeNamed)
219- if !ok {
220- if typ == to.Type {
221- val, errVal := d.downcast(typ, bytes, to.Type)
222- if errVal != nil {
223- //fmt.Println("THIRD MISS")
224- return super.Value{}, errVal
225- }
226- return super.NewValue(to, val.Bytes()), errVal
227- }
228- if unionType, ok := to.Type.(*super.TypeUnion); ok && unionType.TagOf(typ) >= 0 {
229- val, errVal := d.downcast(typ, bytes, to.Type)
230- if errVal != nil {
231- //fmt.Println("THIRD MISS")
232- return super.Value{}, errVal
233- }
234- return super.NewValue(to, val.Bytes()), errVal
235- }
236- //fmt.Println("FIRST MISS", sup.String(super.NewValue(typ, bytes)), sup.String(to))
237- return super.Value{}, d.errMismatch(typ, bytes, to)
238- }
239- val, errVal := d.downcast(fromType.Type, bytes, to.Type)
240- if errVal != nil {
241- //fmt.Println("SECOND MISS")
242- return super.Value{}, errVal
243- }
244- return super.NewValue(to, val.Bytes()), errVal
245- */
246226 if unionType , ok := typ .(* super.TypeUnion ); ok {
247227 typ , bytes = deunion (typ , bytes )
248228 // If we are casting a union type to a named, we need to look through the
249229 // union for the named type in question since type fusion fuses named
250230 // types by name. Then when we find the name, we need to form the subtype
251- // from the union options present. XXX devise a torture test that
252- // reconstruct nested unions from the flattened named union...?
231+ // from the union options present.
253232 for _ , t := range unionType .Types {
254- //fmt.Println("TO NAMED FROM UNION TRY", sup.String(t))
255233 if named , ok := t .(* super.TypeNamed ); ok && named .Name == to .Name {
256- //fmt.Println("TO NAMED FROM UNION MATCH", sup.String(t))
257234 typ , bytes = deunion (typ , bytes )
258235 return super .NewValue (to , bytes ), nil
259- // val, errVal := d.downcast(typ, bytes, to.Type)
260- // if errVal != nil {
261- // return super.Value{}, errVal
262- // }
263- // return super.NewValue(to, val.Bytes()), nil
264236 }
265-
266237 }
267238 return super.Value {}, d .errMismatch (typ , bytes , to )
268239 }
269- /*
270- fromType, ok := typ.(*super.TypeNamed)
271- if !ok {
272- if unionType, ok := typ.(*super.TypeUnion); ok {
273- if unionType.TagOf(to) >= 0 {
274- typ, bytes = deunion(typ, bytes)
275- val, errVal := d.downcast(typ, bytes, to)
276- if errVal != nil {
277- return super.Value{}, errVal
278- }
279- return super.NewValue(to, val.Bytes()), errVal
280- }
281- }
282- //fmt.Println("MISS", sup.String(typ))
283- return super.Value{}, d.errMismatch(typ, bytes, to)
284- }
285- */
286240 if fromType , ok := typ .(* super.TypeNamed ); ok {
287241 if fromType .Name != to .Name {
288242 return super.Value {}, d .errMismatch (typ , bytes , to )
@@ -301,35 +255,9 @@ func (d *downcast) toNamed(typ super.Type, bytes scode.Bytes, to *super.TypeName
301255}
302256
303257func (d * downcast ) errMismatch (typ super.Type , bytes []byte , to super.Type ) * super.Value {
304- //debug.PrintStack()
305258 return d .sctx .WrapError ("downcast: type mismatch to " + sup .FormatType (to ), super .NewValue (typ , bytes )).Ptr ()
306259}
307260
308261func (d * downcast ) errSubtype (typ super.Type , bytes []byte , to super.Type ) * super.Value {
309- //debug.PrintStack()
310262 return d .sctx .WrapError ("downcast: invalid subtype " + sup .FormatType (to ), super .NewValue (typ , bytes )).Ptr ()
311263}
312-
313- // subTypeOf finds the tag in the union array types that this value should be
314- // downcast to. If the child value is a fusion value, then the type must match
315- // the subtype of the fusion value. Otherwise, the child wasn't fused, and by
316- // definition of a fusion type, one of the union type must exactly match the
317- // child type.
318- func (d * downcast ) subTypeOf (typ super.Type , bytes scode.Bytes , types []super.Type ) (int , super.Type , []byte ) {
319- if fusionType , ok := typ .(* super.TypeFusion ); ok {
320- superBytes , subtype := fusionType .Deref (d .sctx , bytes )
321- return slices .Index (types , subtype ), fusionType .Type , superBytes
322- }
323- //XXX now that we are going to fuse by name inside of unions, we need
324- // to search through the types for a name match then recursively search
325- // for the piece that matches. XXX hmm maybe this isn't right as this
326- // search is handled by toNamed
327- if tag := slices .Index (types , typ ); tag >= 0 {
328- return tag , typ , bytes
329- }
330- //fmt.Println("SUBTYPE OF", sup.String(typ), sup.String(d.sctx.LookupTypeUnion(types)))
331- return - 1 , typ , bytes //XXX
332- // return slices.IndexFunc(types, func(t super.Type) bool {
333- // return typ); tag >= 0 {
334-
335- }
0 commit comments