checker: make struct_init check more robust
							parent
							
								
									4d5fe14968
								
							
						
					
					
						commit
						e8b26b1b8d
					
				|  | @ -89,10 +89,26 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type { | ||||||
| 			} | 			} | ||||||
| 			mut inited_fields := []string | 			mut inited_fields := []string | ||||||
| 			for i, expr in struct_init.exprs { | 			for i, expr in struct_init.exprs { | ||||||
|  | 				if is_short_syntax && i >= info.fields.len { | ||||||
|  | 					// It doesn't make sense to check for fields that don't exist.
 | ||||||
|  | 					// We should just stop here.
 | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
| 				// struct_field info.
 | 				// struct_field info.
 | ||||||
| 				field_name := if is_short_syntax { info.fields[i].name } else { struct_init.fields[i] } | 				field_name := if is_short_syntax { info.fields[i].name } else { struct_init.fields[i] } | ||||||
| 				mut field := info.fields[i] | 				if field_name in inited_fields { | ||||||
|  | 					c.error('struct init: duplicate field `$field_name` for struct `$typ_sym.name`', struct_init.pos) | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
| 				inited_fields << field_name | 				inited_fields << field_name | ||||||
|  | 				mut field := if is_short_syntax { | ||||||
|  | 					info.fields[i] | ||||||
|  | 				} else { | ||||||
|  | 					// There is no guarantee that `i` will not be out of bounds of `info.fields`
 | ||||||
|  | 					// So we just use an empty field as placeholder here.
 | ||||||
|  | 					table.Field{} | ||||||
|  | 				} | ||||||
|  | 				if !is_short_syntax { | ||||||
| 					mut found_field := false | 					mut found_field := false | ||||||
| 					for f in info.fields { | 					for f in info.fields { | ||||||
| 						if f.name == field_name { | 						if f.name == field_name { | ||||||
|  | @ -103,6 +119,8 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type { | ||||||
| 					} | 					} | ||||||
| 					if !found_field { | 					if !found_field { | ||||||
| 						c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', struct_init.pos) | 						c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', struct_init.pos) | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 				c.expected_type = field.typ | 				c.expected_type = field.typ | ||||||
| 				expr_type := c.expr(expr) | 				expr_type := c.expr(expr) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue