[m-rev.] for review: fix lambda expansion misordered arguments
Peter Wang
novalazy at gmail.com
Tue Sep 27 16:27:20 AEST 2011
[in particular the statement about the rhs_lambda_goal nonlocals list]
Branches: main, 11.07
The lambda expansion pass sometimes created predicates with misordered
arguments, e.g. in a different order to that of the modes, and with type_info
variables not at the front of the list. I noticed this problem when compiling
exception.m.
`expand_lambda' creates a map from corresponding lists of OrigVars and
OrigArgModes. OrigVars was taken from a `unify_rhs.rhs_lambda_goal' term,
whereas OrigArgModes is derived from the uni_modes of a `unification.construct'
term.
compiler/lambda.m:
Take OrigVars from the list of arguments in the `unification.construct'
term, which must be in the same order as the list of uni_modes right
next to it.
Add sanity check.
compiler/hlds_goal.m:
State that the `rhs_lambda_goal' nonlocals list is in no particular
order.
diff --git a/compiler/hlds_goal.m b/compiler/hlds_goal.m
index fb708e9..5b10e4b 100644
--- a/compiler/hlds_goal.m
+++ b/compiler/hlds_goal.m
@@ -729,7 +729,7 @@
rhs_eval_method :: lambda_eval_method,
% Non-locals of the goal excluding the lambda quantified
- % variables.
+ % variables, in no particular order.
rhs_nonlocals :: list(prog_var),
% Lambda quantified variables.
diff --git a/compiler/lambda.m b/compiler/lambda.m
index 9da9fa8..039c924 100644
--- a/compiler/lambda.m
+++ b/compiler/lambda.m
@@ -382,10 +382,18 @@ expand_lambda(Purity, _Groundness, PredOrFunc, EvalMethod, Vars, Modes,
set_of_var.insert_list(Vars, LambdaGoalNonLocals, LambdaNonLocals),
goal_util.extra_nonlocal_typeinfos(RttiVarMaps, VarTypes, ExistQVars,
LambdaNonLocals, ExtraTypeInfos),
- OrigVars = OrigNonLocals0,
(
- Unification0 = construct(Var, _, _, UniModes0, _, _, _)
+ Unification0 = construct(Var, _, OrigNonLocals1, UniModes0, _, _, _),
+ % We use to use OrigVars = OrigNonLocals0 (from rhs_lambda_goal) but
+ % the order of the variables does not necessarily match UniModes0.
+ OrigVars = OrigNonLocals1,
+ trace [compiletime(flag("lambda_var_order"))] (
+ list.sort(OrigNonLocals0, SortedOrigNonLocals0),
+ list.sort(OrigNonLocals1, SortedOrigNonLocals1),
+ expect(unify(SortedOrigNonLocals0, SortedOrigNonLocals1),
+ $module, $pred, "OrigNonLocals0 != OrigNonLocals1")
+ )
;
( Unification0 = deconstruct(_, _, _, _, _, _)
; Unification0 = assign(_, _)
@@ -539,6 +547,8 @@ expand_lambda(Purity, _Groundness, PredOrFunc, EvalMethod, Vars, Modes,
list.append(ArgModes1, Modes, AllArgModes),
map.apply_to_list(AllArgVars, VarTypes, ArgTypes),
+ list.foldl_corresponding(check_lambda_arg_type_and_mode(ModuleInfo1),
+ ArgTypes, AllArgModes, 0, _),
purity_to_markers(Purity, LambdaMarkers),
@@ -621,6 +631,26 @@ uni_modes_to_modes([UniMode | UniModes], [Mode | Modes]) :-
Mode = (Initial1 -> Initial1),
uni_modes_to_modes(UniModes, Modes).
+ % Make sure the arguments and modes are not misordered. An obvious
+ % indicator is if a non-higher order argument is paired a higher order
+ % inst.
+ %
+:- pred check_lambda_arg_type_and_mode(module_info::in, mer_type::in,
+ mer_mode::in, T::in, T::out) is det.
+
+check_lambda_arg_type_and_mode(ModuleInfo, Type, Mode, !T) :-
+ Inst = mode_get_initial_inst(ModuleInfo, Mode),
+ ( Inst = ground(_, higher_order(_)) ->
+ ( type_is_higher_order(Type) ->
+ true
+ ;
+ unexpected($module, $pred,
+ "non-higher order argument with higher order inst")
+ )
+ ;
+ true
+ ).
+
%---------------------------------------------------------------------------%
% The proc_info has several maps that refer to variables. After lambda
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list