浏览代码

allow constraint function type-parameter if it's only used for return type

Nicolas Cannasse 13 年之前
父节点
当前提交
346c3fcf1f
共有 2 个文件被更改,包括 27 次插入5 次删除
  1. 1 1
      std/haxe/EnumFlags.hx
  2. 26 4
      typeload.ml

+ 1 - 1
std/haxe/EnumFlags.hx

@@ -61,7 +61,7 @@ extern class EnumFlags<T:EnumValue> {
 	/**
 		Convert a integer bitflag into a typed one (this is a no-op, it doesn't have any impact on speed).
 	**/
-	public inline static function ofInt( i : Int ) : EnumFlags<Dynamic> {
+	public inline static function ofInt<T:EnumValue>( i : Int ) : EnumFlags<T> {
 		return cast i;
 	}
 

+ 26 - 4
typeload.ml

@@ -915,10 +915,32 @@ let init_class ctx c p herits fields =
 		| FFun fd ->
 			let params = ref [] in
 			params := List.map (fun (n,flags) ->
-				match flags with
-				| [] ->
-					type_type_params ctx ([],name) (fun() -> !params) p (n,[])
-				| _ -> error "This notation is not allowed because it can't be checked" p
+				(match flags with
+				| [] -> ()
+				| _ ->
+					(** look if the type is contained into arguments **)
+					let rec lookup_type t =
+						match t with
+						| CTPath { tpackage = []; tname = n2 } when n = n2 -> true
+						| CTPath p -> List.exists lookup_tparam p.tparams
+						| CTFunction (cl,r) -> List.exists lookup_type (r::cl)
+						| CTExtend (_,fl) | CTAnonymous fl -> List.exists lookup_cfield fl
+						| CTOptional t | CTParent t -> lookup_type t						
+					and lookup_cfield f =
+						match f.cff_kind with
+						| FVar (None,_) -> false
+						| FProp (_,_,t,_) | FVar (Some t,_) -> lookup_type t
+						| FFun f -> lookup_fun f
+					and lookup_fun f =
+						List.exists (fun (_,_,t,_) -> match t with None -> false | Some t -> lookup_type t) f.f_args || 
+						List.exists (fun (_,tl) -> List.exists lookup_type tl) f.f_params ||
+						(match f.f_type with None -> false | Some t -> lookup_type t)
+					and lookup_tparam = function
+						| TPType t -> lookup_type t
+						| TPExpr _ -> false
+					in
+					if lookup_fun { fd with f_type = None; f_params = [] } then error "This notation is not allowed because it can't be checked" p);
+				type_type_params ctx ([],name) (fun() -> !params) p (n,flags)
 			) fd.f_params;
 			let params = !params in
 			if inline && c.cl_interface then error "You can't declare inline methods in interfaces" p;