diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 11d970e..b34d005 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -2322,7 +2322,8 @@ solve_field_constraints(Env, Constraints) -> -spec solve_ambiguous_field_constraints(env(), [field_constraint()]) -> ok. 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; length(Unknown) < length(Constraints) -> %% progress! Keep trying. @@ -2347,10 +2348,23 @@ solve_unknown_record_types(Env, Unknown) -> false -> Solutions end. --spec solve_known_record_types(env(), [field_constraint()]) -> [field_constraint()]. -solve_known_record_types(Env, Constraints) -> +%% Since named argument constraints solving happens after field +%% 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 = - [ 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 ], SolvedConstraints = [begin @@ -2398,7 +2412,7 @@ destroy_and_report_unsolved_field_constraints(Env) -> OtherCs), {ContractCs, []} = 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; true -> case solve_unknown_record_types(Env, Unknown) of diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index 26a0c74..e5e646f 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -168,6 +168,7 @@ compilable_contracts() -> "maps", "oracles", "remote_call", + "remote_call_ambiguous_record", "simple", "simple_storage", "spend_test", diff --git a/test/contracts/remote_call_ambiguous_record.aes b/test/contracts/remote_call_ambiguous_record.aes new file mode 100644 index 0000000..915045f --- /dev/null +++ b/test/contracts/remote_call_ambiguous_record.aes @@ -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()