@@ -3,6 +3,7 @@ package vibes
33import (
44 "fmt"
55 "reflect"
6+ "sort"
67 "strings"
78)
89
@@ -257,55 +258,93 @@ func resolveEnumType(ty *TypeExpr, ctx typeContext) (*EnumDef, error) {
257258 if ty .Kind != TypeEnum {
258259 return nil , fmt .Errorf ("unknown type %s" , ty .Name )
259260 }
260- if enumDef , ok := lookupEnumDef (ctx .owner , ty .Name ); ok {
261+ if enumDef , ok , err := lookupEnumDef (ctx .owner , ty .Name ); err != nil {
262+ return nil , err
263+ } else if ok {
261264 return enumDef , nil
262265 }
263- if enumDef , ok := lookupEnumInEnv (ctx .env , ty .Name ); ok {
266+ if enumDef , ok , err := lookupEnumInEnv (ctx .env , ty .Name ); err != nil {
267+ return nil , err
268+ } else if ok {
264269 return enumDef , nil
265270 }
266271 if ctx .fallback != ctx .env {
267- if enumDef , ok := lookupEnumInEnv (ctx .fallback , ty .Name ); ok {
272+ if enumDef , ok , err := lookupEnumInEnv (ctx .fallback , ty .Name ); err != nil {
273+ return nil , err
274+ } else if ok {
268275 return enumDef , nil
269276 }
270277 }
271278 return nil , fmt .Errorf ("unknown type %s" , ty .Name )
272279}
273280
274- func lookupEnumDef (owner * Script , name string ) (* EnumDef , bool ) {
281+ func lookupEnumDef (owner * Script , name string ) (* EnumDef , bool , error ) {
275282 if owner == nil || len (owner .enums ) == 0 {
276- return nil , false
283+ return nil , false , nil
277284 }
278285 if enumDef , ok := owner .enums [name ]; ok {
279- return enumDef , true
286+ return enumDef , true , nil
280287 }
288+ var match * EnumDef
289+ matches := make ([]string , 0 , 2 )
281290 for enumName , enumDef := range owner .enums {
282- if strings .EqualFold (enumName , name ) {
283- return enumDef , true
291+ if ! strings .EqualFold (enumName , name ) {
292+ continue
293+ }
294+ matches = append (matches , enumName )
295+ if match == nil {
296+ match = enumDef
297+ continue
284298 }
299+ if match != enumDef {
300+ return nil , false , ambiguousEnumTypeError (name , matches )
301+ }
302+ }
303+ if match != nil {
304+ return match , true , nil
285305 }
286- return nil , false
306+ return nil , false , nil
287307}
288308
289- func lookupEnumInEnv (env * Env , name string ) (* EnumDef , bool ) {
309+ func lookupEnumInEnv (env * Env , name string ) (* EnumDef , bool , error ) {
290310 for scope := env ; scope != nil ; scope = scope .parent {
291- if enumDef , ok := lookupEnumValue (scope .values , name ); ok {
292- return enumDef , true
311+ if enumDef , ok , err := lookupEnumValue (scope .values , name ); err != nil {
312+ return nil , false , err
313+ } else if ok {
314+ return enumDef , true , nil
293315 }
294316 }
295- return nil , false
317+ return nil , false , nil
296318}
297319
298- func lookupEnumValue (values map [string ]Value , name string ) (* EnumDef , bool ) {
320+ func lookupEnumValue (values map [string ]Value , name string ) (* EnumDef , bool , error ) {
299321 if val , ok := values [name ]; ok && val .Kind () == KindEnum {
300- return val .Enum (), true
322+ return val .Enum (), true , nil
301323 }
324+ var match * EnumDef
325+ matches := make ([]string , 0 , 2 )
302326 for key , val := range values {
303327 if key == name || ! strings .EqualFold (key , name ) || val .Kind () != KindEnum {
304328 continue
305329 }
306- return val .Enum (), true
330+ matches = append (matches , key )
331+ if match == nil {
332+ match = val .Enum ()
333+ continue
334+ }
335+ if match != val .Enum () {
336+ return nil , false , ambiguousEnumTypeError (name , matches )
337+ }
338+ }
339+ if match != nil {
340+ return match , true , nil
307341 }
308- return nil , false
342+ return nil , false , nil
343+ }
344+
345+ func ambiguousEnumTypeError (name string , matches []string ) error {
346+ sort .Strings (matches )
347+ return fmt .Errorf ("ambiguous enum type %s matches %s" , name , strings .Join (matches , ", " ))
309348}
310349
311350func errorAsTypeMismatch (err error , target * * typeMismatchError ) bool {
0 commit comments