mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 23:05:21 +00:00
Estimated hours taken: 6 Fix a semantic hole. Previously, unique variables could be used as non-local variables inside a lambda goal and shared within that lambda. This fixes the problem by requiring that all non-local vars to a lambda must be ground-shared. compiler/modecheck_unify.m: Changes detailed above. compiler/mode_errors.m: Add a new kind of mode error, mode_error_non_local_lambda_var. One small change to find_important_errors/3 to ensure that this error will be reported if the lambda is an implicit call argument unification. compiler/inst_util.m: Export make_shared_inst_list/4 for use by modecheck_unify.m. compiler/instmap.m: New predicate: instmap__set_vars/4, which sets multiple vars in an instmap. tests/invalid/bind_var_errors.m: tests/invalid/bind_var_errors.err_exp: Regression test.
63 lines
1.0 KiB
Mathematica
63 lines
1.0 KiB
Mathematica
:- module bind_var_errors.
|
|
:- interface.
|
|
|
|
:- import_module int.
|
|
|
|
:- pred bind_var_in_negation is semidet.
|
|
|
|
:- pred bind_var_in_ite_cond(int :: in) is semidet.
|
|
|
|
:- pred bind_var_in_lambda is semidet.
|
|
|
|
:- pred share_var_in_lambda(T :: di) is det.
|
|
|
|
:- pred share_dead_var_in_lambda(T :: di) is det.
|
|
|
|
:- pred clobber_var_in_lambda(T :: di) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- pragma no_inline(consume/1).
|
|
:- pred consume(T :: in) is det.
|
|
consume(_).
|
|
|
|
:- pragma no_inline(destroy/1).
|
|
:- pred destroy(T :: di) is det.
|
|
destroy(_).
|
|
|
|
:- pragma no_inline(share/1).
|
|
:- pred share(T :: in) is det.
|
|
share(_).
|
|
|
|
bind_var_in_negation :-
|
|
\+ (X = 42),
|
|
consume(X).
|
|
|
|
bind_var_in_ite_cond(X) :-
|
|
(
|
|
X = 42,
|
|
Y = 42
|
|
->
|
|
true
|
|
;
|
|
true
|
|
),
|
|
consume(Y).
|
|
|
|
bind_var_in_lambda :-
|
|
call((pred) is det :- Y = 42),
|
|
consume(Y).
|
|
|
|
share_var_in_lambda(X) :-
|
|
call((pred) is det :- share(X)),
|
|
destroy(X).
|
|
|
|
% This one is OK since X is dead after the lambda.
|
|
share_dead_var_in_lambda(X) :-
|
|
call((pred) is det :- share(X)).
|
|
|
|
clobber_var_in_lambda(X) :-
|
|
call((pred) is det :- destroy(X)),
|
|
destroy(X).
|
|
|