瀏覽代碼

[nullsafety] allow concatenation with nullable string (fixes #7899)

Alexander Kuzmenko 6 年之前
父節點
當前提交
6789d8c501
共有 2 個文件被更改,包括 22 次插入0 次删除
  1. 12 0
      src/typing/nullSafety.ml
  2. 10 0
      tests/nullsafety/src/cases/TestStrict.hx

+ 12 - 0
src/typing/nullSafety.ml

@@ -53,6 +53,12 @@ let fail ?msg hxpos mlpos =
 *)
 let str_type t = s_type (print_context()) t
 
+let is_string_type t =
+	match t with
+		| TInst ({ cl_path = ([], "String")}, _)
+		| TAbstract ({ a_path = ([],"Null") },[TInst ({ cl_path = ([], "String")}, _)]) -> true
+		| _ -> false
+
 (**
 	Check for explicit `Null<>` typing
 *)
@@ -1186,6 +1192,12 @@ class expr_checker mode immediate_execution report =
 					local_safety#process_and left_expr right_expr self#is_nullable_expr self#check_expr
 				| OpBoolOr ->
 					local_safety#process_or left_expr right_expr self#is_nullable_expr self#check_expr
+				(* String concatination is safe if one of operands is safe *)
+				| OpAdd
+				| OpAssignOp OpAdd when is_string_type left_expr.etype || is_string_type right_expr.etype  ->
+					check_both();
+					if is_nullable_type left_expr.etype && is_nullable_type right_expr.etype then
+						self#error "Cannot concatenate two nullable values." [p; left_expr.epos; right_expr.epos]
 				| OpAssign ->
 					check_both();
 					if not (self#can_pass_expr right_expr left_expr.etype p) then

+ 10 - 0
tests/nullsafety/src/cases/TestStrict.hx

@@ -841,6 +841,16 @@ class TestStrict {
 	static function return_assignNonNullable_shouldPass(?n:String):String {
 		return n = 'hello';
 	}
+
+	static function stringConcat_shouldPass(?a:String) {
+		'hello, ' + a;
+		a += 'hello';
+	}
+
+	static function stringConcat_twoNullables_shouldFail(?a:String, ?b:String) {
+		shouldFail(a + b);
+		shouldFail(a += b);
+	}
 }
 
 private class FinalNullableFields {