mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 17:00:25 +01:00
Replace impl fn with override fn (#6008)
This proposal renames the syntax used to mark an overriding definition of a virtual method from `impl fn` to `override fn` to avoid ambiguity: besides indicating an overriding virtual function, it can be parsed as an "impl" declaration when the construct following "impl" begins with a lambda introduced by "fn". Closes #5711 --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
973d721916
commit
f4bd6e42f9
+17
-16
@@ -1237,21 +1237,20 @@ There are three virtual modifier keywords:
|
||||
virtual" but is called
|
||||
["pure virtual" in C++](https://en.wikipedia.org/wiki/Virtual_function#Abstract_classes_and_pure_virtual_functions).
|
||||
Only abstract classes may have unimplemented abstract methods.
|
||||
- `impl` - This marks a method that overrides a method marked `virtual` or
|
||||
- `override` - This marks a method that overrides a method marked `virtual` or
|
||||
`abstract` in the base class with an implementation specific to -- and
|
||||
defined within -- this class. The method is still virtual and may be
|
||||
overridden again in subsequent derived classes if this is a base class. See
|
||||
[method overriding in Wikipedia](https://en.wikipedia.org/wiki/Method_overriding).
|
||||
Requiring a keyword when overriding allows the compiler to diagnose when the
|
||||
derived class accidentally uses the wrong signature or spelling and so
|
||||
doesn't match the base class. We intentionally use the same keyword here as
|
||||
for implementing interfaces, to emphasize that they are similar operations.
|
||||
doesn't match the base class.
|
||||
|
||||
| Keyword on<br />method in `C` | Allowed in<br />`abstract class C` | Allowed in<br />`base class C` | Allowed in<br />final `class C` | in `B` where<br />`C` extends `B` | in `D` where<br />`D` extends `C` |
|
||||
| ----------------------------- | ---------------------------------- | ------------------------------ | ------------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| `virtual` | ✅ | ✅ | ❌ | _not present_ | `abstract`<br />`impl`<br />_not mentioned_ |
|
||||
| `abstract` | ✅ | ❌ | ❌ | _not present_<br />`virtual`<br />`abstract`<br />`impl` | `abstract`<br />`impl`<br />_may not be<br />mentioned if<br />`D` is not final_ |
|
||||
| `impl` | ✅ | ✅ | ✅ | `virtual`<br />`abstract`<br />`impl` | `abstract`<br />`impl` |
|
||||
| Keyword on<br />method in `C` | Allowed in<br />`abstract class C` | Allowed in<br />`base class C` | Allowed in<br />final `class C` | in `B` where<br />`C` extends `B` | in `D` where<br />`D` extends `C` |
|
||||
| ----------------------------- | ---------------------------------- | ------------------------------ | ------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
|
||||
| `virtual` | ✅ | ✅ | ❌ | _not present_ | `abstract`<br />`override`<br />_not mentioned_ |
|
||||
| `abstract` | ✅ | ❌ | ❌ | _not present_<br />`virtual`<br />`abstract`<br />`override` | `abstract`<br />`override`<br />_may not be<br />mentioned if<br />`D` is not final_ |
|
||||
| `override` | ✅ | ✅ | ✅ | `virtual`<br />`abstract`<br />`override` | `abstract`<br />`override` |
|
||||
|
||||
Since validating a method with a virtual modifier keyword involves looking for
|
||||
methods with the same name in the base class, virtual methods must be declared
|
||||
@@ -1315,15 +1314,15 @@ base class B1 {
|
||||
class D1 {
|
||||
extend base: B1;
|
||||
// ❌ Illegal:
|
||||
// impl fn F[self: Self](x: Self) -> Self;
|
||||
// override fn F[self: Self](x: Self) -> Self;
|
||||
// since that would mean the same thing as:
|
||||
// impl fn F[self: Self](x: D1) -> D1;
|
||||
// override fn F[self: Self](x: D1) -> D1;
|
||||
// and `D1` is a different type than `B1`.
|
||||
|
||||
// ✅ Allowed: Parameter and return types
|
||||
// of `F` match declaration in `B1`.
|
||||
impl fn F[self: Self](x: B1) -> B1;
|
||||
// Or: impl fn F[self: D1](x: B1) -> B1;
|
||||
override fn F[self: Self](x: B1) -> B1;
|
||||
// Or: override fn F[self: D1](x: B1) -> B1;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1341,9 +1340,9 @@ base class B2 {
|
||||
class D2 {
|
||||
extend base: B2;
|
||||
// ✅ Allowed
|
||||
impl fn Clone[self: Self]() -> Self*;
|
||||
override fn Clone[self: Self]() -> Self*;
|
||||
// Means the same thing as:
|
||||
// impl fn Clone[self: D2]() -> D2*;
|
||||
// override fn Clone[self: D2]() -> D2*;
|
||||
// which is allowed since `D2*` is a
|
||||
// subtype of `B2*`.
|
||||
}
|
||||
@@ -1615,7 +1614,7 @@ of its base classes unless it has a
|
||||
[virtual destructor](https://en.wikipedia.org/wiki/Virtual_function#Virtual_destructors).
|
||||
An abstract or base class' destructor may be declared virtual using the
|
||||
`virtual` introducer, in which case any derived class destructor declaration
|
||||
must be `impl`:
|
||||
must be `override`:
|
||||
|
||||
```carbon
|
||||
base class MyBaseClass {
|
||||
@@ -1624,7 +1623,7 @@ base class MyBaseClass {
|
||||
|
||||
class MyDerivedClass {
|
||||
extend base: MyBaseClass;
|
||||
impl fn destroy[addr self: Self*]() { ... }
|
||||
override fn destroy[addr self: Self*]() { ... }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -2298,6 +2297,8 @@ the type of `U.x`."
|
||||
- [Destructor syntax options](/proposals/p5017.md#destructor-syntax-options)
|
||||
- [Destructor name options](/proposals/p5017.md#destructor-name-options)
|
||||
|
||||
- [#6008: Replace `impl fn` with `override fn`](https://github.com/carbon-language/carbon-lang/pull/6008)
|
||||
|
||||
## References
|
||||
|
||||
- [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# Replace `impl fn` with `override fn`
|
||||
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
|
||||
[Pull request](https://github.com/carbon-language/carbon-lang/pull/6008)
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Abstract](#abstract)
|
||||
- [Problem](#problem)
|
||||
- [Background](#background)
|
||||
- [Proposal](#proposal)
|
||||
- [Rationale](#rationale)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Abstract
|
||||
|
||||
This proposal renames the syntax used to mark an overriding definition of a
|
||||
virtual method from `impl fn` to `override fn` to avoid ambiguity.
|
||||
|
||||
## Problem
|
||||
|
||||
The phrase `impl fn` was introduced to mark overriding virtual functions,
|
||||
however, it is now ambiguous: besides indicating an overriding virtual function,
|
||||
it can be parsed as an "impl" declaration when the construct following "impl"
|
||||
begins with a lambda introduced by "fn".
|
||||
|
||||
## Background
|
||||
|
||||
The original syntax was adopted in
|
||||
[proposal #777](https://github.com/carbon-language/carbon-lang/pull/777) to
|
||||
emphasize that implementing interfaces and overriding virtual functions are
|
||||
similar operations.
|
||||
|
||||
## Proposal
|
||||
|
||||
This proposal is to replace the `impl fn` syntax with `override fn` for method
|
||||
overriding in class inheritance.
|
||||
|
||||
Note that `impl` is still a modifier keyword for library and package
|
||||
declarations (`impl library ...` and `impl package ...` respectively). The
|
||||
former is unambiguous and the latter is easy to disambiguate, so no change is
|
||||
needed for these two cases.
|
||||
|
||||
## Rationale
|
||||
|
||||
This proposal is focused on the
|
||||
[That code is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write)
|
||||
Carbon goal. Changing the keyword from `impl` to `override` makes the intent
|
||||
clearer, resolves syntax ambiguity, and adheres to existing C++ conventions.
|
||||
@@ -199,7 +199,7 @@ static auto BuildVtable(Context& context, Parse::ClassDefinitionId node_id,
|
||||
.GetAs<SemIR::FunctionDecl>(override_fn_decl_id)
|
||||
.function_id);
|
||||
return override_fn.virtual_modifier ==
|
||||
SemIR::FunctionFields::VirtualModifier::Impl &&
|
||||
SemIR::FunctionFields::VirtualModifier::Override &&
|
||||
override_fn.name_id == fn.name_id;
|
||||
});
|
||||
if (i != vtable_contents.end()) {
|
||||
@@ -237,13 +237,15 @@ static auto BuildVtable(Context& context, Parse::ClassDefinitionId node_id,
|
||||
for (auto inst_id : vtable_contents) {
|
||||
auto fn_decl = context.insts().GetAs<SemIR::FunctionDecl>(inst_id);
|
||||
auto& fn = context.functions().Get(fn_decl.function_id);
|
||||
if (fn.virtual_modifier != SemIR::FunctionFields::VirtualModifier::Impl) {
|
||||
if (fn.virtual_modifier !=
|
||||
SemIR::FunctionFields::VirtualModifier::Override) {
|
||||
fn.virtual_index = vtable.size();
|
||||
vtable.push_back(build_specific_function(inst_id));
|
||||
} else if (!implemented_impls.Lookup(fn_decl.function_id)) {
|
||||
CARBON_DIAGNOSTIC(ImplWithoutVirtualInBase, Error,
|
||||
"impl without compatible virtual in base class");
|
||||
context.emitter().Emit(SemIR::LocId(inst_id), ImplWithoutVirtualInBase);
|
||||
CARBON_DIAGNOSTIC(OverrideWithoutVirtualInBase, Error,
|
||||
"override without compatible virtual in base class");
|
||||
context.emitter().Emit(SemIR::LocId(inst_id),
|
||||
OverrideWithoutVirtualInBase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,8 @@ static auto GetVirtualModifier(const KeywordModifierSet& modifier_set)
|
||||
SemIR::Function::VirtualModifier::Virtual)
|
||||
.Case(KeywordModifierSet::Abstract,
|
||||
SemIR::Function::VirtualModifier::Abstract)
|
||||
.Case(KeywordModifierSet::Impl, SemIR::Function::VirtualModifier::Impl)
|
||||
.Case(KeywordModifierSet::Override,
|
||||
SemIR::Function::VirtualModifier::Override)
|
||||
.Default(SemIR::Function::VirtualModifier::None);
|
||||
}
|
||||
|
||||
@@ -342,10 +343,11 @@ static auto RequestVtableIfVirtual(
|
||||
}
|
||||
|
||||
auto& class_info = context.classes().Get(class_decl->class_id);
|
||||
if (virtual_modifier == SemIR::Function::VirtualModifier::Impl &&
|
||||
if (virtual_modifier == SemIR::Function::VirtualModifier::Override &&
|
||||
!class_info.base_id.has_value()) {
|
||||
CARBON_DIAGNOSTIC(ImplWithoutBase, Error, "impl without base class");
|
||||
context.emitter().Emit(node_id, ImplWithoutBase);
|
||||
CARBON_DIAGNOSTIC(OverrideWithoutBase, Error,
|
||||
"override without base class");
|
||||
context.emitter().Emit(node_id, OverrideWithoutBase);
|
||||
virtual_modifier = SemIR::Function::VirtualModifier::None;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ enum class ModifierOrder : int8_t { Access, Extern, Extend, Decl, Last = Decl };
|
||||
X(Export) \
|
||||
X(Final) \
|
||||
X(Impl) \
|
||||
X(Override) \
|
||||
X(Returned) \
|
||||
X(Virtual)
|
||||
|
||||
@@ -113,11 +114,11 @@ CARBON_KEYWORD_MODIFIER_SET(CARBON_KEYWORD_MODIFIER_SET_WITH_TYPE)
|
||||
|
||||
constexpr KeywordModifierSet KeywordModifierSet::Access(Private | Protected);
|
||||
constexpr KeywordModifierSet KeywordModifierSet::Class(Abstract | Base);
|
||||
constexpr KeywordModifierSet KeywordModifierSet::Method(Abstract | Impl |
|
||||
constexpr KeywordModifierSet KeywordModifierSet::Method(Abstract | Override |
|
||||
Virtual);
|
||||
constexpr KeywordModifierSet KeywordModifierSet::ImplDecl(Extend | Final);
|
||||
constexpr KeywordModifierSet KeywordModifierSet::Interface(Default | Final);
|
||||
constexpr KeywordModifierSet KeywordModifierSet::Decl(Class | Method |
|
||||
constexpr KeywordModifierSet KeywordModifierSet::Decl(Class | Method | Impl |
|
||||
Interface | Export |
|
||||
Returned);
|
||||
|
||||
|
||||
+109
-109
@@ -34,7 +34,7 @@ import Modifiers;
|
||||
|
||||
class Derived {
|
||||
extend base: Modifiers.Base;
|
||||
impl fn H[self: Self]();
|
||||
override fn H[self: Self]();
|
||||
}
|
||||
|
||||
fn Use() {
|
||||
@@ -72,7 +72,7 @@ abstract class A1 {
|
||||
|
||||
abstract class A2 {
|
||||
extend base: A1;
|
||||
impl fn F[self: Self]();
|
||||
override fn F[self: Self]();
|
||||
}
|
||||
|
||||
// --- impl_base.carbon
|
||||
@@ -85,12 +85,12 @@ base class B1 {
|
||||
|
||||
base class B2 {
|
||||
extend base: B1;
|
||||
impl fn F[self: Self]();
|
||||
override fn F[self: Self]();
|
||||
}
|
||||
|
||||
class C {
|
||||
extend base: B2;
|
||||
impl fn F[self: Self]();
|
||||
override fn F[self: Self]();
|
||||
}
|
||||
|
||||
fn Use() {
|
||||
@@ -104,11 +104,11 @@ fn Use() {
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
class C {
|
||||
// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:3: error: impl without base class [ImplWithoutBase]
|
||||
// CHECK:STDERR: impl fn F[self: Self]();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_modifiers.carbon:[[@LINE+4]]:3: error: override without base class [OverrideWithoutBase]
|
||||
// CHECK:STDERR: override fn F[self: Self]();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn F[self: Self]();
|
||||
override fn F[self: Self]();
|
||||
}
|
||||
|
||||
// --- init_members.carbon
|
||||
@@ -139,11 +139,11 @@ base class Base {
|
||||
|
||||
class Derived {
|
||||
extend base: Base;
|
||||
// CHECK:STDERR: fail_impl_without_base_declaration.carbon:[[@LINE+4]]:3: error: impl without compatible virtual in base class [ImplWithoutVirtualInBase]
|
||||
// CHECK:STDERR: impl fn F[self: Self]();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_impl_without_base_declaration.carbon:[[@LINE+4]]:3: error: override without compatible virtual in base class [OverrideWithoutVirtualInBase]
|
||||
// CHECK:STDERR: override fn F[self: Self]();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn F[self: Self]();
|
||||
override fn F[self: Self]();
|
||||
}
|
||||
|
||||
// --- abstract_impl.carbon
|
||||
@@ -160,7 +160,7 @@ abstract class AbstractIntermediate {
|
||||
|
||||
class Derived {
|
||||
extend base: AbstractIntermediate;
|
||||
impl fn F[self: Self]();
|
||||
override fn F[self: Self]();
|
||||
}
|
||||
|
||||
// --- virtual_impl.carbon
|
||||
@@ -177,7 +177,7 @@ base class VirtualIntermediate {
|
||||
|
||||
class Derived {
|
||||
extend base: VirtualIntermediate;
|
||||
impl fn F[self: Self]();
|
||||
override fn F[self: Self]();
|
||||
}
|
||||
|
||||
// --- fail_impl_mismatch.carbon
|
||||
@@ -191,13 +191,13 @@ base class Base {
|
||||
class Derived {
|
||||
extend base: Base;
|
||||
// CHECK:STDERR: fail_impl_mismatch.carbon:[[@LINE+7]]:3: error: redeclaration differs because of parameter count of 1 [RedeclParamCountDiffers]
|
||||
// CHECK:STDERR: impl fn F[self: Self](v: i32);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: override fn F[self: Self](v: i32);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_impl_mismatch.carbon:[[@LINE-8]]:3: note: previously declared with parameter count of 0 [RedeclParamCountPrevious]
|
||||
// CHECK:STDERR: virtual fn F[self: Self]();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn F[self: Self](v: i32);
|
||||
override fn F[self: Self](v: i32);
|
||||
}
|
||||
|
||||
// --- fail_todo_impl_conversion.carbon
|
||||
@@ -223,13 +223,13 @@ base class Base {
|
||||
class Derived {
|
||||
extend base: Base;
|
||||
// CHECK:STDERR: fail_todo_impl_conversion.carbon:[[@LINE+7]]:3: error: function redeclaration differs because return type is `T2` [FunctionRedeclReturnTypeDiffers]
|
||||
// CHECK:STDERR: impl fn F[self: Self]() -> T2;
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: override fn F[self: Self]() -> T2;
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_impl_conversion.carbon:[[@LINE-8]]:3: note: previously declared with return type `T1` [FunctionRedeclReturnTypePrevious]
|
||||
// CHECK:STDERR: virtual fn F[self: Self]() -> T1;
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn F[self: Self]() -> T2;
|
||||
override fn F[self: Self]() -> T2;
|
||||
}
|
||||
|
||||
// --- fail_generic_virtual_decl.carbon
|
||||
@@ -261,7 +261,7 @@ base class Base(T:! type) {
|
||||
|
||||
class Derived {
|
||||
extend base: Base(T1);
|
||||
impl fn F[self: Self](t: T1) { }
|
||||
override fn F[self: Self](t: T1) { }
|
||||
}
|
||||
|
||||
// --- fail_virtual_without_self.carbon
|
||||
@@ -284,10 +284,10 @@ abstract class T1 {
|
||||
class T2 {
|
||||
extend base: T1;
|
||||
// CHECK:STDERR: fail_virtual_without_self.carbon:[[@LINE+4]]:3: error: virtual class function [VirtualWithoutSelf]
|
||||
// CHECK:STDERR: impl fn F();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~
|
||||
// CHECK:STDERR: override fn F();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn F();
|
||||
override fn F();
|
||||
}
|
||||
|
||||
// --- fail_addr_self_mismatch.carbon
|
||||
@@ -300,14 +300,14 @@ base class T1 {
|
||||
|
||||
class T2 {
|
||||
extend base: T1;
|
||||
// CHECK:STDERR: fail_addr_self_mismatch.carbon:[[@LINE+7]]:14: error: redeclaration differs at implicit parameter 1 [RedeclParamDiffers]
|
||||
// CHECK:STDERR: impl fn F1[addr self: Self*]();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_addr_self_mismatch.carbon:[[@LINE+7]]:18: error: redeclaration differs at implicit parameter 1 [RedeclParamDiffers]
|
||||
// CHECK:STDERR: override fn F1[addr self: Self*]();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_addr_self_mismatch.carbon:[[@LINE-8]]:17: note: previous declaration's corresponding implicit parameter here [RedeclParamPrevious]
|
||||
// CHECK:STDERR: virtual fn F1[self: Self*]();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn F1[addr self: Self*]();
|
||||
override fn F1[addr self: Self*]();
|
||||
}
|
||||
|
||||
// --- fail_generic_virtual.carbon
|
||||
@@ -369,7 +369,7 @@ base class NonGenericBase {
|
||||
|
||||
base class GenericDerived(T:! type) {
|
||||
extend base: NonGenericBase;
|
||||
impl fn F2[self: Self]() { }
|
||||
override fn F2[self: Self]() { }
|
||||
virtual fn F3[self: Self]() { }
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ class T1;
|
||||
|
||||
base class NonGenericDerived {
|
||||
extend base: GenericBase(T1);
|
||||
impl fn F2[self: Self]() { }
|
||||
override fn F2[self: Self]() { }
|
||||
virtual fn F3[self: Self]() { }
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ base class Base(T:! type) {
|
||||
class T1;
|
||||
class D1 {
|
||||
extend base: Base(T1);
|
||||
impl fn F[self: Self](t: Base(T1)*) { }
|
||||
override fn F[self: Self](t: Base(T1)*) { }
|
||||
}
|
||||
|
||||
// --- fail_impl_generic_specifically_mismatch.carbon
|
||||
@@ -416,14 +416,14 @@ base class Base(T:! type) {
|
||||
|
||||
class D1 {
|
||||
extend base: Base(T1);
|
||||
// CHECK:STDERR: fail_impl_generic_specifically_mismatch.carbon:[[@LINE+7]]:25: error: type `<pattern for T2*>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for T1*>` [RedeclParamDiffersType]
|
||||
// CHECK:STDERR: impl fn F[self: Self](t: T2*) { }
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: fail_impl_generic_specifically_mismatch.carbon:[[@LINE+7]]:29: error: type `<pattern for T2*>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for T1*>` [RedeclParamDiffersType]
|
||||
// CHECK:STDERR: override fn F[self: Self](t: T2*) { }
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: fail_impl_generic_specifically_mismatch.carbon:[[@LINE-8]]:28: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
|
||||
// CHECK:STDERR: virtual fn F[self: Self](t: T1*) { }
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn F[self: Self](t: T2*) { }
|
||||
override fn F[self: Self](t: T2*) { }
|
||||
}
|
||||
|
||||
// --- fail_impl_generic_generic_mismatch.carbon
|
||||
@@ -435,14 +435,14 @@ abstract class Base(T:! type) {
|
||||
}
|
||||
class Derived(T:! type) {
|
||||
extend base: Base(T);
|
||||
// CHECK:STDERR: fail_impl_generic_generic_mismatch.carbon:[[@LINE+7]]:25: error: type `<pattern for T>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for T*>` [RedeclParamDiffersType]
|
||||
// CHECK:STDERR: impl fn F[self: Self](t: T) { }
|
||||
// CHECK:STDERR: ^~~~
|
||||
// CHECK:STDERR: fail_impl_generic_generic_mismatch.carbon:[[@LINE+7]]:29: error: type `<pattern for T>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for T*>` [RedeclParamDiffersType]
|
||||
// CHECK:STDERR: override fn F[self: Self](t: T) { }
|
||||
// CHECK:STDERR: ^~~~
|
||||
// CHECK:STDERR: fail_impl_generic_generic_mismatch.carbon:[[@LINE-7]]:28: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
|
||||
// CHECK:STDERR: virtual fn F[self: Self](t: T*) { }
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn F[self: Self](t: T) { }
|
||||
override fn F[self: Self](t: T) { }
|
||||
}
|
||||
|
||||
// --- impl_generic_generic.carbon
|
||||
@@ -454,7 +454,7 @@ abstract class Base(T:! type) {
|
||||
}
|
||||
class Derived(T:! type) {
|
||||
extend base: Base(T*);
|
||||
impl fn F[self: Self](t: T*) { }
|
||||
override fn F[self: Self](t: T*) { }
|
||||
}
|
||||
|
||||
// --- abstract_generic_undefined.carbon
|
||||
@@ -469,7 +469,7 @@ class T1;
|
||||
|
||||
class Derived {
|
||||
extend base: Base(T1);
|
||||
impl fn F[self: Self]() { }
|
||||
override fn F[self: Self]() { }
|
||||
}
|
||||
|
||||
// --- generic_lib.carbon
|
||||
@@ -802,7 +802,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: @Derived.%Derived.H.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @Derived.H(%self.param: %Derived);
|
||||
// CHECK:STDOUT: override fn @Derived.H(%self.param: %Derived);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -1236,7 +1236,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @A1.as.Destroy.impl.Op(%self.param: %ptr.678) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @A2.F(%self.param: %A2);
|
||||
// CHECK:STDOUT: override fn @A2.F(%self.param: %A2);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @A2.as.Destroy.impl.Op(%self.param: %ptr.590) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -1468,11 +1468,11 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @B1.as.Destroy.impl.Op(%self.param: %ptr.890) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @B2.F(%self.param: %B2);
|
||||
// CHECK:STDOUT: override fn @B2.F(%self.param: %B2);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @B2.as.Destroy.impl.Op(%self.param: %ptr.afe) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @C.F(%self.param: %C);
|
||||
// CHECK:STDOUT: override fn @C.F(%self.param: %C);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -1617,7 +1617,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: .F = %C.F.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @C.F(%self.param: %C);
|
||||
// CHECK:STDOUT: override fn @C.F(%self.param: %C);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -2013,7 +2013,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived);
|
||||
// CHECK:STDOUT: override fn @Derived.F(%self.param: %Derived);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -2218,7 +2218,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @AbstractIntermediate.as.Destroy.impl.Op(%self.param: %ptr.fd8) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived);
|
||||
// CHECK:STDOUT: override fn @Derived.F(%self.param: %Derived);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -2423,7 +2423,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @VirtualIntermediate.as.Destroy.impl.Op(%self.param: %ptr.7dc) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived);
|
||||
// CHECK:STDOUT: override fn @Derived.F(%self.param: %Derived);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -2590,7 +2590,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived, %v.param: %i32);
|
||||
// CHECK:STDOUT: override fn @Derived.F(%self.param: %Derived, %v.param: %i32);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -2882,7 +2882,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived) -> %return.param: %T2;
|
||||
// CHECK:STDOUT: override fn @Derived.F(%self.param: %Derived) -> %return.param: %T2;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -3320,7 +3320,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op";
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived, %t.param: %T1) {
|
||||
// CHECK:STDOUT: override fn @Derived.F(%self.param: %Derived, %t.param: %T1) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -3622,10 +3622,10 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: %T2.F1.decl: %T2.F1.type = fn_decl @T2.F1 [concrete = constants.%T2.F1] {
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.fb8 = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.fb8 = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %.loc17_14: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: %.loc17_18: %pattern_type.f6d = addr_pattern %self.param_patt [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: %ptr.63e = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc17_29: type = splice_block %ptr [concrete = constants.%ptr.63e] {
|
||||
// CHECK:STDOUT: %.loc17_33: type = splice_block %ptr [concrete = constants.%ptr.63e] {
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T2 [concrete = constants.%T2]
|
||||
// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.63e]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -3660,7 +3660,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @T1.as.Destroy.impl.Op(%self.param: %ptr.87b) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @T2.F1(%self.param: %ptr.63e);
|
||||
// CHECK:STDOUT: override fn @T2.F1(%self.param: %ptr.63e);
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @T2.as.Destroy.impl.Op(%self.param: %ptr.63e) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
@@ -4505,9 +4505,9 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: %self.param_patt: @GenericDerived.F2.%pattern_type (%pattern_type.061) = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: @GenericDerived.F2.%GenericDerived (%GenericDerived) = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc11_20.1: type = splice_block %Self.ref [symbolic = %GenericDerived (constants.%GenericDerived)] {
|
||||
// CHECK:STDOUT: %.loc11_20.2: type = specific_constant constants.%GenericDerived, @GenericDerived(constants.%T) [symbolic = %GenericDerived (constants.%GenericDerived)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc11_20.2 [symbolic = %GenericDerived (constants.%GenericDerived)]
|
||||
// CHECK:STDOUT: %.loc11_24.1: type = splice_block %Self.ref [symbolic = %GenericDerived (constants.%GenericDerived)] {
|
||||
// CHECK:STDOUT: %.loc11_24.2: type = specific_constant constants.%GenericDerived, @GenericDerived(constants.%T) [symbolic = %GenericDerived (constants.%GenericDerived)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc11_24.2 [symbolic = %GenericDerived (constants.%GenericDerived)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %self: @GenericDerived.F2.%GenericDerived (%GenericDerived) = bind_name self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
@@ -4566,7 +4566,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @NonGenericBase.as.Destroy.impl.Op(%self.param: %ptr.806) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic impl fn @GenericDerived.F2(@GenericDerived.%T.loc9_27.2: type) {
|
||||
// CHECK:STDOUT: generic override fn @GenericDerived.F2(@GenericDerived.%T.loc9_27.2: type) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %GenericDerived: type = class_type @GenericDerived, @GenericDerived(%T) [symbolic = %GenericDerived (constants.%GenericDerived)]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %GenericDerived [symbolic = %pattern_type (constants.%pattern_type.061)]
|
||||
@@ -4574,7 +4574,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %GenericDerived [symbolic = %require_complete (constants.%require_complete)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn(%self.param: @GenericDerived.F2.%GenericDerived (%GenericDerived)) {
|
||||
// CHECK:STDOUT: override fn(%self.param: @GenericDerived.F2.%GenericDerived (%GenericDerived)) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -4921,7 +4921,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: fn(%self.param: @GenericBase.as.Destroy.impl.Op.%ptr (%ptr.b68)) = "no_op";
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @NonGenericDerived.F2(%self.param: %NonGenericDerived) {
|
||||
// CHECK:STDOUT: override fn @NonGenericDerived.F2(%self.param: %NonGenericDerived) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -5257,7 +5257,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op";
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @D1.F(%self.param: %D1, %t.param: %ptr.184) {
|
||||
// CHECK:STDOUT: override fn @D1.F(%self.param: %D1, %t.param: %ptr.184) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -5568,7 +5568,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op";
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @D1.F(%self.param: %D1, %t.param: %ptr.63e) {
|
||||
// CHECK:STDOUT: override fn @D1.F(%self.param: %D1, %t.param: %ptr.63e) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -5827,15 +5827,15 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: %Base.loc8_22.1: type = class_type @Base, @Base(constants.%T) [symbolic = %Base.loc8_22.2 (constants.%Base)]
|
||||
// CHECK:STDOUT: %.loc8: @Derived.%Derived.elem (%Derived.elem) = base_decl %Base.loc8_22.1, element0 [concrete]
|
||||
// CHECK:STDOUT: %Derived.F.decl: @Derived.%Derived.F.type (%Derived.F.type) = fn_decl @Derived.F [symbolic = @Derived.%Derived.F (constants.%Derived.F)] {
|
||||
// CHECK:STDOUT: %self.patt: @Derived.F.%pattern_type.loc16_13 (%pattern_type.423) = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: @Derived.F.%pattern_type.loc16_13 (%pattern_type.423) = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %t.patt: @Derived.F.%pattern_type.loc16_25 (%pattern_type.7dc) = binding_pattern t [concrete]
|
||||
// CHECK:STDOUT: %t.param_patt: @Derived.F.%pattern_type.loc16_25 (%pattern_type.7dc) = value_param_pattern %t.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: %self.patt: @Derived.F.%pattern_type.loc16_17 (%pattern_type.423) = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: @Derived.F.%pattern_type.loc16_17 (%pattern_type.423) = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %t.patt: @Derived.F.%pattern_type.loc16_29 (%pattern_type.7dc) = binding_pattern t [concrete]
|
||||
// CHECK:STDOUT: %t.param_patt: @Derived.F.%pattern_type.loc16_29 (%pattern_type.7dc) = value_param_pattern %t.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: @Derived.F.%Derived (%Derived) = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc16_19.1: type = splice_block %Self.ref [symbolic = %Derived (constants.%Derived)] {
|
||||
// CHECK:STDOUT: %.loc16_19.2: type = specific_constant constants.%Derived, @Derived(constants.%T) [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc16_19.2 [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: %.loc16_23.1: type = splice_block %Self.ref [symbolic = %Derived (constants.%Derived)] {
|
||||
// CHECK:STDOUT: %.loc16_23.2: type = specific_constant constants.%Derived, @Derived(constants.%T) [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc16_23.2 [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %self: @Derived.F.%Derived (%Derived) = bind_name self, %self.param
|
||||
// CHECK:STDOUT: %t.param: @Derived.F.%T (%T) = value_param call_param1
|
||||
@@ -5898,19 +5898,19 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op";
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic impl fn @Derived.F(@Derived.%T.loc7_15.2: type) {
|
||||
// CHECK:STDOUT: generic override fn @Derived.F(@Derived.%T.loc7_15.2: type) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %Derived: type = class_type @Derived, @Derived(%T) [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: %pattern_type.loc16_13: type = pattern_type %Derived [symbolic = %pattern_type.loc16_13 (constants.%pattern_type.423)]
|
||||
// CHECK:STDOUT: %pattern_type.loc16_17: type = pattern_type %Derived [symbolic = %pattern_type.loc16_17 (constants.%pattern_type.423)]
|
||||
// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base)]
|
||||
// CHECK:STDOUT: %require_complete.loc16_28: <witness> = require_complete_type %Base [symbolic = %require_complete.loc16_28 (constants.%require_complete.97d)]
|
||||
// CHECK:STDOUT: %pattern_type.loc16_25: type = pattern_type %T [symbolic = %pattern_type.loc16_25 (constants.%pattern_type.7dc)]
|
||||
// CHECK:STDOUT: %require_complete.loc16_32: <witness> = require_complete_type %Base [symbolic = %require_complete.loc16_32 (constants.%require_complete.97d)]
|
||||
// CHECK:STDOUT: %pattern_type.loc16_29: type = pattern_type %T [symbolic = %pattern_type.loc16_29 (constants.%pattern_type.7dc)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc16_17: <witness> = require_complete_type %Derived [symbolic = %require_complete.loc16_17 (constants.%require_complete.5f4)]
|
||||
// CHECK:STDOUT: %require_complete.loc16_26: <witness> = require_complete_type %T [symbolic = %require_complete.loc16_26 (constants.%require_complete.4ae)]
|
||||
// CHECK:STDOUT: %require_complete.loc16_21: <witness> = require_complete_type %Derived [symbolic = %require_complete.loc16_21 (constants.%require_complete.5f4)]
|
||||
// CHECK:STDOUT: %require_complete.loc16_30: <witness> = require_complete_type %T [symbolic = %require_complete.loc16_30 (constants.%require_complete.4ae)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn(%self.param: @Derived.F.%Derived (%Derived), %t.param: @Derived.F.%T (%T)) {
|
||||
// CHECK:STDOUT: override fn(%self.param: @Derived.F.%Derived (%Derived), %t.param: @Derived.F.%T (%T)) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -5979,14 +5979,14 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: specific @Derived.F(constants.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %Derived => constants.%Derived
|
||||
// CHECK:STDOUT: %pattern_type.loc16_13 => constants.%pattern_type.423
|
||||
// CHECK:STDOUT: %pattern_type.loc16_17 => constants.%pattern_type.423
|
||||
// CHECK:STDOUT: %Base => constants.%Base
|
||||
// CHECK:STDOUT: %require_complete.loc16_28 => constants.%require_complete.97d
|
||||
// CHECK:STDOUT: %pattern_type.loc16_25 => constants.%pattern_type.7dc
|
||||
// CHECK:STDOUT: %require_complete.loc16_32 => constants.%require_complete.97d
|
||||
// CHECK:STDOUT: %pattern_type.loc16_29 => constants.%pattern_type.7dc
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc16_17 => constants.%require_complete.5f4
|
||||
// CHECK:STDOUT: %require_complete.loc16_26 => constants.%require_complete.4ae
|
||||
// CHECK:STDOUT: %require_complete.loc16_21 => constants.%require_complete.5f4
|
||||
// CHECK:STDOUT: %require_complete.loc16_30 => constants.%require_complete.4ae
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Derived.as.Destroy.impl(constants.%T) {
|
||||
@@ -6210,23 +6210,23 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: %Base.loc8_23.1: type = class_type @Base, @Base(constants.%ptr.79f) [symbolic = %Base.loc8_23.2 (constants.%Base.16b)]
|
||||
// CHECK:STDOUT: %.loc8: @Derived.%Derived.elem (%Derived.elem) = base_decl %Base.loc8_23.1, element0 [concrete]
|
||||
// CHECK:STDOUT: %Derived.F.decl: @Derived.%Derived.F.type (%Derived.F.type) = fn_decl @Derived.F [symbolic = @Derived.%Derived.F (constants.%Derived.F)] {
|
||||
// CHECK:STDOUT: %self.patt: @Derived.F.%pattern_type.loc9_13 (%pattern_type.423) = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: @Derived.F.%pattern_type.loc9_13 (%pattern_type.423) = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %t.patt: @Derived.F.%pattern_type.loc9_25 (%pattern_type.afe) = binding_pattern t [concrete]
|
||||
// CHECK:STDOUT: %t.param_patt: @Derived.F.%pattern_type.loc9_25 (%pattern_type.afe) = value_param_pattern %t.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: %self.patt: @Derived.F.%pattern_type.loc9_17 (%pattern_type.423) = binding_pattern self [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt: @Derived.F.%pattern_type.loc9_17 (%pattern_type.423) = value_param_pattern %self.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: %t.patt: @Derived.F.%pattern_type.loc9_29 (%pattern_type.afe) = binding_pattern t [concrete]
|
||||
// CHECK:STDOUT: %t.param_patt: @Derived.F.%pattern_type.loc9_29 (%pattern_type.afe) = value_param_pattern %t.patt, call_param1 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: @Derived.F.%Derived (%Derived) = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc9_19.1: type = splice_block %Self.ref [symbolic = %Derived (constants.%Derived)] {
|
||||
// CHECK:STDOUT: %.loc9_19.2: type = specific_constant constants.%Derived, @Derived(constants.%T) [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc9_19.2 [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: %.loc9_23.1: type = splice_block %Self.ref [symbolic = %Derived (constants.%Derived)] {
|
||||
// CHECK:STDOUT: %.loc9_23.2: type = specific_constant constants.%Derived, @Derived(constants.%T) [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc9_23.2 [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %self: @Derived.F.%Derived (%Derived) = bind_name self, %self.param
|
||||
// CHECK:STDOUT: %t.param: @Derived.F.%ptr.loc9_28 (%ptr.79f) = value_param call_param1
|
||||
// CHECK:STDOUT: %.loc9_29: type = splice_block %ptr.loc9_29 [symbolic = %ptr.loc9_28 (constants.%ptr.79f)] {
|
||||
// CHECK:STDOUT: %t.param: @Derived.F.%ptr.loc9_32 (%ptr.79f) = value_param call_param1
|
||||
// CHECK:STDOUT: %.loc9_33: type = splice_block %ptr.loc9_33 [symbolic = %ptr.loc9_32 (constants.%ptr.79f)] {
|
||||
// CHECK:STDOUT: %T.ref: type = name_ref T, @Derived.%T.loc7_15.2 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %ptr.loc9_29: type = ptr_type %T.ref [symbolic = %ptr.loc9_28 (constants.%ptr.79f)]
|
||||
// CHECK:STDOUT: %ptr.loc9_33: type = ptr_type %T.ref [symbolic = %ptr.loc9_32 (constants.%ptr.79f)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %t: @Derived.F.%ptr.loc9_28 (%ptr.79f) = bind_name t, %t.param
|
||||
// CHECK:STDOUT: %t: @Derived.F.%ptr.loc9_32 (%ptr.79f) = bind_name t, %t.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [symbolic = @Derived.as.Destroy.impl.%Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {}
|
||||
@@ -6283,20 +6283,20 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op";
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic impl fn @Derived.F(@Derived.%T.loc7_15.2: type) {
|
||||
// CHECK:STDOUT: generic override fn @Derived.F(@Derived.%T.loc7_15.2: type) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT: %Derived: type = class_type @Derived, @Derived(%T) [symbolic = %Derived (constants.%Derived)]
|
||||
// CHECK:STDOUT: %pattern_type.loc9_13: type = pattern_type %Derived [symbolic = %pattern_type.loc9_13 (constants.%pattern_type.423)]
|
||||
// CHECK:STDOUT: %ptr.loc9_28: type = ptr_type %T [symbolic = %ptr.loc9_28 (constants.%ptr.79f)]
|
||||
// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%ptr.loc9_28) [symbolic = %Base (constants.%Base.16b)]
|
||||
// CHECK:STDOUT: %require_complete.loc9_28: <witness> = require_complete_type %Base [symbolic = %require_complete.loc9_28 (constants.%require_complete.fce)]
|
||||
// CHECK:STDOUT: %pattern_type.loc9_25: type = pattern_type %ptr.loc9_28 [symbolic = %pattern_type.loc9_25 (constants.%pattern_type.afe)]
|
||||
// CHECK:STDOUT: %pattern_type.loc9_17: type = pattern_type %Derived [symbolic = %pattern_type.loc9_17 (constants.%pattern_type.423)]
|
||||
// CHECK:STDOUT: %ptr.loc9_32: type = ptr_type %T [symbolic = %ptr.loc9_32 (constants.%ptr.79f)]
|
||||
// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%ptr.loc9_32) [symbolic = %Base (constants.%Base.16b)]
|
||||
// CHECK:STDOUT: %require_complete.loc9_32: <witness> = require_complete_type %Base [symbolic = %require_complete.loc9_32 (constants.%require_complete.fce)]
|
||||
// CHECK:STDOUT: %pattern_type.loc9_29: type = pattern_type %ptr.loc9_32 [symbolic = %pattern_type.loc9_29 (constants.%pattern_type.afe)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc9_17: <witness> = require_complete_type %Derived [symbolic = %require_complete.loc9_17 (constants.%require_complete.5f4)]
|
||||
// CHECK:STDOUT: %require_complete.loc9_26: <witness> = require_complete_type %ptr.loc9_28 [symbolic = %require_complete.loc9_26 (constants.%require_complete.6e5)]
|
||||
// CHECK:STDOUT: %require_complete.loc9_21: <witness> = require_complete_type %Derived [symbolic = %require_complete.loc9_21 (constants.%require_complete.5f4)]
|
||||
// CHECK:STDOUT: %require_complete.loc9_30: <witness> = require_complete_type %ptr.loc9_32 [symbolic = %require_complete.loc9_30 (constants.%require_complete.6e5)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn(%self.param: @Derived.F.%Derived (%Derived), %t.param: @Derived.F.%ptr.loc9_28 (%ptr.79f)) {
|
||||
// CHECK:STDOUT: override fn(%self.param: @Derived.F.%Derived (%Derived), %t.param: @Derived.F.%ptr.loc9_32 (%ptr.79f)) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
@@ -6385,15 +6385,15 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: specific @Derived.F(constants.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: %Derived => constants.%Derived
|
||||
// CHECK:STDOUT: %pattern_type.loc9_13 => constants.%pattern_type.423
|
||||
// CHECK:STDOUT: %ptr.loc9_28 => constants.%ptr.79f
|
||||
// CHECK:STDOUT: %pattern_type.loc9_17 => constants.%pattern_type.423
|
||||
// CHECK:STDOUT: %ptr.loc9_32 => constants.%ptr.79f
|
||||
// CHECK:STDOUT: %Base => constants.%Base.16b
|
||||
// CHECK:STDOUT: %require_complete.loc9_28 => constants.%require_complete.fce
|
||||
// CHECK:STDOUT: %pattern_type.loc9_25 => constants.%pattern_type.afe
|
||||
// CHECK:STDOUT: %require_complete.loc9_32 => constants.%require_complete.fce
|
||||
// CHECK:STDOUT: %pattern_type.loc9_29 => constants.%pattern_type.afe
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc9_17 => constants.%require_complete.5f4
|
||||
// CHECK:STDOUT: %require_complete.loc9_26 => constants.%require_complete.6e5
|
||||
// CHECK:STDOUT: %require_complete.loc9_21 => constants.%require_complete.5f4
|
||||
// CHECK:STDOUT: %require_complete.loc9_30 => constants.%require_complete.6e5
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Derived.as.Destroy.impl(constants.%T) {
|
||||
@@ -6623,7 +6623,7 @@ class T2(G2:! type) {
|
||||
// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op";
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived) {
|
||||
// CHECK:STDOUT: override fn @Derived.F(%self.param: %Derived) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -22,11 +22,11 @@ fn F() {
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
default fn F();
|
||||
// CHECK:STDERR: fail_virtual.carbon:[[@LINE+4]]:3: error: `impl` not allowed; requires class scope [ModifierRequiresClass]
|
||||
// CHECK:STDERR: impl fn G();
|
||||
// CHECK:STDERR: ^~~~
|
||||
// CHECK:STDERR: fail_virtual.carbon:[[@LINE+4]]:3: error: `override` not allowed; requires class scope [ModifierRequiresClass]
|
||||
// CHECK:STDERR: override fn G();
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn G();
|
||||
override fn G();
|
||||
// CHECK:STDERR: fail_virtual.carbon:[[@LINE+4]]:3: error: `virtual` not allowed; requires class scope [ModifierRequiresClass]
|
||||
// CHECK:STDERR: virtual fn H();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
|
||||
@@ -46,11 +46,11 @@ import Cpp library "abstract.h";
|
||||
|
||||
class C {
|
||||
extend base: Cpp.A;
|
||||
// CHECK:STDERR: fail_todo_impl_abstract_member.carbon:[[@LINE+4]]:3: error: impl without compatible virtual in base class [ImplWithoutVirtualInBase]
|
||||
// CHECK:STDERR: impl fn f[addr self: Self*]() {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_todo_impl_abstract_member.carbon:[[@LINE+4]]:3: error: override without compatible virtual in base class [OverrideWithoutVirtualInBase]
|
||||
// CHECK:STDERR: override fn f[addr self: Self*]() {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
impl fn f[addr self: Self*]() {}
|
||||
override fn f[addr self: Self*]() {}
|
||||
}
|
||||
|
||||
// --- abstract_final.h
|
||||
|
||||
@@ -289,8 +289,8 @@ CARBON_DIAGNOSTIC_KIND(ClassSpecificDeclOutsideClass)
|
||||
CARBON_DIAGNOSTIC_KIND(ClassSpecificDeclPrevious)
|
||||
CARBON_DIAGNOSTIC_KIND(ClassIncompleteWithinDefinition)
|
||||
CARBON_DIAGNOSTIC_KIND(GenericVirtual)
|
||||
CARBON_DIAGNOSTIC_KIND(ImplWithoutBase)
|
||||
CARBON_DIAGNOSTIC_KIND(ImplWithoutVirtualInBase)
|
||||
CARBON_DIAGNOSTIC_KIND(OverrideWithoutBase)
|
||||
CARBON_DIAGNOSTIC_KIND(OverrideWithoutVirtualInBase)
|
||||
CARBON_DIAGNOSTIC_KIND(VirtualWithoutSelf)
|
||||
|
||||
// Deduction.
|
||||
|
||||
@@ -199,6 +199,7 @@ CARBON_KEYWORD_TOKEN(Not, "not")
|
||||
CARBON_KEYWORD_TOKEN(Observe, "observe")
|
||||
CARBON_TOKEN_WITH_VIRTUAL_NODE(
|
||||
CARBON_KEYWORD_TOKEN(Or, "or"))
|
||||
CARBON_KEYWORD_TOKEN(Override, "override")
|
||||
CARBON_KEYWORD_TOKEN(Partial, "partial")
|
||||
CARBON_KEYWORD_TOKEN(Private, "private")
|
||||
CARBON_KEYWORD_TOKEN(Protected, "protected")
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ base class Intermediate {
|
||||
|
||||
class Derived {
|
||||
extend base: Intermediate;
|
||||
impl fn Fn[self: Self]() { }
|
||||
override fn Fn[self: Self]() { }
|
||||
}
|
||||
|
||||
// --- create.carbon
|
||||
@@ -100,7 +100,7 @@ base class Base {
|
||||
|
||||
class Derived {
|
||||
extend base: Base;
|
||||
impl fn F[self: Self]();
|
||||
override fn F[self: Self]();
|
||||
}
|
||||
|
||||
fn Use() {
|
||||
|
||||
@@ -344,6 +344,7 @@ CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Export)
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Extend)
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Final)
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Impl)
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Override)
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Private)
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Protected)
|
||||
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Virtual)
|
||||
|
||||
@@ -285,8 +285,8 @@ CARBON_PARSE_STATE(DeclNameAndParamsAfterParams)
|
||||
// ^~~~~~
|
||||
// final
|
||||
// ^~~~~
|
||||
// impl fn
|
||||
// ^~~~
|
||||
// override fn
|
||||
// ^~~~~~~~
|
||||
// private
|
||||
// ^~~~~~~
|
||||
// protected
|
||||
|
||||
+8
-1
@@ -37,6 +37,7 @@ fn F() {
|
||||
namespace N;
|
||||
default fn F();
|
||||
impl fn G();
|
||||
override fn H();
|
||||
virtual fn H();
|
||||
private var v: i32;
|
||||
protected var v: i32;
|
||||
@@ -157,6 +158,12 @@ fn F() {
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'OverrideModifier', text: 'override'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'H'},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'VirtualModifier', text: 'virtual'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'H'},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('},
|
||||
@@ -176,6 +183,6 @@ fn F() {
|
||||
// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 58},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 64},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
|
||||
+8
-8
@@ -58,10 +58,10 @@ fn destroy[self: Self]().Foo() {}
|
||||
|
||||
// --- impl_fn.carbon
|
||||
|
||||
impl fn F();
|
||||
abstract impl fn G();
|
||||
impl abstract fn H();
|
||||
private impl default fn I();
|
||||
override fn F();
|
||||
abstract override fn G();
|
||||
override abstract fn H();
|
||||
private override default fn I();
|
||||
|
||||
// --- fail_identifier_instead_of_sig.carbon
|
||||
|
||||
@@ -346,20 +346,20 @@ fn (a tokens c d e f g h i j k l m n o p q r s t u v w x y z);
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'OverrideModifier', text: 'override'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'AbstractModifier', text: 'abstract'},
|
||||
// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'OverrideModifier', text: 'override'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'G'},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'OverrideModifier', text: 'override'},
|
||||
// CHECK:STDOUT: {kind: 'AbstractModifier', text: 'abstract'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'H'},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('},
|
||||
@@ -367,7 +367,7 @@ fn (a tokens c d e f g h i j k l m n o p q r s t u v w x y z);
|
||||
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'PrivateModifier', text: 'private'},
|
||||
// CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'OverrideModifier', text: 'override'},
|
||||
// CHECK:STDOUT: {kind: 'DefaultModifier', text: 'default'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'I'},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('},
|
||||
|
||||
@@ -496,8 +496,8 @@ auto Formatter::FormatFunction(FunctionId id, const Function& fn) -> void {
|
||||
case FunctionFields::VirtualModifier::Abstract:
|
||||
function_start += "abstract ";
|
||||
break;
|
||||
case FunctionFields::VirtualModifier::Impl:
|
||||
function_start += "impl ";
|
||||
case FunctionFields::VirtualModifier::Override:
|
||||
function_start += "override ";
|
||||
break;
|
||||
case FunctionFields::VirtualModifier::None:
|
||||
break;
|
||||
|
||||
@@ -27,7 +27,7 @@ struct FunctionFields {
|
||||
};
|
||||
|
||||
// Kinds of virtual modifiers that can apply to functions.
|
||||
enum class VirtualModifier : uint8_t { None, Virtual, Abstract, Impl };
|
||||
enum class VirtualModifier : uint8_t { None, Virtual, Abstract, Override };
|
||||
|
||||
// The following members always have values, and do not change throughout the
|
||||
// lifetime of the function.
|
||||
|
||||
Reference in New Issue
Block a user