thunk.polymorph_call_flag = not my_recv.is_exact
compiler.todo(method)
compiler.todo(thunk)
-
- var res = self.new_expr("NEW_{routine_mclass_type.c_name}({my_recv}, &{thunk.c_name})", routine_mclass_type)
+ var ret_type = self.anchor(routine_mclass_type).as(MClassType)
+ var res = self.new_expr("NEW_{ret_type.c_name}({my_recv}, &{thunk.c_name})", ret_type)
return res
end
# The class of the concrete Routine must exist (e.g ProcRef0, FunRef0, etc.)
self.require_declaration("class_{routine_mclass.c_name}")
- self.require_declaration("type_{routine_type.c_name}")
-
- compiler.undead_types.add(routine_type)
self.require_declaration(mmethoddef.c_name)
var thunk_function = mmethoddef.callref_thunk(my_recv_mclass_type)
self.require_declaration(thunk_function.c_name)
compiler.thunk_todo(thunk_function)
end
-
- # Each RoutineRef points to a receiver AND a callref_thunk
- var res = self.new_expr("NEW_{base_routine_mclass.c_name}({my_recv}, (nitmethod_t){c_ref}, &class_{routine_mclass.c_name}, &type_{routine_type.c_name})", routine_type)
- #debug "LEAVING ref_instance"
+ var res: RuntimeVariable
+ if routine_type.need_anchor then
+ hardening_live_open_type(routine_type)
+ link_unresolved_type(self.frame.mpropdef.mclassdef, routine_type)
+ var recv2 = self.frame.arguments.first
+ var recv2_type_info = self.type_info(recv2)
+ self.require_declaration(routine_type.const_color)
+ res = self.new_expr("NEW_{base_routine_mclass.c_name}({my_recv}, (nitmethod_t){c_ref}, &class_{routine_mclass.c_name}, {recv2_type_info}->resolution_table->types[{routine_type.const_color}])", routine_type)
+ else
+ self.require_declaration("type_{routine_type.c_name}")
+ compiler.undead_types.add(routine_type)
+ res = self.new_expr("NEW_{base_routine_mclass.c_name}({my_recv}, (nitmethod_t){c_ref}, &class_{routine_mclass.c_name}, &type_{routine_type.c_name})", routine_type)
+ end
return res
end
do
var recv = v.expr(self.n_expr)
if recv == null then return null
+ var mtype = self.mtype
assert mtype != null
- var inst = new CallrefInstance(mtype.as(not null), recv, callsite.as(not null))
+ # In case we are in generic class where formal parameter can not
+ # be resolved.
+ var mtype2 = v.unanchor_type(mtype)
+ var inst = new CallrefInstance(mtype2, recv, callsite.as(not null))
return inst
end
end
return self.visit_expr_subtype(nexpr, self.type_bool(nexpr))
end
-
fun check_expr_cast(node: ANode, nexpr: AExpr, ntype: AType): nullable MType
do
var sub = nexpr.mtype
return build_callsite_by_name(node, recvtype, name, recv_is_self)
end
-
# Visit the expressions of args and check their conformity with the corresponding type in signature
# The point of this method is to handle varargs correctly
# Note: The signature must be correctly adapted
# Other cases are managed later
end
-
#debug("CALL {unsafe_type}.{msignature}")
# Associate each parameter to a position in the arguments
end
end
-
redef class AContinueExpr
redef fun accept_typing(v)
do
end
end
-
redef class ANotExpr
redef fun accept_typing(v)
do
redef fun compute_raw_arguments do return new Array[AExpr]
end
-
redef class ACallExpr
redef fun property_name do return n_qid.n_id.text
redef fun property_node do return n_qid
# end
#
# var a = new A[Int]
- # var f = &a.toto <- without anchor : ProcRef1[E]
- # ^--- with anchor : ProcRef[Int]
+ # var f = &a.toto # without anchor : ProcRef1[E]
+ # # with anchor : ProcRef[Int]
# ~~~~
- var routine_type = routine_mclass.get_mtype(types_list).anchor_to(v.mmodule, recv.as(MClassType))
-
+ # However, we can only anchor if we can resolve every formal
+ # parameter, here's an example where we can't.
+ # ~~~~nitish
+ # class A[E]
+ # fun bar: A[E] do return self
+ # fun foo: Fun0[A[E]] do return &bar # here we can't anchor
+ # end
+ # var f1 = a1.foo # when this expression will be evaluated,
+ # # `a1` will anchor `&bar` returned by `foo`.
+ # print f1.call
+ # ~~~~
+ var routine_type = routine_mclass.get_mtype(types_list)
+ if not recv.need_anchor then
+ routine_type = routine_type.anchor_to(v.mmodule, recv.as(MClassType))
+ end
is_typed = true
self.mtype = routine_type
end
end
end
-
redef class AAttrAssignExpr
redef fun accept_typing(v)
do
x is null
x is test
x is 100
+x is 100
end
return "x is null"
end
+
+ fun bar: C[E] do return self
+ fun foo: Fun0[C[E]] do return &bar
end
var a = new A
print f6.call # "x is test"
print f7.call # "x is 100"
+
+var f8 = c2.foo
+print f8.call # "x is 100"