Преглед изворни кода

allow `@:followWithAbstracts` on `@:multiType` (closes #4777)

Simon Krajewski пре 9 година
родитељ
комит
9c3063d069
3 измењених фајлова са 29 додато и 5 уклоњено
  1. 17 4
      codegen.ml
  2. 1 1
      std/Map.hx
  3. 11 0
      tests/unit/src/unit/issues/Issue4777.hx

+ 17 - 4
codegen.ml

@@ -876,11 +876,24 @@ module AbstractCast = struct
 			| _,[],_ -> pl
 			| _,el,_ ->
 				let relevant = Hashtbl.create 0 in
-				List.iter (fun e -> match fst e with
-					| EConst(Ident s) -> Hashtbl.replace relevant s true
-					| _ -> error "Type parameter expected" (pos e)
+				List.iter (fun e ->
+					let rec loop f e = match fst e with
+						| EConst(Ident s) ->
+							Hashtbl.replace relevant s f
+						| EMeta((Meta.Custom ":followWithAbstracts",_,_),e1) ->
+							loop Abstract.follow_with_abstracts e1;
+						| _ ->
+							error "Type parameter expected" (pos e)
+					in
+					loop (fun t -> t) e
 				) el;
-				let tl = List.map2 (fun (n,_) t -> if Hashtbl.mem relevant n || not (has_mono t) then t else t_dynamic) a.a_params pl in
+				let tl = List.map2 (fun (n,_) t ->
+					try
+						(Hashtbl.find relevant n) t
+					with Not_found ->
+						if not (has_mono t) then t
+						else t_dynamic
+				) a.a_params pl in
 				if com.platform = Js && a.a_path = ([],"Map") then begin match tl with
 					| t1 :: _ ->
 						let rec loop stack t =

+ 1 - 1
std/Map.hx

@@ -42,7 +42,7 @@ import haxe.Constraints.IMap;
 
 	Map is an abstract type, it is not available at runtime.
 **/
-@:multiType(K)
+@:multiType(@:followWithAbstracts K)
 abstract Map<K,V>(IMap<K,V> ) {
 
 	/**

+ 11 - 0
tests/unit/src/unit/issues/Issue4777.hx

@@ -0,0 +1,11 @@
+package unit.issues;
+
+private abstract A(String) from String {}
+
+class Issue4777 extends Test {
+	function test() {
+		var map:Map<A, String> = new Map();
+		map["foo"] = "bar";
+		eq("bar", map["foo"]);
+	}
+}