// parentEnum is nil if not in enum func (v *TypeCheck) CheckTupleLiteral(s *SemanticAnalyzer, lit *ast.TupleLiteral) { tupleType, ok := lit.GetType().BaseType.ActualType().(ast.TupleType) if !ok { panic("Type of tuple literal was not `TupleType`") } memberTypes := tupleType.Members if len(lit.Members) != len(memberTypes) { s.Err(lit, "Invalid amount of entries in tuple") } var gcon *ast.GenericContext if lit.ParentEnumLiteral != nil { gcon = ast.NewGenericContext(lit.ParentEnumLiteral.GetType().BaseType.ActualType().(ast.EnumType).GenericParameters, lit.ParentEnumLiteral.Type.GenericArguments) } else { gcon = ast.NewGenericContext(nil, nil) } for idx, mem := range lit.Members { expectType(s, mem, gcon.Get(memberTypes[idx]), &mem) } }
// if outer is not nil, this function does not add the current function gcon as outer, as it assumes it is already there func (v *Codegen) typeRefToLLVMTypeWithOuter(typ *ast.TypeReference, outer *ast.GenericContext) llvm.Type { var gcon *ast.GenericContext if len(typ.GenericArguments) > 0 { gcon = ast.NewGenericContextFromTypeReference(typ) } else { gcon = ast.NewGenericContext(nil, nil) } if outer != nil { gcon.Outer = outer } else if v.inFunction() { gcon.Outer = v.currentFunction().gcon } return v.typeRefToLLVMTypeWithGenericContext(typ, gcon) }
func (v *TypeCheck) CheckCompositeLiteral(s *SemanticAnalyzer, lit *ast.CompositeLiteral) { gcon := ast.NewGenericContext([]*ast.SubstitutionType{}, []*ast.TypeReference{}) if len(lit.Type.GenericArguments) > 0 { gcon = ast.NewGenericContextFromTypeReference(lit.Type) } switch typ := lit.Type.BaseType.ActualType().(type) { case ast.ArrayType: memType := typ.MemberType for i, mem := range lit.Values { expectType(s, mem, memType, &mem) if lit.Fields[i] != "" { s.Err(mem, "Unexpected field in array literal: `%s`", lit.Fields[i]) } } case ast.StructType: for i, mem := range lit.Values { name := lit.Fields[i] if name == "" { s.Err(mem, "Missing field in struct literal") continue } sMem := typ.GetMember(name) if sMem == nil { s.Err(lit, "No member named `%s` on struct of type `%s`", name, typ.String()) } sMemType := gcon.Replace(sMem.Type) expectType(s, mem, sMemType, &mem) } default: panic("composite literal has neither struct nor array type") } }