@@ -387,7 +387,7 @@ static void doPtrToInterfaceConv(Compiler *comp, Type *dest, Type **src, Const *
387387 genSwapAssign (& comp -> gen , TYPE_PTR , 0 ); // Assign to dest.__self
388388
389389 // Assign to __selftype (RTTI)
390- Field * selfType = typeAssertFindField (& comp -> types , dest , "__selftype" );
390+ Field * selfType = typeAssertFindField (& comp -> types , dest , "__selftype" , NULL );
391391
392392 genPushGlobalPtr (& comp -> gen , * src ); // Push src type
393393 genPushLocalPtr (& comp -> gen , destOffset + selfType -> offset ); // Push dest.__selftype pointer
@@ -440,7 +440,7 @@ static void doInterfaceToInterfaceConv(Compiler *comp, Type *dest, Type **src, C
440440 genSwapAssign (& comp -> gen , TYPE_PTR , 0 ); // Assign to dest.__self (NULL means a dynamic type)
441441
442442 // Assign to __selftype (RTTI)
443- Field * selfType = typeAssertFindField (& comp -> types , dest , "__selftype" );
443+ Field * selfType = typeAssertFindField (& comp -> types , dest , "__selftype" , NULL );
444444
445445 genDup (& comp -> gen ); // Duplicate src pointer
446446 genGetFieldPtr (& comp -> gen , selfType -> offset ); // Get src.__selftype pointer
@@ -452,7 +452,7 @@ static void doInterfaceToInterfaceConv(Compiler *comp, Type *dest, Type **src, C
452452 for (int i = 2 ; i < dest -> numItems ; i ++ )
453453 {
454454 const char * name = dest -> field [i ]-> name ;
455- Field * srcMethod = typeFindField (* src , name );
455+ Field * srcMethod = typeFindField (* src , name , NULL );
456456 if (!srcMethod )
457457 comp -> error .handler (comp -> error .context , "Method %s is not implemented" , name );
458458
@@ -1557,7 +1557,7 @@ static void parseCall(Compiler *comp, Type **type, Const *constant)
15571557 if ((* type )-> kind == TYPE_CLOSURE )
15581558 {
15591559 // Closure upvalue
1560- Field * fn = typeAssertFindField (& comp -> types , * type , "__fn" );
1560+ Field * fn = typeAssertFindField (& comp -> types , * type , "__fn" , NULL );
15611561 * type = fn -> type ;
15621562
15631563 genPushUpvalue (& comp -> gen );
@@ -1768,6 +1768,8 @@ static void parseArrayOrStructLiteral(Compiler *comp, Type **type, Const *consta
17681768 lexEat (& comp -> lex , TOK_LBRACE );
17691769
17701770 bool namedFields = false;
1771+ bool * fieldInitialized = NULL ;
1772+
17711773 if ((* type )-> kind == TYPE_STRUCT )
17721774 {
17731775 if (comp -> lex .tok .kind == TOK_RBRACE )
@@ -1780,6 +1782,9 @@ static void parseArrayOrStructLiteral(Compiler *comp, Type **type, Const *consta
17801782 }
17811783 }
17821784
1785+ if (namedFields )
1786+ fieldInitialized = calloc ((* type )-> numItems + 1 , sizeof (bool ));
1787+
17831788 const int size = typeSize (& comp -> types , * type );
17841789 Ident * arrayOrStruct = NULL ;
17851790
@@ -1808,7 +1813,14 @@ static void parseArrayOrStructLiteral(Compiler *comp, Type **type, Const *consta
18081813 if (namedFields )
18091814 {
18101815 lexCheck (& comp -> lex , TOK_IDENT );
1811- field = typeAssertFindField (& comp -> types , * type , comp -> lex .tok .name );
1816+
1817+ int fieldIndex = 0 ;
1818+ field = typeAssertFindField (& comp -> types , * type , comp -> lex .tok .name , & fieldIndex );
1819+
1820+ if (field && fieldInitialized [fieldIndex ])
1821+ comp -> error .handler (comp -> error .context , "Duplicate field %s" , field -> name );
1822+
1823+ fieldInitialized [fieldIndex ] = true;
18121824 itemOffset = field -> offset ;
18131825
18141826 lexNext (& comp -> lex );
@@ -1846,9 +1858,13 @@ static void parseArrayOrStructLiteral(Compiler *comp, Type **type, Const *consta
18461858 lexNext (& comp -> lex );
18471859 }
18481860 }
1861+
18491862 if (!namedFields && numItems < (* type )-> numItems )
18501863 comp -> error .handler (comp -> error .context , "Too few elements in literal" );
18511864
1865+ if (fieldInitialized )
1866+ free (fieldInitialized );
1867+
18521868 if (!constant )
18531869 doPushVarPtr (comp , arrayOrStruct );
18541870
@@ -2028,7 +2044,7 @@ static void parseClosureLiteral(Compiler *comp, Type **type, Const *constant)
20282044 if (comp -> blocks .top != 0 )
20292045 genNop (& comp -> gen ); // Jump over the nested function block (stub)
20302046
2031- Field * fn = typeAssertFindField (& comp -> types , * type , "__fn" );
2047+ Field * fn = typeAssertFindField (& comp -> types , * type , "__fn" , NULL );
20322048
20332049 Const fnConstant = {.intVal = comp -> gen .ip };
20342050 Ident * fnConstantIdent = identAddTempConst (& comp -> idents , & comp -> modules , & comp -> blocks , fn -> type , fnConstant );
@@ -2095,7 +2111,7 @@ static void parseClosureLiteral(Compiler *comp, Type **type, Const *constant)
20952111 }
20962112
20972113 // Assign closure upvalues
2098- Field * upvalues = typeAssertFindField (& comp -> types , closureIdent -> type , "__upvalues" );
2114+ Field * upvalues = typeAssertFindField (& comp -> types , closureIdent -> type , "__upvalues" , NULL );
20992115 Type * upvaluesType = upvaluesStructIdent -> type ;
21002116
21012117 doPushVarPtr (comp , closureIdent );
@@ -2113,7 +2129,7 @@ static void parseClosureLiteral(Compiler *comp, Type **type, Const *constant)
21132129
21142130 genNop (& comp -> gen ); // Jump over the nested function block (stub)
21152131
2116- Field * fn = typeAssertFindField (& comp -> types , closureIdent -> type , "__fn" );
2132+ Field * fn = typeAssertFindField (& comp -> types , closureIdent -> type , "__fn" , NULL );
21172133
21182134 Const fnConstant = {.intVal = comp -> gen .ip };
21192135 Ident * fnConstantIdent = identAddTempConst (& comp -> idents , & comp -> modules , & comp -> blocks , fn -> type , fnConstant );
@@ -2365,7 +2381,7 @@ static void parseFieldSelector(Compiler *comp, Type **type, Const *constant, boo
23652381 comp -> error .handler (comp -> error .context , "Method %s is not defined for %s" , comp -> lex .tok .name , typeSpelling (* type , typeBuf ));
23662382 }
23672383
2368- Field * field = typeAssertFindField (& comp -> types , * type , comp -> lex .tok .name );
2384+ Field * field = typeAssertFindField (& comp -> types , * type , comp -> lex .tok .name , NULL );
23692385 lexNext (& comp -> lex );
23702386
23712387 genGetFieldPtr (& comp -> gen , field -> offset );
0 commit comments