瀏覽代碼

improved dynamic-to-mono backtracking heuristic (fixed issue #487)

Nicolas Cannasse 14 年之前
父節點
當前提交
ccc589ecb5
共有 1 個文件被更改,包括 23 次插入9 次删除
  1. 23 9
      typer.ml

+ 23 - 9
typer.ml

@@ -649,24 +649,38 @@ let unify_int ctx e k =
 	let is_dynamic_field t f =
 		match follow t with
 		| TAnon a ->
-			(try is_dynamic (PMap.find f a.a_fields).cf_type with Not_found -> true)
-		| _ -> true
+			(try is_dynamic (PMap.find f a.a_fields).cf_type with Not_found -> false)
+		| TInst (c,pl) ->
+			(try is_dynamic (apply_params c.cl_types pl (fst (class_field c f))) with Not_found -> false)
+		| _ -> 
+			true
 	in
 	let is_dynamic_return t =
 		match follow t with
 		| TFun (_,r) -> is_dynamic r
 		| _ -> true
 	in
-	let maybe_dynamic_mono() =
+	(* 
+		This is some quick analysis that matches the most common cases of dynamic-to-mono convertions
+	*) 
+	let rec maybe_dynamic_mono e =
 		match e.eexpr with
-		| TLocal _ when not (is_dynamic e.etype)  -> false
-		| TArray({ etype = t },_) when not (is_dynamic_array t) -> false
-		| TField({ etype = t },f) when not (is_dynamic_field t f) -> false
-		| TCall({ etype = t },_) when not (is_dynamic_return t) -> false
-		| _ -> true
+		| TLocal _ -> is_dynamic e.etype
+		| TArray({ etype = t } as e,_) -> is_dynamic_array t || maybe_dynamic_rec e t
+		| TField({ etype = t } as e,f) -> is_dynamic_field t f || maybe_dynamic_rec e t
+		| TCall({ etype = t } as e,_) -> is_dynamic_return t || maybe_dynamic_rec e t
+		| TParenthesis e -> maybe_dynamic_mono e
+		| TIf (_,a,Some b) -> maybe_dynamic_mono a || maybe_dynamic_mono b		
+		| _ -> false
+	and maybe_dynamic_rec e t =
+		match follow t with
+		| TMono _ | TDynamic _ -> maybe_dynamic_mono e
+		(* we might have inferenced a tmono into a single field *)
+		| TAnon a when !(a.a_status) = Opened -> maybe_dynamic_mono e
+		| _ -> false
 	in
 	match k with
-	| KUnk | KDyn when maybe_dynamic_mono() ->
+	| KUnk | KDyn when maybe_dynamic_mono e ->
 		unify ctx e.etype ctx.t.tfloat e.epos;
 		false
 	| _ ->