Forráskód Böngészése

detect abstract chains (closes #2657)

Simon Krajewski 11 éve
szülő
commit
1075f30d52
1 módosított fájl, 21 hozzáadás és 4 törlés
  1. 21 4
      codegen.ml

+ 21 - 4
codegen.ml

@@ -633,18 +633,35 @@ module Abstract = struct
 	let find_from ab pl a b = List.find (Type.unify_from_field ab pl a b) ab.a_from
 
 	let cast_stack = ref []
-
-	let get_underlying_type a pl =
+	let underlying_type_stack = ref []
+
+	let rec get_underlying_type a pl =
+		let maybe_recurse t =
+			underlying_type_stack := a :: !underlying_type_stack;
+			let t = match follow t with
+				| TAbstract(a,tl) ->
+					if List.mem a !underlying_type_stack then begin
+						let s = String.concat " -> " (List.map (fun a -> s_type_path a.a_path) (List.rev (a :: !underlying_type_stack))) in
+						(* technically this should be done at type declaration level *)
+						error ("Abstract chain detected: " ^ s) a.a_pos
+					end;
+					get_underlying_type a tl
+				| _ ->
+					t
+			in
+			underlying_type_stack := List.tl !underlying_type_stack;
+			t
+		in
 		try
 			if not (Meta.has Meta.MultiType a.a_meta) then raise Not_found;
 			let m = mk_mono() in
 			let _ = find_to a pl m in
-			follow m
+			maybe_recurse (follow m)
 		with Not_found ->
 			if Meta.has Meta.CoreType a.a_meta then
 				t_dynamic
 			else
-				apply_params a.a_types pl a.a_this
+				maybe_recurse (apply_params a.a_types pl a.a_this)
 
 	let make_static_call ctx c cf a pl args t p =
 		let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in