Browse Source

respect `Dynamic<T>` for structure declarations (closes #3635)

Simon Krajewski 11 years ago
parent
commit
8bec6f17db
2 changed files with 32 additions and 2 deletions
  1. 23 0
      tests/unit/src/unit/issues/Issue3635.hx
  2. 9 2
      typer.ml

+ 23 - 0
tests/unit/src/unit/issues/Issue3635.hx

@@ -0,0 +1,23 @@
+package unit.issues;
+
+private typedef A = { var x:Int; };
+private typedef B = { var x(default, never):Int; };
+
+class Issue3635 extends Test {
+	function test() {
+		var a:A, b:B;
+		var dA:Dynamic<A>, dB:Dynamic<B>;
+
+		a = { x: 10 };
+		b = { x: 10 };
+
+		dA = { key: { x: 10 }};
+		dB = { key: { x: 10 }};
+		dB = {};
+		dB.key = { x: 10 };
+		dB = { key: b };
+
+		t(unit.TestType.typeError(dA = { key: { y: 120 } }));
+		t(unit.TestType.typeError(dB = { key: { y: 120 } }));
+	}
+}

+ 9 - 2
typer.ml

@@ -2832,6 +2832,7 @@ and type_expr ctx (e,p) (with_type:with_type) =
 		let e = type_expr ctx e with_type in
 		mk (TParenthesis e) e.etype p
 	| EObjectDecl fl ->
+		let dynamic_parameter = ref None in
 		let a = (match with_type with
 		| WithType t | WithTypeResume t ->
 			(match follow t with
@@ -2841,6 +2842,12 @@ and type_expr ctx (e,p) (with_type:with_type) =
 					| TAnon a when not (PMap.is_empty a.a_fields) -> Some a
 					| _ -> None
 				end
+			| TDynamic t when (follow t != t_dynamic) ->
+				dynamic_parameter := Some t;
+				Some {
+					a_status = ref Closed;
+					a_fields = PMap.empty;
+				}
 			| _ -> None)
 		| _ -> None
 		) in
@@ -2868,7 +2875,7 @@ and type_expr ctx (e,p) (with_type:with_type) =
 				let n,add = Parser.unquote_ident n in
 				if PMap.mem n !fields then error ("Duplicate field in object declaration : " ^ n) p;
 				let e = try
-					let t = (PMap.find n a.a_fields).cf_type in
+					let t = (match !dynamic_parameter with Some t -> t | None -> (PMap.find n a.a_fields).cf_type) in
 					let e = type_expr ctx e (match with_type with WithTypeResume _ -> WithTypeResume t | _ -> WithType t) in
 					let e = Codegen.AbstractCast.cast_or_unify ctx t e p in
 					(try type_eq EqStrict e.etype t; e with Unify_error _ -> mk (TCast (e,None)) t e.epos)
@@ -4881,4 +4888,4 @@ make_call_ref := make_call;
 get_constructor_ref := get_constructor;
 cast_or_unify_ref := Codegen.AbstractCast.cast_or_unify_raise;
 type_module_type_ref := type_module_type;
-find_array_access_raise_ref := Codegen.AbstractCast.find_array_access_raise
+find_array_access_raise_ref := Codegen.AbstractCast.find_array_access_raise