2
0
Эх сурвалжийг харах

error if @:generic generates already used name
#8393

Aleksandr Kuzmenko 6 жил өмнө
parent
commit
7000f8bf62

+ 5 - 2
src/typing/calls.ml

@@ -325,7 +325,7 @@ let unify_field_call ctx fa el args ret p inline =
 			| (el,tf,mk_call) :: _ -> List.map fst el,tf,mk_call
 		end
 
- let type_generic_function ctx (e,fa) el ?(using_param=None) with_type p =
+let type_generic_function ctx (e,fa) el ?(using_param=None) with_type p =
 	let c,tl,cf,stat = match fa with
 		| FInstance(c,tl,cf) -> c,tl,cf,false
 		| FStatic(c,cf) -> c,[],cf,true
@@ -378,7 +378,10 @@ let unify_field_call ctx fa el args ret p inline =
 				unify_existing_field cf2.cf_type cf2.cf_pos;
 				cf2
 			in
-			cf2
+			if cf.cf_name_pos = cf2.cf_name_pos then
+				cf2
+			else
+				error ("Cannot specialize @:generic because the generated function name is already used: " ^ name) p
 		with Not_found ->
 			let cf2 = mk_field name (map_monos cf.cf_type) cf.cf_pos cf.cf_name_pos in
 			if stat then begin

+ 4 - 1
src/typing/generic.ml

@@ -161,7 +161,10 @@ let rec build_generic ctx c p tl =
 	let gctx = make_generic ctx c.cl_params tl p in
 	let name = (snd c.cl_path) ^ "_" ^ gctx.name in
 	try
-		Typeload.load_instance ctx ({ tpackage = pack; tname = name; tparams = []; tsub = None },p) false
+		let t = Typeload.load_instance ctx ({ tpackage = pack; tname = name; tparams = []; tsub = None },p) false in
+		match t with
+		| TInst({ cl_kind = KGenericInstance (csup,_) },_) when c == csup -> t
+		| _ -> error ("Cannot specialize @:generic because the generated type name is already used: " ^ name) p
 	with Error(Module_not_found path,_) when path = (pack,name) ->
 		let m = (try Hashtbl.find ctx.g.modules (Hashtbl.find ctx.g.types_module c.cl_path) with Not_found -> assert false) in
 		(* let ctx = { ctx with m = { ctx.m with module_types = m.m_types @ ctx.m.module_types } } in *)

+ 9 - 0
tests/misc/projects/Issue8393/Main.hx

@@ -0,0 +1,9 @@
+@:generic
+class Generic<T> {}
+
+class Generic_Int {}
+
+class Main {
+	static var tmp:Generic<Int>;
+	static function main():Void {}
+}

+ 11 - 0
tests/misc/projects/Issue8393/Main2.hx

@@ -0,0 +1,11 @@
+class Main2 {
+
+	@:generic
+	static function test<T>(i:T) {}
+
+	static function test_Int(i:Int) {}
+
+	static function main():Void {
+		test(10);
+	}
+}

+ 1 - 0
tests/misc/projects/Issue8393/compile-fail.hxml

@@ -0,0 +1 @@
+-main Main

+ 1 - 0
tests/misc/projects/Issue8393/compile-fail.hxml.stderr

@@ -0,0 +1 @@
+Main.hx:7: characters 17-29 : Cannot specialize @:generic because the generated type name is already used: Generic_Int

+ 1 - 0
tests/misc/projects/Issue8393/compile2-fail.hxml

@@ -0,0 +1 @@
+-main Main2

+ 1 - 0
tests/misc/projects/Issue8393/compile2-fail.hxml.stderr

@@ -0,0 +1 @@
+Main2.hx:9: characters 3-11 : Cannot specialize @:generic because the generated function name is already used: test_Int