ソースを参照

[typer] deal with `for (i in throw)`

closes #11403
Simon Krajewski 1 年間 前
コミット
297353c8a6
2 ファイル変更41 行追加24 行削除
  1. 28 24
      src/typing/forLoop.ml
  2. 13 0
      tests/unit/src/unit/issues/Issue11403.hx

+ 28 - 24
src/typing/forLoop.ml

@@ -457,29 +457,7 @@ type iteration_kind =
 	| IKNormal of iteration_ident
 	| IKKeyValue of iteration_ident * iteration_ident
 
-let type_for_loop ctx handle_display it e2 p =
-	let rec loop_ident dko e1 = match e1 with
-		| EConst(Ident i),p -> i,p,dko
-		| EDisplay(e1,dk),_ -> loop_ident (Some dk) e1
-		| _ -> raise_typing_error "Identifier expected" (pos e1)
-	in
-	let rec loop dko e1 = match fst e1 with
-		| EBinop(OpIn,e1,e2) ->
-			begin match fst e1 with
-			| EBinop(OpArrow,ei1,ei2) -> IKKeyValue(loop_ident None ei1,loop_ident None ei2),e2
-			| _ -> IKNormal (loop_ident dko e1),e2
-			end
-		| EDisplay(e1,dk) -> loop (Some dk) e1
-		| EBinop(OpArrow,ei1,(EBinop(OpIn,ei2,e2),_)) -> IKKeyValue(loop_ident None ei1,loop_ident None ei2),e2
-		| _ ->
-			begin match dko with
-			| Some dk -> ignore(handle_display ctx e1 dk MGet WithType.value);
-			| None -> ()
-			end;
-			raise_typing_error "For expression should be 'v in expr'" (snd it)
-	in
-	let ik,e1 = loop None it in
-	let e1 = type_expr ctx e1 WithType.value in
+let type_for_loop ctx handle_display ik e1 e2 p =
 	let old_loop = ctx.in_loop in
 	let old_locals = save_locals ctx in
 	ctx.in_loop <- true;
@@ -535,4 +513,30 @@ let type_for_loop ctx handle_display it e2 p =
 		old_locals();
 		e
 
-
+let type_for_loop ctx handle_display it e2 p =
+	let rec loop_ident dko e1 = match e1 with
+		| EConst(Ident i),p -> i,p,dko
+		| EDisplay(e1,dk),_ -> loop_ident (Some dk) e1
+		| _ -> raise_typing_error "Identifier expected" (pos e1)
+	in
+	let rec loop dko e1 = match fst e1 with
+		| EBinop(OpIn,e1,e2) ->
+			begin match fst e1 with
+			| EBinop(OpArrow,ei1,ei2) -> IKKeyValue(loop_ident None ei1,loop_ident None ei2),e2
+			| _ -> IKNormal (loop_ident dko e1),e2
+			end
+		| EDisplay(e1,dk) -> loop (Some dk) e1
+		| EBinop(OpArrow,ei1,(EBinop(OpIn,ei2,e2),_)) -> IKKeyValue(loop_ident None ei1,loop_ident None ei2),e2
+		| _ ->
+			begin match dko with
+			| Some dk -> ignore(handle_display ctx e1 dk MGet WithType.value);
+			| None -> ()
+			end;
+			raise_typing_error "For expression should be 'v in expr'" (snd it)
+	in
+	let ik,e1 = loop None it in
+	let e1 = type_expr ctx e1 WithType.value in
+	if DeadEnd.has_dead_end e1 then
+		e1
+	else
+		type_for_loop ctx handle_display ik e1 e2 p

+ 13 - 0
tests/unit/src/unit/issues/Issue11403.hx

@@ -0,0 +1,13 @@
+package unit.issues;
+
+class Issue11403 extends Test {
+	public static macro function getValues() {
+		return macro [1];
+	}
+
+	function test() {
+		for (v in getValues()) {
+			eq(1, v);
+		}
+	}
+}