aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/boot/me/type.ml38
-rw-r--r--src/test/run-pass/obj-return-polytypes.rs16
3 files changed, 41 insertions, 14 deletions
diff --git a/src/Makefile b/src/Makefile
index 9a24b270..94c42c9c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -437,6 +437,7 @@ TEST_XFAILS_LLVM := $(addprefix test/run-pass/, \
obj-drop.rs \
obj-dtor.rs \
obj-recursion.rs \
+ obj-return-polytypes.rs \
obj-with-vec.rs \
opeq.rs \
output-slot-variants.rs \
diff --git a/src/boot/me/type.ml b/src/boot/me/type.ml
index 9efaa8f6..20f2443d 100644
--- a/src/boot/me/type.ml
+++ b/src/boot/me/type.ml
@@ -845,20 +845,24 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit =
Stack.push fn_ctx fn_ctx_stack
in
+ let push_fn_ctx_of_ty_fn (ty_fn:Ast.ty_fn) : unit =
+ let (ty_sig, ty_fn_aux) = ty_fn in
+ let ret_ty = ty_sig.Ast.sig_output_slot.Ast.slot_ty in
+ let is_iter = ty_fn_aux.Ast.fn_is_iter in
+ push_fn_ctx (Common.option_get ret_ty) is_iter
+ in
+
let visit_mod_item_pre _ _ item =
- match item.Common.node.Ast.decl_item with
+ let { Common.node = item; Common.id = item_id } = item in
+ match item.Ast.decl_item with
Ast.MOD_ITEM_fn _ ->
- let id = item.Common.id in
+ let fn_ty = Hashtbl.find cx.Semant.ctxt_all_item_types item_id in
begin
- match Hashtbl.find cx.Semant.ctxt_all_item_types id with
- Ast.TY_fn (ty_sig, ty_fn_aux) ->
- let ret_ty = ty_sig.Ast.sig_output_slot.Ast.slot_ty in
- let is_iter = ty_fn_aux.Ast.fn_is_iter in
- push_fn_ctx (Common.option_get ret_ty) is_iter
+ match fn_ty with
+ Ast.TY_fn ty_fn -> push_fn_ctx_of_ty_fn ty_fn
| _ ->
- Common.bug
- ()
- "Type.visit_mod_item_pre: fn item doesn't have a fn type"
+ Common.bug ()
+ "Type.visit_mod_item_pre: fn item didn't have a fn type"
end
| _ -> ()
in
@@ -869,10 +873,16 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit =
| _ -> ()
in
- let visit_obj_fn_pre _ _ fn =
- let fn = fn.Common.node in
- let ret_ty = fn.Ast.fn_output_slot.Common.node.Ast.slot_ty in
- push_fn_ctx (Common.option_get ret_ty) fn.Ast.fn_aux.Ast.fn_is_iter
+ let visit_obj_fn_pre obj ident _ =
+ let obj_ty = Hashtbl.find cx.Semant.ctxt_all_item_types obj.Common.id in
+ match obj_ty with
+ Ast.TY_fn ({ Ast.sig_output_slot =
+ { Ast.slot_ty = Some (Ast.TY_obj (_, methods)) } }, _) ->
+ push_fn_ctx_of_ty_fn (Hashtbl.find methods ident)
+ | _ ->
+ Common.bug ()
+ "Type.visit_obj_fn_pre: item doesn't have an object type (%a)"
+ Ast.sprintf_ty obj_ty
in
let visit_obj_fn_post _ _ _ = ignore (Stack.pop fn_ctx_stack) in
diff --git a/src/test/run-pass/obj-return-polytypes.rs b/src/test/run-pass/obj-return-polytypes.rs
new file mode 100644
index 00000000..78897d7e
--- /dev/null
+++ b/src/test/run-pass/obj-return-polytypes.rs
@@ -0,0 +1,16 @@
+// -*- rust -*-
+
+type clam[T] = tag(signed(int), unsigned(uint));
+
+fn getclam[T]() -> clam[T] {
+ ret signed[T](42);
+}
+
+obj impatience[T]() {
+ fn moreclam() -> clam[T] {
+ be getclam[T]();
+ }
+}
+
+fn main() {}
+