mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-09 19:02:18 +00:00
Fix some bugs in lambda.m.
Estimated hours taken: 4 Fix some bugs in lambda.m. compiler/lambda.m: Fix a bug: in some cases (the cases when it avoided introducing a new predicate), lambda.m was not setting the `address_taken' field correctly. A fix for the MLDS back-end: the optimization of assuming that the calling convention for `model_det' is compatible with the calling convention for `model_non' is not valid if the `--high-level-code' option is set. Update an obsolete comment. compiler/hlds_pred.m: Add a new predicate `proc_info_set_address_taken', for use by lambda.m. tests/hard_coded/deep_copy_bug.m: tests/hard_coded/deep_copy_bug.exp: Add some more regression tests to test the above-mentioned bugs.
This commit is contained in:
@@ -1482,6 +1482,9 @@ compute_arg_types_modes([Var | Vars], VarTypes, InstMap0, InstMap,
|
||||
:- pred proc_info_is_address_taken(proc_info, is_address_taken).
|
||||
:- mode proc_info_is_address_taken(in, out) is det.
|
||||
|
||||
:- pred proc_info_set_address_taken(proc_info, is_address_taken, proc_info).
|
||||
:- mode proc_info_set_address_taken(in, in, out) is det.
|
||||
|
||||
:- pred proc_info_get_rl_exprn_id(proc_info, maybe(rl_exprn_id)).
|
||||
:- mode proc_info_get_rl_exprn_id(in, out) is det.
|
||||
|
||||
@@ -1963,6 +1966,12 @@ proc_info_set_maybe_termination_info(ProcInfo0, R, ProcInfo) :-
|
||||
ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
|
||||
P, Q, R, S, T, U).
|
||||
|
||||
proc_info_set_address_taken(ProcInfo0, T, ProcInfo) :-
|
||||
ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
|
||||
P, Q, R, S, _, U),
|
||||
ProcInfo = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
|
||||
P, Q, R, S, T, U).
|
||||
|
||||
proc_info_set_rl_exprn_id(ProcInfo0, U, ProcInfo) :-
|
||||
ProcInfo0 = procedure(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
|
||||
P, Q, R, S, T, _),
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
% Similarly, a lambda expression may not bind any of the type_infos for
|
||||
% those variables; that is, none of the non-local variables
|
||||
% should be existentially typed (from the perspective of the lambda goal).
|
||||
% When we run the polymorphism.m pass before mode checking, this will
|
||||
% be checked by mode analysis. XXX But currently it is not checked.
|
||||
% Now that we run the polymorphism.m pass before mode checking, this is
|
||||
% also checked by mode analysis.
|
||||
%
|
||||
% It might be OK to allow the parameters of the lambda goal to be
|
||||
% existentially typed, but currently that is not supported.
|
||||
@@ -373,10 +373,15 @@ lambda__process_lambda(PredOrFunc, EvalMethod, Vars, Modes, Detism,
|
||||
% Check that the code models are compatible.
|
||||
% Note that det is not compatible with semidet,
|
||||
% and semidet is not compatible with nondet,
|
||||
% since the arguments go in different registers.
|
||||
% But det is compatible with nondet.
|
||||
% since the calling conventions are different.
|
||||
% But if we're using the LLDS back-end
|
||||
% (i.e. not --high-level-code),
|
||||
% det is compatible with nondet.
|
||||
( CodeModel = Call_CodeModel
|
||||
; CodeModel = model_non, Call_CodeModel = model_det
|
||||
; CodeModel = model_non, Call_CodeModel = model_det,
|
||||
module_info_globals(ModuleInfo0, Globals),
|
||||
globals__lookup_bool_option(Globals,
|
||||
highlevel_code, no)
|
||||
),
|
||||
% check that the curried arguments are all input
|
||||
proc_info_argmodes(Call_ProcInfo, Call_ArgModes),
|
||||
@@ -390,10 +395,17 @@ lambda__process_lambda(PredOrFunc, EvalMethod, Vars, Modes, Detism,
|
||||
PredId = PredId0,
|
||||
ProcId = ProcId0,
|
||||
PredName = PredName0,
|
||||
ModuleInfo = ModuleInfo0,
|
||||
NumArgVars = NumInitialVars,
|
||||
mode_util__modes_to_uni_modes(CurriedArgModes, CurriedArgModes,
|
||||
ModuleInfo0, UniModes)
|
||||
ModuleInfo0, UniModes),
|
||||
%
|
||||
% we need to mark the procedure as having had its
|
||||
% address taken
|
||||
%
|
||||
proc_info_set_address_taken(Call_ProcInfo, address_is_taken,
|
||||
Call_NewProcInfo),
|
||||
module_info_set_pred_proc_info(ModuleInfo0, PredId, ProcId,
|
||||
Call_PredInfo, Call_NewProcInfo, ModuleInfo)
|
||||
;
|
||||
% Prepare to create a new predicate for the lambda
|
||||
% expression: work out the arguments, module name, predicate
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
[var(1), var(2), var(3), var(4), var(5), var(6), var(7), var(8), var(9), var(10)]
|
||||
[var(1), var(2), var(3), var(4), var(5), var(6), var(7), var(8), var(9), var(10)]
|
||||
[42]
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
|
||||
:- import_module int, std_util, list, term, varset.
|
||||
|
||||
main -->
|
||||
main --> test1, test2, test3.
|
||||
|
||||
:- pred test1(io__state::di, io__state::uo) is det.
|
||||
test1 -->
|
||||
{ Lambda = lambda([X::out] is nondet,
|
||||
(
|
||||
varset__init(Varset0),
|
||||
@@ -24,3 +27,31 @@ main -->
|
||||
{ solutions(Lambda, List) },
|
||||
io__write(List),
|
||||
io__write_string("\n").
|
||||
|
||||
:- pred test2(io__state::di, io__state::uo) is det.
|
||||
test2 -->
|
||||
test2b("blahblah").
|
||||
|
||||
:- pred test2b(T::in, io__state::di, io__state::uo) is det.
|
||||
test2b(S) -->
|
||||
{ F = foo(S) },
|
||||
{ solutions(F, List) },
|
||||
io__write(List),
|
||||
io__write_string("\n").
|
||||
|
||||
:- pred foo(T, var).
|
||||
:- mode foo(in, out) is nondet.
|
||||
foo(Blah, X) :-
|
||||
varset__init(Varset0),
|
||||
varset__new_vars(Varset0, 10, Vars, _),
|
||||
list__member(X, Vars).
|
||||
|
||||
:- pred test3(io__state::di, io__state::uo) is det.
|
||||
test3 -->
|
||||
{ solutions((pred(X::out) is nondet :- bar(X)), List) },
|
||||
io__write(List),
|
||||
io__write_string("\n").
|
||||
|
||||
:- pred bar(int).
|
||||
:- mode bar(out) is det.
|
||||
bar(42).
|
||||
|
||||
Reference in New Issue
Block a user