Simon Krajewski 3 years ago
parent
commit
0fab66451d
4 changed files with 45 additions and 1 deletions
  1. 20 0
      src/typing/fields.ml
  2. 8 0
      src/typing/typeload.ml
  3. 7 1
      src/typing/typer.ml
  4. 10 0
      tests/unit/src/unit/issues/Issue9825.hx

+ 20 - 0
src/typing/fields.ml

@@ -58,6 +58,23 @@ let remove_constant_flag t callb =
 		restore();
 		raise e
 
+let extract_dynamic_parameter_from_anon an = match !(an.a_status) with
+	| Extend tl ->
+		let rec loop tl = match tl with
+			| t :: tl ->
+				begin match follow t with
+				| TDynamic t ->
+					t
+				| _ ->
+					loop tl
+				end
+			| [] ->
+				raise Not_found
+		in
+		loop tl
+	| _ ->
+		raise Not_found
+
 let enum_field_type ctx en ef p =
 	let tl_en = Monomorph.spawn_constrained_monos (fun t -> t) en.e_params in
 	let map = apply_params en.e_params tl_en in
@@ -519,6 +536,9 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) =
 			)
 		| TDynamic t ->
 			AKExpr (mk (TField (e,FDynamic i)) t p)
+		| TAnon an ->
+			let t =  extract_dynamic_parameter_from_anon an in
+			AKExpr (mk (TField (e,FDynamic i)) t p)
 		| TAbstract (a,tl) ->
 			(try
 				if not (TypeFieldConfig.allow_resolve cfg) then raise Not_found;

+ 8 - 0
src/typing/typeload.ml

@@ -263,17 +263,25 @@ let is_redefined ctx cf1 fields p =
 		false
 
 let make_extension_type ctx tl =
+	let extends_dynamic = ref None in
 	let mk_extension fields (t,p) = match follow t with
 		| TAnon a ->
 			PMap.fold (fun cf fields ->
 				if not (is_redefined ctx cf fields p) then PMap.add cf.cf_name cf fields
 				else fields
 			) a.a_fields fields
+		| TDynamic _ ->
+			extends_dynamic := Some t;
+			fields
 		| _ ->
 			error "Can only extend structures" p
 	in
 	let fields = List.fold_left mk_extension PMap.empty tl in
 	let tl = List.map (fun (t,_) -> t) tl in
+	let tl = match !extends_dynamic with
+		| None -> tl
+		| Some t -> t :: tl
+	in
 	let ta = mk_anon ~fields (ref (Extend tl)) in
 	ta
 

+ 7 - 1
src/typing/typer.ml

@@ -763,7 +763,13 @@ and type_object_decl ctx fl with_type p =
 	| WithType.WithType(t,_) ->
 		let rec loop seen t =
 			match follow t with
-			| TAnon a -> ODKWithStructure a
+			| TAnon a ->
+				begin try
+					dynamic_parameter := Some (extract_dynamic_parameter_from_anon a);
+				with Not_found ->
+					()
+				end;
+				ODKWithStructure a
 			| TAbstract (a,pl) as t
 				when not (Meta.has Meta.CoreType a.a_meta)
 					&& not (List.exists (fun t' -> shallow_eq t t') seen) ->

+ 10 - 0
tests/unit/src/unit/issues/Issue9825.hx

@@ -0,0 +1,10 @@
+package unit.issues;
+
+typedef KnownDynamic<T> = {known:T} &
+	Dynamic<T>;
+
+class Issue9825 extends Test {
+	function test() {
+		var d:KnownDynamic<String> = {known: "foo", also: "bar"};
+	}
+}