Browse Source

[typer] delay interface unification too

closes #9784
Simon Krajewski 5 years ago
parent
commit
8465bd7185

+ 22 - 20
src/typing/typeloadCheck.ml

@@ -353,26 +353,28 @@ module Inheritance = struct
 					else
 					else
 						t2, f2
 						t2, f2
 				in
 				in
-				ignore(follow f2.cf_type); (* force evaluation *)
-				let p = f2.cf_name_pos in
-				let mkind = function
-					| MethNormal | MethInline -> 0
-					| MethDynamic -> 1
-					| MethMacro -> 2
-				in
-				if (has_class_field_flag f CfPublic) && not (has_class_field_flag f2 CfPublic) && not (Meta.has Meta.CompilerGenerated f.cf_meta) then
-					display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
-				else if not (unify_kind f2.cf_kind f.cf_kind) || not (match f.cf_kind, f2.cf_kind with Var _ , Var _ -> true | Method m1, Method m2 -> mkind m1 = mkind m2 | _ -> false) then
-					display_error ctx ("Field " ^ i ^ " has different property access than in " ^ s_type_path intf.cl_path ^ " (" ^ s_kind f2.cf_kind ^ " should be " ^ s_kind f.cf_kind ^ ")") p
-				else try
-					valid_redefinition ctx f2 t2 f (apply_params intf.cl_params params f.cf_type)
-				with
-					Unify_error l ->
-						if not (Meta.has Meta.CsNative c.cl_meta && (has_class_flag c CExtern)) then begin
-							display_error ctx ("Field " ^ i ^ " has different type than in " ^ s_type_path intf.cl_path) p;
-							display_error ctx (compl_msg "Interface field is defined here") f.cf_pos;
-							display_error ctx (compl_msg (error_msg (Unify l))) p;
-						end
+				delay ctx PForce (fun () ->
+					ignore(follow f2.cf_type); (* force evaluation *)
+					let p = f2.cf_name_pos in
+					let mkind = function
+						| MethNormal | MethInline -> 0
+						| MethDynamic -> 1
+						| MethMacro -> 2
+					in
+					if (has_class_field_flag f CfPublic) && not (has_class_field_flag f2 CfPublic) && not (Meta.has Meta.CompilerGenerated f.cf_meta) then
+						display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
+					else if not (unify_kind f2.cf_kind f.cf_kind) || not (match f.cf_kind, f2.cf_kind with Var _ , Var _ -> true | Method m1, Method m2 -> mkind m1 = mkind m2 | _ -> false) then
+						display_error ctx ("Field " ^ i ^ " has different property access than in " ^ s_type_path intf.cl_path ^ " (" ^ s_kind f2.cf_kind ^ " should be " ^ s_kind f.cf_kind ^ ")") p
+					else try
+						valid_redefinition ctx f2 t2 f (apply_params intf.cl_params params f.cf_type)
+					with
+						Unify_error l ->
+							if not (Meta.has Meta.CsNative c.cl_meta && (has_class_flag c CExtern)) then begin
+								display_error ctx ("Field " ^ i ^ " has different type than in " ^ s_type_path intf.cl_path) p;
+								display_error ctx (compl_msg "Interface field is defined here") f.cf_pos;
+								display_error ctx (compl_msg (error_msg (Unify l))) p;
+							end
+				)
 			with
 			with
 				| Not_found when (has_class_flag c CAbstract) ->
 				| Not_found when (has_class_flag c CAbstract) ->
 					let cf = {f with cf_overloads = []} in
 					let cf = {f with cf_overloads = []} in

+ 1 - 1
tests/misc/projects/Issue9010/InterfaceFields-fail.hxml.stderr

@@ -1,3 +1,3 @@
 InterfaceFields.hx:1: characters 7-22 : Field missing needed by IFace is missing
 InterfaceFields.hx:1: characters 7-22 : Field missing needed by IFace is missing
+InterfaceFields.hx:5: characters 18-27 : Field wrongKind has different property access than in IFace (method should be var)
 InterfaceFields.hx:4: characters 13-24 : Field wrongAccess has different property access than in IFace ((never,null) should be (default,null))
 InterfaceFields.hx:4: characters 13-24 : Field wrongAccess has different property access than in IFace ((never,null) should be (default,null))
-InterfaceFields.hx:5: characters 18-27 : Field wrongKind has different property access than in IFace (method should be var)

+ 21 - 0
tests/unit/src/unit/issues/Issue9784.hx

@@ -0,0 +1,21 @@
+package unit.issues;
+
+private class C implements I {
+	public var v(get,never):String;
+	function get_v():String return "";
+
+	public function f(i:I) {
+		trace(i.v); // Could not resolve accessor
+	}
+}
+
+private interface I {
+	var v(get,never):String;
+	function f(i:I):Void;
+}
+
+class Issue9784 extends unit.Test {
+	function test() {
+		utest.Assert.pass();
+	}
+}