Browse Source

Disallow mixture of polymorphic $ names and normal identifiers within record parameters

gingerBill 1 year ago
parent
commit
7b672ac72a
1 changed files with 47 additions and 0 deletions
  1. 47 0
      src/parser.cpp

+ 47 - 0
src/parser.cpp

@@ -2164,6 +2164,49 @@ gb_internal Array<Ast *> parse_union_variant_list(AstFile *f) {
 	return variants;
 }
 
+gb_internal void parser_check_polymorphic_record_parameters(AstFile *f, Ast *polymorphic_params) {
+	if (polymorphic_params == nullptr) {
+		return;
+	}
+	if (polymorphic_params->kind != Ast_FieldList) {
+		return;
+	}
+
+
+	enum {Unknown, Dollar, Bare} prefix = Unknown;
+	gb_unused(prefix);
+
+	for (Ast *field : polymorphic_params->FieldList.list) {
+		if (field == nullptr || field->kind != Ast_Field) {
+			continue;
+		}
+		for (Ast *name : field->Field.names) {
+			if (name == nullptr) {
+				continue;
+			}
+			bool error = false;
+
+			if (name->kind == Ast_Ident) {
+				switch (prefix) {
+				case Unknown: prefix = Bare; break;
+				case Dollar:  error = true;  break;
+				case Bare:                   break;
+				}
+			} else if (name->kind == Ast_PolyType) {
+				switch (prefix) {
+				case Unknown: prefix = Dollar; break;
+				case Dollar:                   break;
+				case Bare:    error = true;    break;
+				}
+			}
+			if (error) {
+				syntax_error(name, "Mixture of polymorphic $ names and normal identifiers are not allowed within record parameters");
+			}
+		}
+	}
+}
+
+
 gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
 	Ast *operand = nullptr; // Operand
 	switch (f->curr_token.kind) {
@@ -2610,6 +2653,8 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
 			decls = fields->FieldList.list;
 		}
 
+		parser_check_polymorphic_record_parameters(f, polymorphic_params);
+
 		return ast_struct_type(f, token, decls, name_count, polymorphic_params, is_packed, is_raw_union, no_copy, align, field_align, where_token, where_clauses);
 	} break;
 
@@ -2702,6 +2747,8 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
 		auto variants = parse_union_variant_list(f);
 		Token close = expect_closing_brace_of_field_list(f);
 
+		parser_check_polymorphic_record_parameters(f, polymorphic_params);
+
 		return ast_union_type(f, token, variants, polymorphic_params, align, union_kind, where_token, where_clauses);
 	} break;