Skip to content

Commit 67d4e94

Browse files
committed
Callref bugfix in interpreter and sep compiler + autosav
~~~~nitish class A[E] fun foo: A[E] do return self fun bar: Fun0[A[E]] do return &foo # it didn't work before end ~~~~ - Fixed a bug when `self` was a generic class with unsolved type. It was impossible to return a callref, since the typing rule were not properly executed. - Added a test case in `test_callref.res` - Still need to fix the global and erasure compiler Signed-off-by: Louis-Vincent Boudreault <lv.boudreault95@gmail.com>
1 parent 0709376 commit 67d4e94

File tree

5 files changed

+42
-19
lines changed

5 files changed

+42
-19
lines changed

src/compiler/separate_compiler.nit

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,9 +2213,6 @@ class SeparateCompilerVisitor
22132213

22142214
# The class of the concrete Routine must exist (e.g ProcRef0, FunRef0, etc.)
22152215
self.require_declaration("class_{routine_mclass.c_name}")
2216-
self.require_declaration("type_{routine_type.c_name}")
2217-
2218-
compiler.undead_types.add(routine_type)
22192216
self.require_declaration(mmethoddef.c_name)
22202217

22212218
var thunk_function = mmethoddef.callref_thunk(my_recv_mclass_type)
@@ -2235,10 +2232,19 @@ class SeparateCompilerVisitor
22352232
self.require_declaration(thunk_function.c_name)
22362233
compiler.thunk_todo(thunk_function)
22372234
end
2238-
2239-
# Each RoutineRef points to a receiver AND a callref_thunk
2240-
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)
2241-
#debug "LEAVING ref_instance"
2235+
var res: RuntimeVariable
2236+
if routine_type.need_anchor then
2237+
hardening_live_open_type(routine_type)
2238+
link_unresolved_type(self.frame.mpropdef.mclassdef, routine_type)
2239+
var recv2 = self.frame.arguments.first
2240+
var recv2_type_info = self.type_info(recv2)
2241+
self.require_declaration(routine_type.const_color)
2242+
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)
2243+
else
2244+
self.require_declaration("type_{routine_type.c_name}")
2245+
compiler.undead_types.add(routine_type)
2246+
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)
2247+
end
22422248
return res
22432249
end
22442250

src/interpreter/naive_interpreter.nit

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2295,8 +2295,12 @@ redef class ACallrefExpr
22952295
do
22962296
var recv = v.expr(self.n_expr)
22972297
if recv == null then return null
2298+
var mtype = self.mtype
22982299
assert mtype != null
2299-
var inst = new CallrefInstance(mtype.as(not null), recv, callsite.as(not null))
2300+
# In case we are in generic class where formal parameter can not
2301+
# be resolved.
2302+
var mtype2 = v.unanchor_type(mtype)
2303+
var inst = new CallrefInstance(mtype2, recv, callsite.as(not null))
23002304
return inst
23012305
end
23022306
end

src/semantize/typing.nit

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ private class TypeVisitor
181181
return self.visit_expr_subtype(nexpr, self.type_bool(nexpr))
182182
end
183183

184-
185184
fun check_expr_cast(node: ANode, nexpr: AExpr, ntype: AType): nullable MType
186185
do
187186
var sub = nexpr.mtype
@@ -424,7 +423,6 @@ private class TypeVisitor
424423
return build_callsite_by_name(node, recvtype, name, recv_is_self)
425424
end
426425

427-
428426
# Visit the expressions of args and check their conformity with the corresponding type in signature
429427
# The point of this method is to handle varargs correctly
430428
# Note: The signature must be correctly adapted
@@ -445,7 +443,6 @@ private class TypeVisitor
445443
# Other cases are managed later
446444
end
447445

448-
449446
#debug("CALL {unsafe_type}.{msignature}")
450447

451448
# Associate each parameter to a position in the arguments
@@ -1177,7 +1174,6 @@ redef class AVarReassignExpr
11771174
end
11781175
end
11791176

1180-
11811177
redef class AContinueExpr
11821178
redef fun accept_typing(v)
11831179
do
@@ -1503,7 +1499,6 @@ redef class AAndExpr
15031499
end
15041500
end
15051501

1506-
15071502
redef class ANotExpr
15081503
redef fun accept_typing(v)
15091504
do
@@ -2074,7 +2069,6 @@ redef class AUnaryopExpr
20742069
redef fun compute_raw_arguments do return new Array[AExpr]
20752070
end
20762071

2077-
20782072
redef class ACallExpr
20792073
redef fun property_name do return n_qid.n_id.text
20802074
redef fun property_node do return n_qid
@@ -2215,11 +2209,24 @@ redef class ACallrefExpr
22152209
# end
22162210
#
22172211
# var a = new A[Int]
2218-
# var f = &a.toto <- without anchor : ProcRef1[E]
2219-
# ^--- with anchor : ProcRef[Int]
2212+
# var f = &a.toto # without anchor : ProcRef1[E]
2213+
# # with anchor : ProcRef[Int]
22202214
# ~~~~
2221-
var routine_type = routine_mclass.get_mtype(types_list).anchor_to(v.mmodule, recv.as(MClassType))
2222-
2215+
# However, we can only anchor if we can resolve every formal
2216+
# parameter, here's an example where we can't.
2217+
# ~~~~nitish
2218+
# class A[E]
2219+
# fun bar: A[E] do return self
2220+
# fun foo: Fun0[A[E]] do return &bar # here we can't anchor
2221+
# end
2222+
# var f1 = a1.foo # when this expression will be evaluated,
2223+
# # `a1` will anchor `&bar` returned by `foo`.
2224+
# print f1.call
2225+
# ~~~~
2226+
var routine_type = routine_mclass.get_mtype(types_list)
2227+
if not recv.need_anchor then
2228+
routine_type = routine_type.anchor_to(v.mmodule, recv.as(MClassType))
2229+
end
22232230
is_typed = true
22242231
self.mtype = routine_type
22252232
end
@@ -2509,7 +2516,6 @@ redef class AAttrExpr
25092516
end
25102517
end
25112518

2512-
25132519
redef class AAttrAssignExpr
25142520
redef fun accept_typing(v)
25152521
do

tests/sav/test_callref.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ x is null
1111
x is null
1212
x is test
1313
x is 100
14+
x is 100

tests/test_callref.nit

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ class C[E]
5757
end
5858
return "x is null"
5959
end
60+
61+
fun bar: C[E] do return self
62+
fun foo: Fun0[C[E]] do return &bar
6063
end
6164

6265
var a = new A
@@ -102,3 +105,6 @@ c2.x = 100
102105

103106
print f6.call # "x is test"
104107
print f7.call # "x is 100"
108+
109+
var f8 = c2.foo
110+
print f8.call # "x is 100"

0 commit comments

Comments
 (0)