Browse Source

Merge pull request #3493 from nadako/enum_abstract_gadt

Support type hints in @:enum abstract fields (to support GADT-like behaviour)
Dan Korostelev 11 years ago
parent
commit
3a255a851f
3 changed files with 14 additions and 6 deletions
  1. 6 1
      tests/unit/src/unit/MyAbstract.hx
  2. 7 0
      tests/unit/src/unit/TestType.hx
  3. 1 5
      typeload.ml

+ 6 - 1
tests/unit/src/unit/MyAbstract.hx

@@ -320,4 +320,9 @@ abstract ExposingAbstract<S>(Array<S>) {
 		this = [];
 	}
 }
-#end
+#end
+
+@:enum abstract GADTEnumAbstract<T:haxe.Constraints.Function>(Int) {
+	var A:GADTEnumAbstract<Void->Void> = 1;
+	var B:GADTEnumAbstract<Int->Void> = 2;
+}

+ 7 - 0
tests/unit/src/unit/TestType.hx

@@ -862,4 +862,11 @@ class TestType extends Test {
 		eq(12, ea.pop());
 		#end
 	}
+
+	function testGADTEnumAbstract() {
+		var expectedA:unit.MyAbstract.GADTEnumAbstract<Void->Void>;
+		var expectedB:unit.MyAbstract.GADTEnumAbstract<Int->Void>;
+		typedAs(unit.MyAbstract.GADTEnumAbstract.A, expectedA);
+		typedAs(unit.MyAbstract.GADTEnumAbstract.B, expectedB);
+	}
 }

+ 1 - 5
typeload.ml

@@ -1556,10 +1556,6 @@ let build_enum_abstract ctx c a fields p =
 	List.iter (fun field ->
 		match field.cff_kind with
 		| FVar(ct,eo) when not (List.mem AStatic field.cff_access) ->
-			begin match ct with
-				| Some _ -> error "Type hints on enum abstract fields are not allowed" field.cff_pos
-				| None -> ()
-			end;
 			field.cff_access <- [AStatic;APublic;AInline];
 			field.cff_meta <- (Meta.Enum,[],field.cff_pos) :: (Meta.Impl,[],field.cff_pos) :: field.cff_meta;
 			let e = match eo with
@@ -1806,7 +1802,7 @@ let init_class ctx c p context_init herits fields =
 						let e = require_constant_expression e "Inline variable initialization must be a constant value" in
 						begin match c.cl_kind with
 							| KAbstractImpl a when Meta.has Meta.Enum cf.cf_meta && Meta.has Meta.Enum a.a_meta ->
-								unify ctx (TAbstract(a,(List.map (fun _ -> mk_mono()) a.a_params))) t p;
+								unify ctx t (TAbstract(a,(List.map (fun _ -> mk_mono()) a.a_params))) p;
 								begin match e.eexpr with
 									| TCast(e1,None) -> unify ctx e1.etype a.a_this e1.epos
 									| _ -> assert false