Solve constraints together and in the order they are added #851

Merged
ghallak merged 6 commits from ghallak/358 into master 2021-12-16 20:54:07 +09:00
3 changed files with 31 additions and 5 deletions
Showing only changes of commit 6d7a1f9fe2 - Show all commits

View File

@ -2322,7 +2322,8 @@ solve_field_constraints(Env, Constraints) ->
-spec solve_ambiguous_field_constraints(env(), [field_constraint()]) -> ok. -spec solve_ambiguous_field_constraints(env(), [field_constraint()]) -> ok.
solve_ambiguous_field_constraints(Env, Constraints) -> solve_ambiguous_field_constraints(Env, Constraints) ->
Unknown = solve_known_record_types(Env, Constraints), NamedArgConstraints = get_named_argument_constraints(),
Unknown = solve_known_record_types(Env, Constraints, NamedArgConstraints),
if Unknown == [] -> ok; if Unknown == [] -> ok;
length(Unknown) < length(Constraints) -> length(Unknown) < length(Constraints) ->
%% progress! Keep trying. %% progress! Keep trying.
@ -2347,10 +2348,23 @@ solve_unknown_record_types(Env, Unknown) ->
false -> Solutions false -> Solutions
end. end.
-spec solve_known_record_types(env(), [field_constraint()]) -> [field_constraint()]. %% Since named argument constraints solving happens after field
solve_known_record_types(Env, Constraints) -> %% constraints solving, try to find if dereferencing a record type
%% is failing due to unsolved named argument constraint
dereference_or_solve_named_argument_constraints(Env, RecType, Cs) ->
case dereference(RecType) of
UVar = {uvar, _, R} ->
L = [DT || DT = #dependent_type_constraint{specialized_type = {uvar, _, STR}} <- Cs, STR == R],
solve_named_argument_constraints(Env, L),
dereference(UVar);
Type ->
Type
end.
-spec solve_known_record_types(env(), [field_constraint()], [named_argument_constraint()]) -> [field_constraint()].
solve_known_record_types(Env, Constraints, NamedArgConstraints) ->
DerefConstraints = DerefConstraints =
[ C#field_constraint{record_t = dereference(RecordType)} [ C#field_constraint{record_t = dereference_or_solve_named_argument_constraints(Env, RecordType, NamedArgConstraints)}
|| C = #field_constraint{record_t = RecordType} <- Constraints ], || C = #field_constraint{record_t = RecordType} <- Constraints ],
SolvedConstraints = SolvedConstraints =
[begin [begin
@ -2398,7 +2412,7 @@ destroy_and_report_unsolved_field_constraints(Env) ->
OtherCs), OtherCs),
{ContractCs, []} = {ContractCs, []} =
lists:partition(fun(#is_contract_constraint{}) -> true; (_) -> false end, OtherCs1), lists:partition(fun(#is_contract_constraint{}) -> true; (_) -> false end, OtherCs1),
Unknown = solve_known_record_types(Env, FieldCs), Unknown = solve_known_record_types(Env, FieldCs, []),
if Unknown == [] -> ok; if Unknown == [] -> ok;
true -> true ->
case solve_unknown_record_types(Env, Unknown) of case solve_unknown_record_types(Env, Unknown) of

View File

@ -168,6 +168,7 @@ compilable_contracts() ->
"maps", "maps",
"oracles", "oracles",
"remote_call", "remote_call",
"remote_call_ambiguous_record",
"simple", "simple",
"simple_storage", "simple_storage",
"spend_test", "spend_test",

View File

@ -0,0 +1,11 @@
contract interface Coin =
entrypoint mint : () => int
contract interface OtherCoin =
entrypoint mint : () => int
main contract Main =
function mkCoin() : Coin = ct_11111111111111111111111111111115rHyByZ
entrypoint foo() : int =
let r = mkCoin()
r.mint()