mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
This fixes github bug #98. compiler/polymorphism.m: Compiling gh98.m used to cause a compiler crash when the compiler tried to look up info about a typeclass_info variable that was needed in a call inside a lambda goal, but was not created inside the lambda goal. It should therefore have been listed as a nonlocal of the lambda goal, but it was not, because none of the variables inside the lambda goal had the typeclass constraint represented by that typeclass_info var on their types. And since later invocations of quantification may reduce, but may not expand, the set of nonlocals in a rhs_lambda_goal (as opposed to the nonlocals set of the unification whose RHS consists of that rhs_lambda_goal), this problem stuck. Fix this underestimation of the final lambda nonlocals set by including in it all typeinfo and/or typeclass_info vars in the updated lambda goal. Since this may then result in an overestimation, set a flag to force a requantification of the whole procedure body once its polymorphism transformation has been completed. compiler/polymorphism_info.m: Add a flag to force requantification. compiler/goal_util.m: Fix a misleading predicate name. compiler/hlds_goal.m: Fix documentation of rhs_lambda_goal. compiler/hlds_out_goal.m: Fix a layout problem in HLDS dumps. compiler/hlds_pred.m: compiler/lambda.m: Fix misleading variable names. tests/valid/gh98.m: Add the github test case. tests/valid/Mmakefile: Enable the new test case.
96 lines
3.4 KiB
Mathematica
96 lines
3.4 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Released by Transnat Games as public domain for testing purposes.
|
|
% Any copyright is dedicated to the Public Domain.
|
|
% https://creativecommons.org/publicdomain/zero/1.0/
|
|
%
|
|
% Crashes the following error when compiling:
|
|
% Uncaught Mercury exception:
|
|
% Software Error: map.lookup: key not found
|
|
% Key Type: term.var(parse_tree.prog_data.prog_var_type)
|
|
% Key Value: var(25)
|
|
% Value Type: hlds.hlds_goal.unify_mode
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module gh98.
|
|
|
|
:- interface.
|
|
|
|
:- use_module array.
|
|
:- use_module stream.
|
|
|
|
:- pred crash(Stream::in, stream.result(array.array(int), string)::out,
|
|
State::di, State::uo) is det
|
|
<= (stream.reader(Stream, int, State, Error), stream.error(Error)).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- use_module string.
|
|
|
|
% Just using stream.get in crash/4 doesn't trigger the crash.
|
|
:- pred get(Stream::in, stream.result(int, string)::out,
|
|
State::di, State::uo) is det
|
|
<= (stream.reader(Stream, int, State, Error), stream.error(Error)).
|
|
|
|
get(Stream, Result, !State) :-
|
|
stream.get(Stream, NResult, !State),
|
|
(
|
|
NResult = stream.eof,
|
|
Result = stream.eof
|
|
;
|
|
NResult = stream.error(Error),
|
|
Result = stream.error(stream.error_message(Error))
|
|
;
|
|
NResult = stream.ok(N),
|
|
Result = stream.ok(N)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Removing the typeclass constraint stops the crash.
|
|
:- pred crash_loop(Stream::in, int::in, int::out,
|
|
{stream.res(string), State}::di, {stream.res(string), State}::uo) is det
|
|
<= (stream.reader(Stream, int, State, Error), stream.error(Error)).
|
|
|
|
crash_loop(_Stream, _N, 0, {Result, !.State}, {Result, !:State}).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
crash(Stream, Result, !State) :-
|
|
get(Stream, LenResult, !State),
|
|
(
|
|
LenResult = stream.eof,
|
|
Result = stream.eof
|
|
;
|
|
LenResult = stream.error(Error),
|
|
Result = stream.error(Error)
|
|
;
|
|
LenResult = stream.ok(Len),
|
|
% The crash_loop predicate has two typeclass constraints on it,
|
|
% so it takes two typeclass_info arguments. The polymorphism
|
|
% transformation, when it converted this implicit lambda expression
|
|
% into an explicit lambda expression, did add both typeclass_infos
|
|
% to the start of crash_loop's argument list. The bug was that
|
|
% it included only one of them in the rhs_lambda_goal's nonlocal set,
|
|
% and quantification is not allowed to add any variables to that set.
|
|
% Since the actual source of that typeclass_info is the clause head
|
|
% (i.e. the crash predicate's own input arguments), this meant that
|
|
% one of crash_loop's argument variables was not in the map that
|
|
% the compiler tried to look it up in.
|
|
Closure = crash_loop(Stream),
|
|
array.generate_foldl(Len, Closure, Array,
|
|
{stream.ok, !.State}, {LoopResult, !:State}),
|
|
(
|
|
LoopResult = stream.error(Error),
|
|
Result = stream.error(Error)
|
|
;
|
|
LoopResult = stream.ok,
|
|
Result = stream.ok(Array)
|
|
)
|
|
).
|