Browse Source

allow catching `@:runtimeValue` abstracts (closes #3948)

Simon Krajewski 10 years ago
parent
commit
c0a3985640
3 changed files with 39 additions and 6 deletions
  1. 1 0
      genneko.ml
  2. 27 0
      tests/unit/src/unit/issues/Issue3948.hx
  3. 11 6
      typer.ml

+ 1 - 0
genneko.ml

@@ -332,6 +332,7 @@ and gen_expr ctx e =
 				let path = (match follow v.v_type with
 					| TInst (c,_) -> Some c.cl_path
 					| TEnum (e,_) -> Some e.e_path
+					| TAbstract (a,_) -> Some a.a_path
 					| TDynamic _ -> None
 					| _ -> assert false
 				) in

+ 27 - 0
tests/unit/src/unit/issues/Issue3948.hx

@@ -0,0 +1,27 @@
+package unit.issues;
+
+class Issue3948 extends Test {
+	function test() {
+		eq("ok:true", throwBool(true));
+		eq("ok:false", throwBool(false));
+		eq("ok:12", throwInt(12));
+		eq("ok:-12", throwInt(-12));
+		eq("ok:0", throwInt(0));
+	}
+
+	function throwBool(b:Bool) {
+		return try {
+			throw b;
+		} catch(b:Bool) {
+			"ok:" + b;
+		}
+	}
+
+	function throwInt(i:Int) {
+		return try {
+			throw i;
+		} catch(i:Int) {
+			"ok:" + i;
+		}
+	}
+}

+ 11 - 6
typer.ml

@@ -3215,6 +3215,14 @@ and type_expr ctx (e,p) (with_type:with_type) =
 			| [] ->
 				()
 		in
+		let check_catch_type path params =
+			List.iter (fun pt ->
+				if pt != t_dynamic then error "Catch class parameter must be Dynamic" p;
+			) params;
+			(match path with
+			| x :: _ , _ -> x
+			| [] , name -> name)
+		in
 		let catches = List.fold_left (fun acc (v,t,e) ->
 			let t = Typeload.load_complex_type ctx (pos e) t in
 			let rec loop t = match follow t with
@@ -3222,12 +3230,9 @@ and type_expr ctx (e,p) (with_type:with_type) =
 					error "Cannot catch non-generic type parameter" p
 				| TInst ({ cl_path = path },params)
 				| TEnum ({ e_path = path },params) ->
-					List.iter (fun pt ->
-						if pt != t_dynamic then error "Catch class parameter must be Dynamic" p;
-					) params;
-					(match path with
-					| x :: _ , _ -> x
-					| [] , name -> name),t
+					check_catch_type path params,t
+				| TAbstract(a,params) when Meta.has Meta.RuntimeValue a.a_meta ->
+					check_catch_type a.a_path params,t
 				| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) ->
 					loop (Abstract.get_underlying_type a tl)
 				| TDynamic _ -> "",t