Răsfoiți Sursa

don't create monos on control flow terminator if we have an expected type

In most cases they won't be unified with anything, so we might as well use the expected type directly.
Simon Krajewski 8 luni în urmă
părinte
comite
683c11e03b
1 a modificat fișierele cu 13 adăugiri și 11 ștergeri
  1. 13 11
      src/typing/typer.ml

+ 13 - 11
src/typing/typer.ml

@@ -36,10 +36,12 @@ open Operators
 (* ---------------------------------------------------------------------- *)
 (* TOOLS *)
 
-let mono_or_dynamic ctx with_type p = match with_type with
+let terminator_type ctx with_type p = match with_type with
 	| WithType.NoValue ->
 		t_dynamic
-	| Value _ | WithType _ ->
+	| WithType(t,_) ->
+		t
+	| Value _ ->
 		spawn_monomorph ctx p
 
 let get_iterator_param t =
@@ -1475,7 +1477,7 @@ and type_return ?(implicit=false) ctx e with_type p =
 	match e with
 	| None when is_abstract_ctor ->
 		let e_cast = mk (TCast(get_this ctx p,None)) ctx.e.ret p in
-		mk (TReturn (Some e_cast)) (mono_or_dynamic ctx with_type p) p
+		mk (TReturn (Some e_cast)) (terminator_type ctx with_type p) p
 	| None ->
 		let v = ctx.t.tvoid in
 		unify ctx v ctx.e.ret p;
@@ -1484,7 +1486,7 @@ and type_return ?(implicit=false) ctx e with_type p =
 			| WithType.Value (Some ImplicitReturn) -> true
 			| _ -> false
 		in
-		mk (TReturn None) (if expect_void then v else (mono_or_dynamic ctx with_type p)) p
+		mk (TReturn None) (if expect_void then v else (terminator_type ctx with_type p)) p
 	| Some e ->
 		if is_abstract_ctor then begin
 			match fst e with
@@ -1510,20 +1512,20 @@ and type_return ?(implicit=false) ctx e with_type p =
 					| _ -> ()
 					end;
 					(* if we get a Void expression (e.g. from inlining) we don't want to return it (issue #4323) *)
-					let t = mono_or_dynamic ctx with_type p in
+					let t = terminator_type ctx with_type p in
 					mk (TBlock [
 						e;
 						mk (TReturn None) t p
 					]) t e.epos;
 				| _ ->
-					mk (TReturn (Some e)) (mono_or_dynamic ctx with_type p) p
+					mk (TReturn (Some e)) (terminator_type ctx with_type p) p
 		with Error err ->
 			let p = err.err_pos in
 			check_error ctx err;
 			(* If we have a bad return, let's generate a return null expression at least. This surpresses various
 				follow-up errors that come from the fact that the function no longer has a return expression (issue #6445). *)
 			let e_null = mk (TConst TNull) (mk_mono()) p in
-			mk (TReturn (Some e_null)) (mono_or_dynamic ctx with_type p) p
+			mk (TReturn (Some e_null)) (terminator_type ctx with_type p) p
 
 and type_cast ctx e t p =
 	let tpos = pos t in
@@ -1952,7 +1954,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 			display_error ctx.com "Return outside function" p;
 			match e with
 			| None ->
-				Texpr.Builder.make_null (mono_or_dynamic ctx with_type p) p
+				Texpr.Builder.make_null (terminator_type ctx with_type p) p
 			| Some e ->
 				(* type the return expression to see if there are more errors
 				   as well as use its type as if there was no `return`, since
@@ -1962,10 +1964,10 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 			type_return ctx e with_type p
 	| EBreak ->
 		if not ctx.e.in_loop then display_error ctx.com "Break outside loop" p;
-		mk TBreak (mono_or_dynamic ctx with_type p) p
+		mk TBreak (terminator_type ctx with_type p) p
 	| EContinue ->
 		if not ctx.e.in_loop then display_error ctx.com "Continue outside loop" p;
-		mk TContinue (mono_or_dynamic ctx with_type p) p
+		mk TContinue (terminator_type ctx with_type p) p
 	| ETry (e1,[]) ->
 		type_expr ctx e1 with_type
 	| ETry (e1,catches) ->
@@ -1977,7 +1979,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
 			check_error ctx err;
 			Texpr.Builder.make_null t_dynamic p
 		in
-		mk (TThrow e) (mono_or_dynamic ctx with_type p) p
+		mk (TThrow e) (terminator_type ctx with_type p) p
 	| ENew (t,el) ->
 		type_new ctx t el with_type false p
 	| EUnop (op,flag,e) ->