mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 09:31:05 +01:00
Generic classes (#1124)
* start of generic classes * fix regressions * class functions in interfaces * access to class function on interface from class parameter * more stuff working for generic classes * fixing bugs * update TypeEqual for generic classes * fixing bugs and finding new ones * disable unqualified access to members from other members for now * minor edits * bug fixes * introduce compile_time_value to use in type checker instead of constant_value * cleanup * put a CHECK back in * failure test cases for the new FATAL_COMPILATION_ERROR * change a runtime FATAL into a FATAL_COMPILATION_ERROR * Update executable_semantics/ast/declaration.h Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/action_stack.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/interpreter.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/interpreter.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/resolve_names.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * responses to reviews * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * rename compile_time_value to symbolic_identity * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * more edits from review * Apply suggestions from code review Co-authored-by: Geoff Romer <gromer@google.com> * review responses * Update executable_semantics/interpreter/interpreter.cpp Co-authored-by: Geoff Romer <gromer@google.com> * const impl_scope for TypeCheckChoiceDeclaration * add some const Co-authored-by: Jon Meow <jperkins@google.com> Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
committed by
GitHub
co-authored by
Jon Meow
Geoff Romer
parent
37a0e35b31
commit
210856dd57
@@ -0,0 +1,41 @@
|
||||
// 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: %{executable_semantics} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{executable_semantics} --trace %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{executable_semantics} %s
|
||||
// CHECK: result: 0
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
interface Number {
|
||||
fn Zero() -> Self;
|
||||
fn Add[me: Self](other: Self) -> Self;
|
||||
}
|
||||
|
||||
class Point(T:! Number) {
|
||||
fn Origin() -> Point(T) {
|
||||
return {.x = T.Zero(), .y = T.Zero()};
|
||||
}
|
||||
fn SumXY(p: Point(T)) -> T {
|
||||
return p.x.Add(p.y);
|
||||
}
|
||||
fn SumFn() -> (__Fn(Point(T)) -> T) {
|
||||
return Point(T).SumXY;
|
||||
}
|
||||
var x: T;
|
||||
var y: T;
|
||||
}
|
||||
|
||||
external impl i32 as Number {
|
||||
fn Zero() -> i32 { return 0; }
|
||||
fn Add[me: i32](other: i32) -> i32 { return me + other; }
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = Point(i32).Origin();
|
||||
return p.SumFn()(p);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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/generic_class/fail_argument_deduction.carbon:26: type error in argument deduction
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
class Point(T:! Type) {
|
||||
var x: T;
|
||||
var y: T;
|
||||
}
|
||||
|
||||
fn FirstOfTwoPoints[T:! Type](a: Point(T), b: Point(T)) -> Point(T) {
|
||||
return a;
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = {.x = 0, .y = 1};
|
||||
var q: Point(Bool) = {.x = true, .y = false};
|
||||
return FirstOfTwoPoints(p, q).x;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// 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/generic_class/fail_bad_parameter_type.carbon:16: unexpected type of deduced parameter i32
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
class Point(T:! i32) {
|
||||
|
||||
fn Origin(zero: T) -> Point(T) {
|
||||
return {.x = zero, .y = zero};
|
||||
}
|
||||
|
||||
fn GetX[me: Point(T)]() -> T {
|
||||
return me.x;
|
||||
}
|
||||
|
||||
var x: T;
|
||||
var y: T;
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = Point(i32).Origin(0);
|
||||
return p.GetX();
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// 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/generic_class/fail_field_access_on_generic.carbon:15: field access, unexpected T:! Type of non-interface type Type in a.x
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
fn BadFieldAccess[T:! Type](a: T) -> T {
|
||||
return a.x;
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
return BadFieldAccess(0);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// 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/generic_class/fail_generic_in_pattern.carbon:17: Generic binding may not occur in pattern with expected type: T:! i32
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
fn Main() -> i32 {
|
||||
var t: auto = 5;
|
||||
match (t) {
|
||||
case T:! i32 =>
|
||||
return 0;
|
||||
default =>
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+25
@@ -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/generic_class/fail_instantiate_non_generic.carbon:23: attempt to instantiate a non-generic class: Point(i32)
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
class Point {
|
||||
fn Origin() -> Point {
|
||||
return {.x = 0, .y = 0};
|
||||
}
|
||||
var x: i32;
|
||||
var y: i32;
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = Point.Origin();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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/generic_class/fail_point_equal.carbon:21: type error in name binding: 'class Point(T = i32)' is not implicitly convertible to 'class Point(T = Bool)'
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
class Point(T:! Type) {
|
||||
var x: T;
|
||||
var y: T;
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = {.x = 0, .y = 0};
|
||||
var q: Point(Bool) = p;
|
||||
return 0;
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// 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: %{executable_semantics} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{executable_semantics} --trace %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{executable_semantics} %s
|
||||
// CHECK: result: 0
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
interface Number {
|
||||
fn Zero() -> Self;
|
||||
fn Add[me: Self](other: Self) -> Self;
|
||||
}
|
||||
|
||||
class Point(T:! Number) {
|
||||
fn Origin() -> Point(T) {
|
||||
return {.x = T.Zero(), .y = T.Zero()};
|
||||
}
|
||||
var x: T;
|
||||
var y: T;
|
||||
}
|
||||
|
||||
external impl i32 as Number {
|
||||
fn Zero() -> i32 { return 0; }
|
||||
fn Add[me: i32](other: i32) -> i32 { return me + other; }
|
||||
}
|
||||
|
||||
fn SumXY[U:! Number](p: Point(U)) -> U {
|
||||
return p.Origin().x.Add(p.y);
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = {.x = 0, .y = 0};
|
||||
return SumXY(p);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// 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: %{executable_semantics} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{executable_semantics} --trace %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{executable_semantics} %s
|
||||
// CHECK: result: 0
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
interface Number {
|
||||
fn Zero() -> Self;
|
||||
fn Add[me: Self](other: Self) -> Self;
|
||||
}
|
||||
|
||||
class Point(T:! Number) {
|
||||
var x: T;
|
||||
var y: T;
|
||||
}
|
||||
|
||||
fn Origin[U :! Number](other: U) -> Point(U) {
|
||||
return {.x = U.Zero(), .y = U.Zero()};
|
||||
}
|
||||
|
||||
fn Clone[U :! Number](other: Point(U)) -> Point(U) {
|
||||
return {.x = other.x, .y = other.y};
|
||||
}
|
||||
|
||||
fn SumXY[U :! Number](other: Point(U)) -> U {
|
||||
return other.x.Add(other.y);
|
||||
}
|
||||
|
||||
external impl i32 as Number {
|
||||
fn Zero() -> i32 { return 0; }
|
||||
fn Add[me: i32](other: i32) -> i32 { return me + other; }
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = Origin(0);
|
||||
return SumXY(Clone(p));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// 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: %{executable_semantics} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{executable_semantics} --trace %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{executable_semantics} %s
|
||||
// CHECK: result: 0
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
class Point(T:! Type) {
|
||||
|
||||
fn Origin(zero: T) -> Point(T) {
|
||||
return {.x = zero, .y = zero};
|
||||
}
|
||||
|
||||
fn GetX[me: Point(T)]() -> T {
|
||||
return me.x;
|
||||
}
|
||||
|
||||
var x: T;
|
||||
var y: T;
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = Point(i32).Origin(0);
|
||||
return p.GetX();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// 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: %{executable_semantics} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{executable_semantics} --trace %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{executable_semantics} %s
|
||||
// CHECK: result: 0
|
||||
|
||||
package ExecutableSemanticsTest api;
|
||||
|
||||
interface Number {
|
||||
fn Zero() -> Self;
|
||||
fn Add[me: Self](other: Self) -> Self;
|
||||
}
|
||||
|
||||
class Point(T:! Number) {
|
||||
fn Origin() -> Point(T) {
|
||||
return {.x = T.Zero(), .y = T.Zero()};
|
||||
}
|
||||
fn Clone[me: Point(T)]() -> Point(T) {
|
||||
return {.x = me.x, .y = me.y};
|
||||
}
|
||||
fn SumXY[me: Point(T)]() -> T {
|
||||
return me.x.Add(me.y);
|
||||
}
|
||||
var x: T;
|
||||
var y: T;
|
||||
}
|
||||
|
||||
external impl i32 as Number {
|
||||
fn Zero() -> i32 { return 0; }
|
||||
fn Add[me: i32](other: i32) -> i32 { return me + other; }
|
||||
}
|
||||
|
||||
fn Main() -> i32 {
|
||||
var p: Point(i32) = Point(i32).Origin();
|
||||
return p.Clone().SumXY();
|
||||
}
|
||||
Reference in New Issue
Block a user