mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-18 19:03:45 +00:00
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.
38 lines
1.2 KiB
Mathematica
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).
|