Bladeren bron

[typer] use has_dead_end to check return flow

closes #10865
Simon Krajewski 2 jaren geleden
bovenliggende
commit
b89ab0133a

+ 2 - 0
src/core/texpr.ml

@@ -888,6 +888,8 @@ module DeadEnd = struct
 				false (* This isn't executed, so don't recurse *)
 				false (* This isn't executed, so don't recurse *)
 			| TIf (cond, if_body, Some else_body) ->
 			| TIf (cond, if_body, Some else_body) ->
 				loop cond || loop if_body && loop else_body
 				loop cond || loop if_body && loop else_body
+			| TIf (cond, _, None) ->
+				loop cond
 			| TSwitch(e1, cases, def) ->
 			| TSwitch(e1, cases, def) ->
 				let check_exhaustive () =
 				let check_exhaustive () =
 					(is_exhaustive e1 def) && List.for_all (fun (el,e) ->
 					(is_exhaustive e1 def) && List.for_all (fun (el,e) ->

+ 2 - 8
src/typing/typeloadCheck.ml

@@ -270,12 +270,6 @@ let rec return_flow ctx e =
 		display_error ctx.com (Printf.sprintf "Missing return: %s" (s_type (print_context()) ctx.ret)) e.epos; raise Exit
 		display_error ctx.com (Printf.sprintf "Missing return: %s" (s_type (print_context()) ctx.ret)) e.epos; raise Exit
 	in
 	in
 	let return_flow = return_flow ctx in
 	let return_flow = return_flow ctx in
-	let rec uncond e = match e.eexpr with
-		| TIf _ | TWhile _ | TSwitch _ | TTry _ | TFunction _ -> ()
-		| TReturn _ | TThrow _ -> raise Exit
-		| _ -> Type.iter uncond e
-	in
-	let has_unconditional_flow e = try uncond e; false with Exit -> true in
 	match e.eexpr with
 	match e.eexpr with
 	| TReturn _ | TThrow _ -> ()
 	| TReturn _ | TThrow _ -> ()
 	| TParenthesis e | TMeta(_,e) ->
 	| TParenthesis e | TMeta(_,e) ->
@@ -284,7 +278,7 @@ let rec return_flow ctx e =
 		let rec loop = function
 		let rec loop = function
 			| [] -> error()
 			| [] -> error()
 			| [e] -> return_flow e
 			| [e] -> return_flow e
-			| e :: _ when has_unconditional_flow e -> ()
+			| e :: _ when DeadEnd.has_dead_end e -> ()
 			| _ :: l -> loop l
 			| _ :: l -> loop l
 		in
 		in
 		loop el
 		loop el
@@ -309,7 +303,7 @@ let rec return_flow ctx e =
 		in
 		in
 		loop e
 		loop e
 	| _ ->
 	| _ ->
-		error()
+		if not (DeadEnd.has_dead_end e) then error()
 
 
 let check_global_metadata ctx meta f_add mpath tpath so =
 let check_global_metadata ctx meta f_add mpath tpath so =
 	let sl1 = full_dot_path2 mpath tpath in
 	let sl1 = full_dot_path2 mpath tpath in

+ 9 - 0
tests/misc/projects/Issue10865/Main.hx

@@ -0,0 +1,9 @@
+class Main {
+	public static function main():Void
+		trace(foo());
+
+	public static function foo():Int {
+		true || throw 0;
+		0;
+	}
+}

+ 2 - 0
tests/misc/projects/Issue10865/compile-fail.hxml

@@ -0,0 +1,2 @@
+--main Main
+--interp

+ 1 - 0
tests/misc/projects/Issue10865/compile-fail.hxml.stderr

@@ -0,0 +1 @@
+Main.hx:7: characters 3-4 : Missing return: Int