Implement auto return types, removing => returns (#850)

This implements #826, I think covering everything important there.

Regarding ReturnTypeContext, I broke that out because it started feeling like a significant number of args to be passing around, and I think this makes the association inside type checking clearer.

Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
Jon Meow
2021-09-27 11:17:24 -07:00
committed by GitHub
co-authored by Geoff Romer
parent 04ab30f231
commit 5aa958345b
11 changed files with 164 additions and 46 deletions
@@ -11,7 +11,7 @@
package ExecutableSemanticsTest api;
fn add(x: i32, y: i32) => x + y;
fn add(x: i32, y: i32) -> auto { return x + y; }
fn main() -> i32 {
return add(1, 2) - 3;
@@ -0,0 +1,25 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// RUN: not executable_semantics %s 2>&1 | \
// RUN: FileCheck --match-full-lines --allow-unused-prefixes=false %s
// RUN: not executable_semantics --trace %s 2>&1 | \
// RUN: FileCheck --match-full-lines --allow-unused-prefixes %s
// AUTOUPDATE: executable_semantics %s
// CHECK: COMPILATION ERROR: {{.*}}/executable_semantics/testdata/function/auto_return/fail_direct_recurse.carbon:18: could not find `Recurse`
package ExecutableSemanticsTest api;
// This is required to fail even though the Recurse() call's return value isn't
// used.
fn Recurse(x: i32, do_recurse: Bool) -> auto {
if (do_recurse) {
Recurse(x, false);
}
return x;
}
fn main() -> i32 {
return Recurse(1, true) - 3;
}
@@ -0,0 +1,26 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// RUN: not executable_semantics %s 2>&1 | \
// RUN: FileCheck --match-full-lines --allow-unused-prefixes=false %s
// RUN: not executable_semantics --trace %s 2>&1 | \
// RUN: FileCheck --match-full-lines --allow-unused-prefixes %s
// AUTOUPDATE: executable_semantics %s
// CHECK: COMPILATION ERROR: {{.*}}/executable_semantics/testdata/function/auto_return/fail_multiple_returns.carbon:18: Only one return is allowed in a function with an `auto` return type.
package ExecutableSemanticsTest api;
fn Add(x: i32, y: i32) -> auto {
if (x == 0) {
return x;
} else if (y == 0) {
return y;
} else {
return x + y;
}
}
fn main() -> i32 {
return Add(1, 2) - 3;
}
@@ -0,0 +1,19 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// RUN: not executable_semantics %s 2>&1 | \
// RUN: FileCheck --match-full-lines --allow-unused-prefixes=false %s
// RUN: not executable_semantics --trace %s 2>&1 | \
// RUN: FileCheck --match-full-lines --allow-unused-prefixes %s
// AUTOUPDATE: executable_semantics %s
// CHECK: COMPILATION ERROR: {{.*}}/executable_semantics/testdata/function/auto_return/fail_no_return.carbon:15: control-flow reaches end of function that provides a `->` return type without reaching a return statement
package ExecutableSemanticsTest api;
fn NoReturn() -> auto {
}
fn main() {
NoReturn();
}
@@ -0,0 +1,21 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// RUN: not executable_semantics %s 2>&1 | \
// RUN: FileCheck --match-full-lines --allow-unused-prefixes=false %s
// RUN: not executable_semantics --trace %s 2>&1 | \
// RUN: FileCheck --match-full-lines --allow-unused-prefixes %s
// AUTOUPDATE: executable_semantics %s
// CHECK: COMPILATION ERROR: {{.*}}/executable_semantics/testdata/function/auto_return/fail_separate_decl.carbon:15: syntax error, unexpected SEMICOLON, expecting LEFT_CURLY_BRACE
package ExecutableSemanticsTest api;
// This declaration is not allowed.
fn Add(x: i32, y: i32) -> auto;
fn Add(x: i32, y: i32) -> auto { return x + y; }
fn main() -> i32 {
return Add(1, 2) - 3;
}
@@ -11,7 +11,7 @@
package ExecutableSemanticsTest api;
fn Id(t: Type) => t;
fn Id(t: Type) -> auto { return t; }
// Test non-trivial type expression in parameter type.
@@ -11,7 +11,7 @@
package ExecutableSemanticsTest api;
fn Id(t: Type) => t;
fn Id(t: Type) -> auto { return t; }
// Test non-trivial type expression in return type.
@@ -11,7 +11,7 @@
package ExecutableSemanticsTest api;
fn Id(t: Type) => t;
fn Id(t: Type) -> auto { return t; }
// Test non-trivial type expression in variable declaration statement.