浏览代码

resolve field access on type parameters that are constrained to abstracts (see #2343)

Simon Krajewski 11 年之前
父节点
当前提交
c57536a0e5
共有 5 个文件被更改,包括 43 次插入2 次删除
  1. 1 1
      gencs.ml
  2. 1 1
      genjava.ml
  3. 19 0
      tests/unit/issues/Issue2343.hx
  4. 2 0
      type.ml
  5. 20 0
      typer.ml

+ 1 - 1
gencs.ml

@@ -23,9 +23,9 @@
 open Gencommon.ReflectionCFs
 open Ast
 open Common
+open Type
 open Gencommon
 open Gencommon.SourceWriter
-open Type
 open Printf
 open Option
 open ExtString

+ 1 - 1
genjava.ml

@@ -24,9 +24,9 @@ open JData
 open Unix
 open Ast
 open Common
+open Type
 open Gencommon
 open Gencommon.SourceWriter
-open Type
 open Printf
 open Option
 open ExtString

+ 19 - 0
tests/unit/issues/Issue2343.hx

@@ -0,0 +1,19 @@
+package unit.issues;
+
+private abstract MyInt(Int) from Int {
+    public function work() return this;
+}
+
+private class Foo<T:MyInt> {
+	public var result:Int;
+    public function new(val : T) {
+        result = val.work();
+    }
+}
+
+class Issue2343 extends unit.Test {
+	function test() {
+		var foo = new Foo<MyInt>(1);
+		eq(1, foo.result);
+	}
+}

+ 2 - 0
type.ml

@@ -329,6 +329,8 @@ let mk_block e =
 	| TBlock (_ :: _) -> e
 	| _ -> mk (TBlock [e]) e.etype e.epos
 
+let mk_cast e t p = mk (TCast(e,None)) t p
+
 let null t p = mk (TConst TNull) t p
 
 let mk_mono() = TMono (ref None)

+ 20 - 0
typer.ml

@@ -1409,6 +1409,26 @@ and type_field ?(resume=false) ctx e i p mode =
 			using_field ctx mode e i p
 		with Not_found -> try
 			loop_dyn c params
+		with Not_found -> try
+			(* if we have an abstract constraint we have to check its static fields and recurse (issue #2343) *)
+			begin match c.cl_kind with
+				| KTypeParameter tl ->
+					let rec loop tl = match tl with
+						| t :: tl ->
+							begin match follow t with
+								| TAbstract({a_impl = Some c},tl) when PMap.mem i c.cl_statics ->
+									let e = mk_cast e t p in
+									type_field ctx e i p mode;
+								| _ ->
+									loop tl
+							end
+						| [] ->
+							raise Not_found
+					in
+					loop tl
+				| _ ->
+					raise Not_found
+			end
 		with Not_found ->
 			if PMap.mem i c.cl_statics then error ("Cannot access static field " ^ i ^ " from a class instance") p;
 			(*