Skip to content

Commit 4c62653

Browse files
committed
[Tolk] Auto-infer never for always-throwing functions
Previously, `never` could be specified, but was not auto-inferred. (because it's done the same way in TypeScript) Now, it's auto-inferred, which is more expected in our case.
1 parent 82ae5d9 commit 4c62653

File tree

12 files changed

+39
-8
lines changed

12 files changed

+39
-8
lines changed

tolk-tester/tests/inference-tests.tolk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ fun alwaysThrowsNotAnnotated2() { alwaysThrows(); }
111111
fun test9() {
112112
__expect_type(alwaysThrows(), "never");
113113
__expect_type(alwaysThrows, "() -> never");
114-
__expect_type(alwaysThrowsNotAnnotated(), "void");
115-
__expect_type(alwaysThrowsNotAnnotated2(), "void");
114+
__expect_type(alwaysThrowsNotAnnotated(), "never");
115+
__expect_type(alwaysThrowsNotAnnotated2(), "never");
116116
}
117117

118118

tolk-tester/tests/invalid-typing/err-6427.tolk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fun cantReturnVoidAndNonVoid(a: int | slice | builder) {
2+
throw 123;
23
match (a) {
34
int => { return; }
45
slice => {}

tolk-tester/tests/never-type-tests.tolk

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
fun takeInt(a: int) {}
22

3+
fun alwaysThrows() {
4+
throw 123;
5+
}
6+
7+
fun alwaysThrowsButReturns() {
8+
throw 123;
9+
return 123;
10+
}
11+
312
@method_id(101)
413
fun test1(x: int?) {
514
if (x == null && x != null) {
@@ -21,6 +30,8 @@ fun test1(x: int?) {
2130

2231
fun main() {
2332
__expect_type(test1, "(int?) -> int");
33+
__expect_type(alwaysThrows(), "never");
34+
__expect_type(alwaysThrowsButReturns(), "int");
2435
}
2536

2637
/**

tolk-tester/tests/try-catch-tests.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ fun alwaysThrowX(x: int): never {
175175
}
176176

177177
@noinline
178-
fun anotherNever(throw123: bool): never {
178+
fun anotherNever(throw123: bool) { // auto-infer `never`
179179
if (throw123) { alwaysThrow123(); }
180180
alwaysThrowX(456);
181181
}

tolk-tester/tests/var-apply-tests.tolk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ fun testVarApplyInTernary() {
101101
return t;
102102
}
103103

104-
fun always_throw2(x: int) {
104+
fun always_throw2(x: int): void {
105105
throw 239 + x
106106
}
107107

tolk/analyzer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace tolk {
2424
// for instance, variables after their call aren't considered used
2525
// its main purpose is `throw` statement, it's a call to a built-in `__throw` function
2626
static bool does_function_always_throw(FunctionPtr fun_ref) {
27-
return fun_ref->declared_return_type == TypeDataNever::create();
27+
return fun_ref->inferred_return_type == TypeDataNever::create();
2828
}
2929

3030
/*

tolk/ast-replacer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ class ASTReplacerInFunctionBody : public ASTReplacer {
210210
};
211211

212212

213+
const std::vector<FunctionPtr>& get_all_builtin_functions();
213214
const std::vector<FunctionPtr>& get_all_not_builtin_functions();
214215
const std::vector<GlobalConstPtr>& get_all_declared_constants();
215216
const std::vector<StructPtr>& get_all_declared_structs();

tolk/ast-visitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class ASTVisitorFunctionBody : public ASTVisitor {
211211
};
212212

213213

214+
const std::vector<FunctionPtr>& get_all_builtin_functions();
214215
const std::vector<FunctionPtr>& get_all_not_builtin_functions();
215216
const std::vector<GlobalVarPtr>& get_all_declared_global_vars();
216217
const std::vector<GlobalConstPtr>& get_all_declared_constants();

tolk/builtins.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ static std::vector<LocalVarData> define_builtin_parameters(const std::vector<Typ
4343
static void define_builtin_func(const std::string& name, const std::vector<TypePtr>& params_types, TypePtr return_type, const GenericsDeclaration* genericTs, const std::function<FunctionBodyBuiltinAsmOp::CompileToAsmOpImpl>& func, int flags) {
4444
auto* f_sym = new FunctionData(name, {}, "", nullptr, return_type, define_builtin_parameters(params_types, flags), flags, FunctionInlineMode::notCalculated, genericTs, nullptr, new FunctionBodyBuiltinAsmOp(func), nullptr);
4545
G.symtable.add_function(f_sym);
46+
G.all_builtins.push_back(f_sym);
4647
}
4748

4849
static void define_builtin_func(const std::string& name, const std::vector<TypePtr>& params_types, TypePtr return_type, const GenericsDeclaration* genericTs, const std::function<FunctionBodyBuiltinGenerateOps::GenerateOpsImpl>& func, int flags) {
4950
auto* f_sym = new FunctionData(name, {}, "", nullptr, return_type, define_builtin_parameters(params_types, flags), flags, FunctionInlineMode::notCalculated, genericTs, nullptr, new FunctionBodyBuiltinGenerateOps(func), nullptr);
5051
G.symtable.add_function(f_sym);
52+
G.all_builtins.push_back(f_sym);
5153
}
5254

5355
static void define_builtin_method(const std::string& name, TypePtr receiver_type, const std::vector<TypePtr>& params_types, TypePtr return_type, const GenericsDeclaration* genericTs, const std::function<FunctionBodyBuiltinAsmOp::CompileToAsmOpImpl>& func, int flags,
@@ -57,13 +59,15 @@ static void define_builtin_method(const std::string& name, TypePtr receiver_type
5759
f_sym->arg_order = arg_order;
5860
f_sym->ret_order = ret_order;
5961
G.symtable.add_function(f_sym);
62+
G.all_builtins.push_back(f_sym);
6063
G.all_methods.push_back(f_sym);
6164
}
6265

6366
void define_builtin_method(const std::string& name, TypePtr receiver_type, const std::vector<TypePtr>& params_types, TypePtr return_type, const GenericsDeclaration* genericTs, const std::function<FunctionBodyBuiltinGenerateOps::GenerateOpsImpl>& func, int flags) {
6467
std::string method_name = name.substr(name.find('.') + 1);
6568
auto* f_sym = new FunctionData(name, {}, std::move(method_name), receiver_type, return_type, define_builtin_parameters(params_types, flags), flags, FunctionInlineMode::notCalculated, genericTs, nullptr, new FunctionBodyBuiltinGenerateOps(func), nullptr);
6669
G.symtable.add_function(f_sym);
70+
G.all_builtins.push_back(f_sym);
6771
G.all_methods.push_back(f_sym);
6872
}
6973

@@ -1500,7 +1504,7 @@ void define_builtins() {
15001504
define_builtin_func("__throw", ParamsInt1, Never, nullptr,
15011505
compile_throw,
15021506
0);
1503-
define_builtin_func("__throw_arg", {typeT, Int}, Never, declGenericT,
1507+
define_builtin_func("__throw_arg", {TypeDataUnknown::create(), Int}, Never, nullptr,
15041508
compile_throw_arg,
15051509
0);
15061510
define_builtin_func("__throw_if_unless", ParamsInt3, Unit, nullptr,

tolk/compiler-state.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ void CompilerSettings::parse_experimental_options_cmd_arg(const std::string& cmd
6666
}
6767
}
6868

69+
const std::vector<FunctionPtr>& get_all_builtin_functions() {
70+
return G.all_builtins;
71+
}
72+
6973
const std::vector<FunctionPtr>& get_all_not_builtin_functions() {
7074
return G.all_functions;
7175
}

0 commit comments

Comments
 (0)