[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