Files
mercury/tests/valid/inlining_bug.m
Simon Taylor 4ab55e32a5 Fix a bug in the optimization where polymorphism.m passes a
Estimated hours taken: 5

Fix a bug in the optimization where polymorphism.m passes a
base_type_info in place of a type_info for non-polymorphic types.
The type of the variable was `base_type_info' not `type_info'.
This caused inlining.m to be unable to compute a type substitution,
and code_util__cons_id_to_tag aborted on an unsubstituted type
variable.

compiler/mercury_builtin.m
compiler/code_util.m
	Add a new builtin, unsafe_type_cast/2, used by common.m
	to preserve type correctness.
	Make unsafe_promise_unique/2 a builtin, since it is basically
	the same as unsafe_type_cast/2.

compiler/polymorphism.m
	Set the type of a `base_type_info' passed where a `type_info'
	is expected to `type_info'.
	Don't add the type_info argument for unsafe_type_cast, since it is
	not needed and would make the code in common.m more complicated.

compiler/common.m
	Generate a call to unsafe_type_cast rather than an assignment
	unification when the assignment would not be type correct.

tests/valid/inlining_bug.m
	Regression test.

tests/general/common_type_cast.m
tests/general/common_type_cast.exp
	Test of type casts.
1998-02-25 00:12:16 +00:00

38 lines
1.2 KiB
Mathematica

%
% Regression test for an abort in code generation.
% When the actual type for a polymorphic argument is non-polymorphic,
% only the base_type_info is passed, avoiding the construction of
% a type_info. The problem was that the type of the type_info argument
% was being set to `mercury_builtin:base_type_info' rather than
% `type_info'. In the code to compute the type substitution in inlining,
% type_list_subsumes failed on the argument types, and no substitution
% was produced. code_util__cons_id_to_tag then aborted when asked to
% find the tag for a constructor of a variable type.
%
:- module inlining_bug.
:- interface.
:- pred calling_pred(int::in) is semidet.
:- implementation.
:- import_module int, list.
:- type my_pair(A) ---> pair(A, A).
calling_pred(_) :-
Plus1 = lambda([Int0::in, IntPair::out] is det,
IntPair = pair(Int0, Int0)),
called_pred(Plus1, [1,2,3], [X | Ys]),
X = pair(2, 2),
Ys = [pair(3, 3), pair(4, 4)].
:- pred called_pred(pred(T, U), list(T), list(U)) is det.
:- mode called_pred(pred(in, out) is det, in, out) is semidet.
:- pragma inline(called_pred/3).
called_pred(P, [A | As], [B | Bs]) :-
call(P, A, B),
list__map(P, As, Bs).