Browse Source

fix default values of basic types in user-defined structinit constructors
fixes #9177

Aleksandr Kuzmenko 5 years ago
parent
commit
55ac868e60
4 changed files with 39 additions and 3 deletions
  1. 16 0
      src/core/tFunctions.ml
  2. 0 2
      src/core/tUnification.ml
  3. 6 1
      src/typing/typer.ml
  4. 17 0
      tests/unit/src/unit/issues/Issue9177.hx

+ 16 - 0
src/core/tFunctions.ml

@@ -5,6 +5,9 @@ open TType
 let monomorph_create_ref : (unit -> tmono) ref = ref (fun _ -> assert false)
 let monomorph_bind_ref : (tmono -> t -> unit) ref = ref (fun _ _ -> assert false)
 
+let has_meta m ml = List.exists (fun (m2,_,_) -> m = m2) ml
+let get_meta m ml = List.find (fun (m2,_,_) -> m = m2) ml
+
 (* Flags *)
 
 let has_flag flags flag =
@@ -728,3 +731,16 @@ let resolve_typedef t =
 		| TInst (c,_) -> TClassDecl c
 		| TAbstract (a,_) -> TAbstractDecl a
 		| _ -> t
+
+(**
+	Check if type `t` has meta `m`.
+	Does not follow typedefs, monomorphs etc.
+*)
+let type_has_meta t m =
+	match t with
+		| TMono _ | TFun _ | TAnon _ | TDynamic _ | TLazy _ -> false
+		| TEnum ({ e_meta = metadata }, _)
+		| TInst ({ cl_meta = metadata }, _)
+		| TType ({ t_meta = metadata }, _)
+		| TAbstract ({ a_meta = metadata }, _) -> has_meta m metadata
+

+ 0 - 2
src/core/tUnification.ml

@@ -171,8 +171,6 @@ let invalid_visibility n = Invalid_visibility n
 let has_no_field t n = Has_no_field (t,n)
 let has_extra_field t n = Has_extra_field (t,n)
 let error l = raise (Unify_error l)
-let has_meta m ml = List.exists (fun (m2,_,_) -> m = m2) ml
-let get_meta m ml = List.find (fun (m2,_,_) -> m = m2) ml
 
 (*
 	we can restrict access as soon as both are runtime-compatible

+ 6 - 1
src/typing/typer.ml

@@ -1662,7 +1662,12 @@ and type_object_decl ctx fl with_type p =
 		) ([],[],false) (List.rev fl) in
 		let el = List.map (fun (n,_,t) ->
 			try Expr.field_assoc n fl
-			with Not_found -> mk (TConst TNull) t p
+			with Not_found ->
+				let t =
+					if type_has_meta (Abstract.follow_with_abstracts_without_null t) Meta.NotNull then ctx.t.tnull t
+					else t
+				in
+				mk (TConst TNull) t p
 		) args in
 		let e = mk (TNew(c,tl,el)) (TInst(c,tl)) p in
 		mk (TBlock (List.rev (e :: (List.rev evars)))) e.etype e.epos

+ 17 - 0
tests/unit/src/unit/issues/Issue9177.hx

@@ -0,0 +1,17 @@
+package unit.issues;
+
+import unit.Test;
+
+class Issue9177 extends Test {
+	public function test() {
+		eq(123, ({}:C).x);
+	}
+}
+
+@:structInit
+private class C {
+	public var x:Int;
+	public function new(x:Int = 123) {
+		this.x = x;
+	}
+}