소스 검색

[eval,hl] Fix wrong variable scope in closure (#10084)

* [eval,hl] Fix wrong variable scope in closure

Fixes #10083

* Stop lying

* Add test for #10083

* Swap eq args
Rudy Ges 4 년 전
부모
커밋
8c0d30bdbf
3개의 변경된 파일34개의 추가작업 그리고 2개의 파일을 삭제
  1. 1 0
      src/core/tType.ml
  2. 7 2
      src/filters/capturedVars.ml
  3. 26 0
      tests/unit/src/unit/issues/Issue10083.hx

+ 1 - 0
src/core/tType.ml

@@ -401,4 +401,5 @@ type flag_tvar =
 	| VCaptured
 	| VCaptured
 	| VFinal
 	| VFinal
 	| VUsed (* used by the analyzer *)
 	| VUsed (* used by the analyzer *)
+	| VAssigned
 	| VCaught
 	| VCaught

+ 7 - 2
src/filters/capturedVars.ml

@@ -262,7 +262,10 @@ let captured_vars com e =
 		| Use v ->
 		| Use v ->
 			(try
 			(try
 				let d = PMap.find v.v_id !vars in
 				let d = PMap.find v.v_id !vars in
-				if d <> !depth then used := PMap.add v.v_id v !used;
+				if d <> !depth then begin
+					used := PMap.add v.v_id v !used;
+					if has_var_flag v VAssigned then assigned := PMap.add v.v_id v !assigned;
+				end
 			with Not_found -> ())
 			with Not_found -> ())
 		| Assign v ->
 		| Assign v ->
 			(try
 			(try
@@ -274,7 +277,9 @@ let captured_vars com e =
 				end
 				end
 				(* same depth but assigned after being used on a different depth - needs wrap *)
 				(* same depth but assigned after being used on a different depth - needs wrap *)
 				else if PMap.mem v.v_id !used then
 				else if PMap.mem v.v_id !used then
-					assigned := PMap.add v.v_id v !assigned;
+					assigned := PMap.add v.v_id v !assigned
+				else
+					add_var_flag v VAssigned;
 			with Not_found -> ())
 			with Not_found -> ())
 		in
 		in
 		local_usage collect_vars e;
 		local_usage collect_vars e;

+ 26 - 0
tests/unit/src/unit/issues/Issue10083.hx

@@ -0,0 +1,26 @@
+package unit.issues;
+
+private enum FooBar {
+  Foo;
+  Bar;
+}
+
+class Issue10083 extends Test {
+  function test() {
+    var hasFoo = false;
+    var tasks:Array<Void->Void> = [];
+    var flags = ["A" => Bar, "B" => Foo, "C" => Bar];
+
+    for (flag in flags) {
+      switch (flag) {
+        case Foo:
+          hasFoo = true;
+
+        case Bar:
+          tasks.push(() -> eq(true, hasFoo));
+      }
+    }
+
+    while (tasks.length > 0) tasks.shift()();
+  }
+}