2
0
Эх сурвалжийг харах

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 сар өмнө
parent
commit
683c11e03b
1 өөрчлөгдсөн 13 нэмэгдсэн , 11 устгасан
  1. 13 11
      src/typing/typer.ml

+ 13 - 11
src/typing/typer.ml

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