From 1505a634a40b688ee66685663b571f167ace8d85 Mon Sep 17 00:00:00 2001 From: josh11b Date: Thu, 15 Jun 2023 08:42:14 -0700 Subject: [PATCH] Implement syntax changes from #2760 in Explorer (#2906) Implement syntax changes from #2760 in Explorer --- common/fuzzing/carbon.proto | 13 ++- common/fuzzing/proto_to_carbon.cpp | 37 +++--- explorer/ast/ast_kinds.h | 7 +- explorer/ast/declaration.cpp | 48 +++++--- explorer/ast/declaration.h | 60 ++++++---- explorer/data/prelude.carbon | 72 ++++++------ explorer/fuzzing/ast_to_proto.cpp | 28 +++-- ... 2291d3e5898c9c430cc6ecf3855f87bcae68cfbc} | 2 +- ... 29cb786e12d8db536d5f0748863f751ef4db52ce} | 2 +- ... 2b342d5ea73ce8b83dd29a47bda07bb050f62d56} | 2 +- ... 2bbd64b5c75365c1644b9823f9cd572ce53acdd4} | 2 +- ... e16ea66236bb097cd84a5366b1b0035149a138f8} | 4 +- ... e2d470d716b0c66b140be21c060b3cf401703c31} | 4 +- ... efa240ed14717324b4e69b96dd37978d9205e4b5} | 2 +- explorer/interpreter/interpreter.cpp | 5 +- explorer/interpreter/resolve_control_flow.cpp | 5 +- explorer/interpreter/resolve_names.cpp | 28 +++-- explorer/interpreter/resolve_unformed.cpp | 5 +- explorer/interpreter/type_checker.cpp | 108 ++++++++++++------ explorer/syntax/lexer.lpp | 8 +- explorer/syntax/parser.ypp | 80 ++++++++----- .../testdata/alias/member_name_alias.carbon | 2 +- .../array/element_convertible_to_type.carbon | 2 +- explorer/testdata/as/convert.carbon | 2 +- explorer/testdata/as/implicit_as.carbon | 2 +- explorer/testdata/assert/convert.carbon | 2 +- explorer/testdata/assert/fail_convert.carbon | 2 +- .../assert/fail_intrinsic_bool_type.carbon | 2 +- .../assert/fail_intrinsic_no_args.carbon | 2 +- .../assert/fail_intrinsic_no_convert.carbon | 2 +- .../assert/fail_intrinsic_str_type.carbon | 2 +- .../assoc_const/bug_multi_impl_scoping.carbon | 4 +- .../assoc_const/fail_different_type.carbon | 4 +- .../assoc_const/fail_different_value.carbon | 4 +- .../assoc_const/fail_equal_indirectly.carbon | 2 +- .../fail_equal_to_dependent_type.carbon | 2 +- .../assoc_const/fail_incomplete_impl_1.carbon | 2 +- .../assoc_const/fail_incomplete_impl_2.carbon | 2 +- .../assoc_const/fail_indirectly_equal.carbon | 2 +- .../fail_match_in_deduction.carbon | 2 +- .../fail_overspecified_impl.carbon | 2 +- .../testdata/assoc_const/impl_lookup.carbon | 2 +- .../testdata/assoc_const/implement.carbon | 2 +- .../assoc_const/lookup_in_rewrite.carbon | 8 +- .../assoc_const/member_of_value.carbon | 2 +- .../assoc_const/pass_equal_to_rewrite.carbon | 2 +- .../assoc_const/pass_rewrite_to_equal.carbon | 2 +- .../assoc_const/resolve_rewrites.carbon | 2 +- .../assoc_const/rewrite_large_type.carbon | 2 +- explorer/testdata/class/abstract_class.carbon | 3 +- .../testdata/class/base_constructor.carbon | 3 +- .../class_inheritance_function_call.carbon | 3 +- .../class/class_inheritance_methods.carbon | 3 +- .../class/class_inheritance_multiple.carbon | 6 +- .../class/class_inheritance_shadow.carbon | 3 +- .../class/class_inheritance_variables.carbon | 3 +- .../class/class_subtyping_argument.carbon | 6 +- .../class/class_subtyping_basic.carbon | 3 +- .../class/class_subtyping_multiple.carbon | 6 +- .../fail_abstract_method_not_supported.carbon | 3 +- .../class/fail_direct_base_class_init.carbon | 3 +- .../class/fail_extend_after_var.carbon | 20 ++++ ....carbon => fail_extend_final_class.carbon} | 5 +- ...ss.carbon => fail_extend_non_class.carbon} | 5 +- .../testdata/class/fail_extend_twice.carbon | 23 ++++ .../fail_field_access_mismatch_base.carbon | 3 +- .../fail_field_assign_mismatch_base.carbon | 3 +- .../fail_impl_method_not_existing.carbon | 3 +- .../class/fail_impl_method_not_virtual.carbon | 3 +- ...l_override_virtual_with_non_virtual.carbon | 3 +- .../fail_redeclare_virtual_method.carbon | 3 +- .../class/fail_virtual_method_absent.carbon | 3 +- .../class/new_and_delete_hierarchy.carbon | 3 +- .../class/non_virtual_dispatch.carbon | 3 +- .../non_virtual_dispatch_abstract.carbon | 3 +- .../class/parametrized_base_class.carbon | 5 +- .../testdata/class/pointer_conversion.carbon | 6 +- explorer/testdata/class/virtual_method.carbon | 3 +- .../testdata/class/virtual_method_self.carbon | 6 +- .../class/virtual_method_shadowed_attr.carbon | 3 +- .../comparison/custom_equality.carbon | 2 +- .../testdata/comparison/empty_struct.carbon | 2 +- explorer/testdata/constraint/rewrite.carbon | 2 +- .../constraint/rewrite_compound.carbon | 2 +- .../constraint/rewrite_compound_2.carbon | 2 +- .../constraint/rewrite_in_qualifier.carbon | 2 +- .../rewrite_in_qualifier_and_type.carbon | 2 +- .../testdata/constraint/where_impls.carbon | 2 +- .../destructor/destroy_base_class.carbon | 24 ++-- .../destroy_base_class_and_members.carbon | 6 +- ...ete_base_without_virtual_destructor.carbon | 13 ++- .../fail_override_virtual_virtual.carbon | 7 +- .../destructor/virtual_destructor.carbon | 30 ++--- .../virtual_destructor_nested.carbon | 45 ++++---- .../testdata/function/convert_args.carbon | 6 +- .../return_convertible_to_type.carbon | 2 +- .../generic_class/class_function.carbon | 2 +- .../generic_class_substitution.carbon | 2 +- .../generic_fun_and_class.carbon | 2 +- .../generic_class/impl_with_argument.carbon | 2 +- .../generic_class/impl_with_self.carbon | 2 +- .../parameter_type_conversion.carbon | 2 +- .../generic_class/point_with_interface.carbon | 2 +- .../testdata/if_else/convert_condition.carbon | 2 +- .../if_expression/convert_condition.carbon | 2 +- .../testdata/impl/deducible_parameter.carbon | 2 +- .../testdata/impl/fail_bad_member_kind.carbon | 2 +- explorer/testdata/impl/fail_impl_as.carbon | 2 +- .../impl/fail_impl_as_non_interface.carbon | 2 +- .../impl/fail_impl_as_not_constraint.carbon | 2 +- .../impl/fail_impl_as_parameterized.carbon | 2 +- .../impl/fail_impl_redefinition.carbon | 4 +- .../impl/fail_nondeducible_parameter.carbon | 2 +- .../impl/fail_unmet_impls_constraint.carbon | 2 +- .../impl/impl_in_generic_class.carbon | 2 +- .../testdata/impl/impls_constraint.carbon | 4 +- explorer/testdata/impl/param_impl.carbon | 4 +- explorer/testdata/impl/param_impl2.carbon | 4 +- .../testdata/impl/param_impl_with_self.carbon | 4 +- .../testdata/impl_match/match_first.carbon | 8 +- .../impl_match/non_overlapping_labels.carbon | 8 +- .../testdata/impl_match/specialization.carbon | 4 +- .../impl_match/type_structure_bindings.carbon | 12 +- .../impl_match/type_structure_order.carbon | 6 +- .../type_structure_vs_match_first.carbon | 6 +- explorer/testdata/interface/addr_self.carbon | 2 +- ...assoc_constant_constraints_in_scope.carbon | 6 +- .../testdata/interface/class_function.carbon | 2 +- .../interface/constrained_parameter.carbon | 4 +- .../{extends.carbon => extend.carbon} | 4 +- .../external_impl_point_vector.carbon | 2 +- .../interface/external_impl_use_self.carbon | 2 +- .../interface/fail_extend_external.carbon | 20 ++++ ...rbon => fail_extend_not_constraint.carbon} | 4 +- .../interface/fail_extend_with_self.carbon | 28 +++++ .../fail_external_impl_omit_self.carbon | 2 +- .../interface/fail_external_impl_self.carbon | 2 +- .../interface/fail_impl_bad_member.carbon | 2 +- .../interface/fail_impl_missing_member.carbon | 2 +- .../fail_interface_missing_member.carbon | 2 +- ...bon => fail_require_not_constraint.carbon} | 4 +- ...pe.carbon => fail_require_not_type.carbon} | 4 +- .../interface/generic_call_generic.carbon | 2 +- .../interface/generic_with_two_params.carbon | 4 +- explorer/testdata/interface/omit_self.carbon | 2 +- .../testdata/interface/parameterized.carbon | 2 +- .../{impl_as.carbon => require.carbon} | 6 +- ...ot_self.carbon => require_not_self.carbon} | 6 +- .../interface/tuple_vector_add_scale.carbon | 2 +- .../interface/vector_point_add_scale.carbon | 2 +- explorer/testdata/interface/with_self.carbon | 2 +- .../testdata/let/implicit_conversion.carbon | 2 +- .../member_access/convert_lhs_class.carbon | 2 +- .../convert_lhs_interface.carbon | 4 +- .../member_access/fail_vacuous_access.carbon | 2 +- .../fail_vacuous_access_via_type_param.carbon | 2 +- ...rly_vacuous_access_with_impl_lookup.carbon | 2 +- ...acuous_access_with_instance_binding.carbon | 2 +- .../param_qualified_interface_member.carbon | 2 +- .../qualified_constraint_member.carbon | 4 +- .../qualified_interface_member.carbon | 2 +- .../qualified_param_member.carbon | 2 +- .../testdata/mixin/fail_mix_in_impl.carbon | 2 +- .../{extends.carbon => extend.carbon} | 6 +- .../fail_compound_member_access.carbon | 4 +- ...rbon => fail_require_member_access.carbon} | 4 +- .../named_constraint/impl_constraint.carbon | 6 +- .../{impl_as.carbon => require.carbon} | 8 +- explorer/testdata/namespace/members.carbon | 6 +- explorer/testdata/operators/add.carbon | 2 +- explorer/testdata/operators/add_with.carbon | 2 +- explorer/testdata/operators/bit_and.carbon | 2 +- .../testdata/operators/bit_complement.carbon | 2 +- explorer/testdata/operators/bit_or.carbon | 2 +- explorer/testdata/operators/bit_xor.carbon | 2 +- explorer/testdata/operators/div.carbon | 2 +- explorer/testdata/operators/inc_dec.carbon | 4 +- explorer/testdata/operators/left_shift.carbon | 2 +- explorer/testdata/operators/mod.carbon | 2 +- explorer/testdata/operators/mul.carbon | 2 +- explorer/testdata/operators/negate.carbon | 2 +- .../testdata/operators/right_shift.carbon | 2 +- explorer/testdata/operators/sub.carbon | 2 +- .../pointer/pointer_to_type_like.carbon | 2 +- .../testdata/print/associated_constant.carbon | 4 +- .../return/convert_return_value.carbon | 2 +- explorer/testdata/struct/equality.carbon | 2 +- .../testdata/struct/equality_false.carbon | 2 +- .../testdata/struct/fail_equality_type.carbon | 2 +- .../struct/field_convertible_to_type.carbon | 2 +- .../testdata/template/fail_name_lookup.carbon | 4 +- explorer/testdata/template/name_lookup.carbon | 4 +- explorer/testdata/tuple/convert.carbon | 4 +- .../fail_implicit_convert_with_as.carbon | 2 +- .../testdata/unformed/fail_base_access.carbon | 4 +- .../testdata/while/convert_condition.carbon | 2 +- 196 files changed, 755 insertions(+), 483 deletions(-) rename explorer/fuzzing/fuzzer_corpus/{9a435ff6608006cf717e4ea6d7e22a793081b096 => 2291d3e5898c9c430cc6ecf3855f87bcae68cfbc} (96%) rename explorer/fuzzing/fuzzer_corpus/{f4442e613969488b64b568701f015baa552df409 => 29cb786e12d8db536d5f0748863f751ef4db52ce} (99%) rename explorer/fuzzing/fuzzer_corpus/{693b9959c2755a9a294266be5333fe1a08dd7732 => 2b342d5ea73ce8b83dd29a47bda07bb050f62d56} (99%) rename explorer/fuzzing/fuzzer_corpus/{a6cbb1c4cbbae44391bce60832b7f9b034f3839e => 2bbd64b5c75365c1644b9823f9cd572ce53acdd4} (99%) rename explorer/fuzzing/fuzzer_corpus/{6740e9ab30860f2c0277ff36e850c53ca4091e89 => e16ea66236bb097cd84a5366b1b0035149a138f8} (99%) rename explorer/fuzzing/fuzzer_corpus/{1ac93b3166a73257d35daabe1224a4fa02b91438 => e2d470d716b0c66b140be21c060b3cf401703c31} (99%) rename explorer/fuzzing/fuzzer_corpus/{c1dda40eae19225720932d324f3f0610f31ab471 => efa240ed14717324b4e69b96dd37978d9205e4b5} (99%) create mode 100644 explorer/testdata/class/fail_extend_after_var.carbon rename explorer/testdata/class/{fail_extends_final_class.carbon => fail_extend_final_class.carbon} (56%) rename explorer/testdata/class/{fail_extends_non_class.carbon => fail_extend_non_class.carbon} (61%) create mode 100644 explorer/testdata/class/fail_extend_twice.carbon rename explorer/testdata/interface/{extends.carbon => extend.carbon} (92%) create mode 100644 explorer/testdata/interface/fail_extend_external.carbon rename explorer/testdata/interface/{fail_extends_not_constraint.carbon => fail_extend_not_constraint.carbon} (65%) create mode 100644 explorer/testdata/interface/fail_extend_with_self.carbon rename explorer/testdata/interface/{fail_impl_as_not_constraint.carbon => fail_require_not_constraint.carbon} (66%) rename explorer/testdata/interface/{fail_impl_as_not_type.carbon => fail_require_not_type.carbon} (82%) rename explorer/testdata/interface/{impl_as.carbon => require.carbon} (87%) rename explorer/testdata/interface/{impl_as_not_self.carbon => require_not_self.carbon} (80%) rename explorer/testdata/named_constraint/{extends.carbon => extend.carbon} (92%) rename explorer/testdata/named_constraint/{fail_impl_as_member_access.carbon => fail_require_member_access.carbon} (84%) rename explorer/testdata/named_constraint/{impl_as.carbon => require.carbon} (80%) diff --git a/common/fuzzing/carbon.proto b/common/fuzzing/carbon.proto index 45a398a538b8..905414eb816c 100644 --- a/common/fuzzing/carbon.proto +++ b/common/fuzzing/carbon.proto @@ -371,6 +371,10 @@ message ClassDeclaration { optional TuplePattern type_params = 3; } +message ExtendBaseDeclaration { + optional Expression base_class = 1; +} + message AlternativeSignature { optional string name = 1; optional TupleLiteralExpression signature = 3; @@ -392,11 +396,11 @@ message LetDeclaration { // `let` declarations in general. } -message InterfaceExtendsDeclaration { +message InterfaceExtendDeclaration { optional Expression base = 1; } -message InterfaceImplDeclaration { +message InterfaceRequireDeclaration { optional Expression impl_type = 1; optional Expression constraint = 2; } @@ -465,11 +469,12 @@ message Declaration { MixinDeclaration mixin = 9; MixDeclaration mix = 10; DestructorDeclaration destructor = 11; - InterfaceExtendsDeclaration interface_extends = 12; - InterfaceImplDeclaration interface_impl = 13; + InterfaceExtendDeclaration interface_extend = 12; + InterfaceRequireDeclaration interface_require = 13; ConstraintDeclaration constraint = 14; MatchFirstDeclaration match_first = 15; NamespaceDeclaration namespace = 16; + ExtendBaseDeclaration extend_base = 17; } } diff --git a/common/fuzzing/proto_to_carbon.cpp b/common/fuzzing/proto_to_carbon.cpp index 139f4802e886..1bcd1c2f2ed7 100644 --- a/common/fuzzing/proto_to_carbon.cpp +++ b/common/fuzzing/proto_to_carbon.cpp @@ -801,6 +801,14 @@ static auto DeclarationToCarbon(const Fuzzing::Declaration& declaration, break; } + case Fuzzing::Declaration::kExtendBase: { + const auto& extend_base_declaration = declaration.extend_base(); + out << " extend base: "; + ExpressionToCarbon(extend_base_declaration.base_class(), out); + out << ";\n"; + break; + } + // EXPERIMENTAL MIXIN FEATURE case Fuzzing::Declaration::kMixin: { const auto& mixin_declaration = declaration.mixin(); @@ -877,19 +885,19 @@ static auto DeclarationToCarbon(const Fuzzing::Declaration& declaration, break; } - case Fuzzing::Declaration::kInterfaceExtends: { - const auto& extends = declaration.interface_extends(); - out << "extends "; - ExpressionToCarbon(extends.base(), out); + case Fuzzing::Declaration::kInterfaceExtend: { + const auto& extend = declaration.interface_extend(); + out << "extend "; + ExpressionToCarbon(extend.base(), out); out << ";"; break; } - case Fuzzing::Declaration::kInterfaceImpl: { - const auto& impl = declaration.interface_impl(); - out << "impl "; + case Fuzzing::Declaration::kInterfaceRequire: { + const auto& impl = declaration.interface_require(); + out << "require "; ExpressionToCarbon(impl.impl_type(), out); - out << " as "; + out << " impls "; ExpressionToCarbon(impl.constraint(), out); out << ";"; break; @@ -923,8 +931,8 @@ static auto DeclarationToCarbon(const Fuzzing::Declaration& declaration, case Fuzzing::Declaration::kImpl: { const auto& impl = declaration.impl(); - if (impl.kind() == Fuzzing::ImplDeclaration::ExternalImpl) { - out << "external "; + if (impl.kind() == Fuzzing::ImplDeclaration::InternalImpl) { + out << "extend "; } out << "impl "; if (!impl.deduced_parameters().empty()) { @@ -934,10 +942,13 @@ static auto DeclarationToCarbon(const Fuzzing::Declaration& declaration, out << sep; GenericBindingToCarbon(p, out); } - out << "]"; + out << "] "; } - ExpressionToCarbon(impl.impl_type(), out); - out << " as "; + if (impl.kind() != Fuzzing::ImplDeclaration::InternalImpl) { + ExpressionToCarbon(impl.impl_type(), out); + out << " "; + } + out << "as "; ExpressionToCarbon(impl.interface(), out); out << " {\n"; for (const auto& member : impl.members()) { diff --git a/explorer/ast/ast_kinds.h b/explorer/ast/ast_kinds.h index 8d59438b2a89..675387c3f57e 100644 --- a/explorer/ast/ast_kinds.h +++ b/explorer/ast/ast_kinds.h @@ -78,12 +78,13 @@ FINAL(VariableDeclaration) \ CARBON_ConstraintTypeDeclaration_KINDS(ABSTRACT, FINAL) \ ABSTRACT(ConstraintTypeDeclaration) \ - FINAL(InterfaceExtendsDeclaration) \ - FINAL(InterfaceImplDeclaration) \ + FINAL(InterfaceExtendDeclaration) \ + FINAL(InterfaceRequireDeclaration) \ FINAL(AssociatedConstantDeclaration) \ FINAL(ImplDeclaration) \ FINAL(MatchFirstDeclaration) \ - FINAL(AliasDeclaration) + FINAL(AliasDeclaration) \ + FINAL(ExtendBaseDeclaration) #define CARBON_CallableDeclaration_KINDS(ABSTRACT, FINAL) \ FINAL(FunctionDeclaration) \ diff --git a/explorer/ast/declaration.cpp b/explorer/ast/declaration.cpp index 141ab7b68cda..4fb7930790f7 100644 --- a/explorer/ast/declaration.cpp +++ b/explorer/ast/declaration.cpp @@ -108,8 +108,8 @@ void Declaration::Print(llvm::raw_ostream& out) const { break; } - case DeclarationKind::InterfaceExtendsDeclaration: - case DeclarationKind::InterfaceImplDeclaration: + case DeclarationKind::InterfaceExtendDeclaration: + case DeclarationKind::InterfaceRequireDeclaration: case DeclarationKind::AssociatedConstantDeclaration: { PrintID(out); out << ";\n"; @@ -127,6 +127,12 @@ void Declaration::Print(llvm::raw_ostream& out) const { out << " = " << alias.target() << ";\n"; break; } + + case DeclarationKind::ExtendBaseDeclaration: { + PrintID(out); + out << ";\n"; + break; + } } } @@ -149,9 +155,9 @@ void Declaration::PrintID(llvm::raw_ostream& out) const { const auto& impl_decl = cast(*this); switch (impl_decl.kind()) { case ImplKind::InternalImpl: + out << "extend "; break; case ImplKind::ExternalImpl: - out << "external "; break; } out << "impl "; @@ -163,7 +169,10 @@ void Declaration::PrintID(llvm::raw_ostream& out) const { } out << "] "; } - out << *impl_decl.impl_type() << " as " << impl_decl.interface(); + if (impl_decl.kind() != ImplKind::InternalImpl) { + out << *impl_decl.impl_type() << " "; + } + out << "as " << impl_decl.interface(); break; } case DeclarationKind::MatchFirstDeclaration: @@ -204,15 +213,15 @@ void Declaration::PrintID(llvm::raw_ostream& out) const { break; } - case DeclarationKind::InterfaceExtendsDeclaration: { - const auto& extends = cast(*this); - out << "extends " << *extends.base(); + case DeclarationKind::InterfaceExtendDeclaration: { + const auto& extend = cast(*this); + out << "extend " << *extend.base(); break; } - case DeclarationKind::InterfaceImplDeclaration: { - const auto& impl = cast(*this); - out << "impl " << *impl.impl_type() << " as " << *impl.constraint(); + case DeclarationKind::InterfaceRequireDeclaration: { + const auto& impl = cast(*this); + out << "require " << *impl.impl_type() << " impls " << *impl.constraint(); break; } @@ -232,6 +241,12 @@ void Declaration::PrintID(llvm::raw_ostream& out) const { out << "alias " << alias.name(); break; } + + case DeclarationKind::ExtendBaseDeclaration: { + const auto& extend = cast(*this); + out << "extend base: " << *extend.base_class(); + break; + } } } @@ -268,8 +283,8 @@ auto GetName(const Declaration& declaration) return cast(declaration).binding().name(); case DeclarationKind::AssociatedConstantDeclaration: return cast(declaration).binding().name(); - case DeclarationKind::InterfaceExtendsDeclaration: - case DeclarationKind::InterfaceImplDeclaration: + case DeclarationKind::InterfaceExtendDeclaration: + case DeclarationKind::InterfaceRequireDeclaration: case DeclarationKind::ImplDeclaration: case DeclarationKind::MatchFirstDeclaration: return std::nullopt; @@ -278,6 +293,9 @@ auto GetName(const Declaration& declaration) case DeclarationKind::AliasDeclaration: { return cast(declaration).name().inner_name(); } + case DeclarationKind::ExtendBaseDeclaration: { + return "extend base"; + } } } @@ -417,10 +435,14 @@ ClassDeclaration::ClassDeclaration(CloneContext& context, extensibility_(other.extensibility_), self_decl_(context.Clone(other.self_decl_)), type_params_(context.Clone(other.type_params_)), - base_expr_(context.Clone(other.base_expr_)), members_(context.Clone(other.members_)), base_type_(context.Clone(other.base_type_)) {} +ExtendBaseDeclaration::ExtendBaseDeclaration(CloneContext& context, + const ExtendBaseDeclaration& other) + : Declaration(context, other), + base_class_(context.Clone(other.base_class_)) {} + ConstraintTypeDeclaration::ConstraintTypeDeclaration( CloneContext& context, const ConstraintTypeDeclaration& other) : Declaration(context, other), diff --git a/explorer/ast/declaration.h b/explorer/ast/declaration.h index 8ed6d9d62e7e..b3f11f506f50 100644 --- a/explorer/ast/declaration.h +++ b/explorer/ast/declaration.h @@ -375,14 +375,12 @@ class ClassDeclaration : public Declaration { Nonnull self_decl, ClassExtensibility extensibility, std::optional> type_params, - std::optional> base, std::vector> members) : Declaration(AstNodeKind::ClassDeclaration, source_loc), name_(std::move(name)), extensibility_(extensibility), self_decl_(self_decl), type_params_(type_params), - base_expr_(base), members_(std::move(members)) {} explicit ClassDeclaration(CloneContext& context, @@ -420,10 +418,6 @@ class ClassDeclaration : public Declaration { return ExpressionCategory::Value; } - auto base_expr() const -> std::optional> { - return base_expr_; - } - // Returns the original base type, before instantiation & substitutions // Use `NominalClassType::base()` to get the instantiated type. auto base_type() const -> std::optional> { @@ -439,7 +433,6 @@ class ClassDeclaration : public Declaration { ClassExtensibility extensibility_; Nonnull self_decl_; std::optional> type_params_; - std::optional> base_expr_; std::vector> members_; std::optional> base_type_; }; @@ -520,6 +513,27 @@ class MixDeclaration : public Declaration { std::optional> mixin_value_; }; +class ExtendBaseDeclaration : public Declaration { + public: + ExtendBaseDeclaration(SourceLocation source_loc, + Nonnull base_class) + : Declaration(AstNodeKind::ExtendBaseDeclaration, source_loc), + base_class_(base_class) {} + + explicit ExtendBaseDeclaration(CloneContext& context, + const ExtendBaseDeclaration& other); + + static auto classof(const AstNode* node) -> bool { + return InheritsFromExtendBaseDeclaration(node->kind()); + } + + auto base_class() const -> Nonnull { return base_class_; } + auto base_class() -> Nonnull { return base_class_; } + + private: + Nonnull base_class_; +}; + class AlternativeSignature : public AstNode { public: AlternativeSignature(SourceLocation source_loc, std::string name, @@ -789,19 +803,19 @@ class ConstraintDeclaration : public ConstraintTypeDeclaration { }; // An `extends` declaration in an interface. -class InterfaceExtendsDeclaration : public Declaration { +class InterfaceExtendDeclaration : public Declaration { public: - InterfaceExtendsDeclaration(SourceLocation source_loc, - Nonnull base) - : Declaration(AstNodeKind::InterfaceExtendsDeclaration, source_loc), + InterfaceExtendDeclaration(SourceLocation source_loc, + Nonnull base) + : Declaration(AstNodeKind::InterfaceExtendDeclaration, source_loc), base_(base) {} - explicit InterfaceExtendsDeclaration(CloneContext& context, - const InterfaceExtendsDeclaration& other) + explicit InterfaceExtendDeclaration(CloneContext& context, + const InterfaceExtendDeclaration& other) : Declaration(context, other), base_(context.Clone(other.base_)) {} static auto classof(const AstNode* node) -> bool { - return InheritsFromInterfaceExtendsDeclaration(node->kind()); + return InheritsFromInterfaceExtendDeclaration(node->kind()); } auto base() const -> const Expression* { return base_; } @@ -811,24 +825,24 @@ class InterfaceExtendsDeclaration : public Declaration { Nonnull base_; }; -// An `impl ... as` declaration in an interface. -class InterfaceImplDeclaration : public Declaration { +// A `require ... impls` declaration in an interface. +class InterfaceRequireDeclaration : public Declaration { public: - InterfaceImplDeclaration(SourceLocation source_loc, - Nonnull impl_type, - Nonnull constraint) - : Declaration(AstNodeKind::InterfaceImplDeclaration, source_loc), + InterfaceRequireDeclaration(SourceLocation source_loc, + Nonnull impl_type, + Nonnull constraint) + : Declaration(AstNodeKind::InterfaceRequireDeclaration, source_loc), impl_type_(impl_type), constraint_(constraint) {} - explicit InterfaceImplDeclaration(CloneContext& context, - const InterfaceImplDeclaration& other) + explicit InterfaceRequireDeclaration(CloneContext& context, + const InterfaceRequireDeclaration& other) : Declaration(context, other), impl_type_(context.Clone(other.impl_type_)), constraint_(context.Clone(other.constraint_)) {} static auto classof(const AstNode* node) -> bool { - return InheritsFromInterfaceImplDeclaration(node->kind()); + return InheritsFromInterfaceRequireDeclaration(node->kind()); } auto impl_type() const -> const Expression* { return impl_type_; } diff --git a/explorer/data/prelude.carbon b/explorer/data/prelude.carbon index 1cc9b0c2fea2..dea79da15105 100644 --- a/explorer/data/prelude.carbon +++ b/explorer/data/prelude.carbon @@ -15,7 +15,7 @@ interface As(T:! type) { // Implicitly convert `Self` to `T`. interface ImplicitAs(T:! type) { - extends As(T); + extend As(T); } // TODO: This should be private. @@ -87,7 +87,7 @@ interface EqWith(U:! type) { } constraint Eq { - extends EqWith(Self); + extend EqWith(Self); } // TODO: Simplify this once we have variadics @@ -151,7 +151,7 @@ interface CompareWith(U:! type) { // TODO: Add `default fn` for Less, LessOrEquivalent, Greater, and GreaterOrEquivalent once it's available. } constraint Ordered { - extends CompareWith(Self); + extend CompareWith(Self); } impl i32 as CompareWith(Self) { @@ -327,7 +327,7 @@ interface AddWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint Add { - extends AddWith(Self) where .Result = Self; + extend AddWith(Self) where .Result = Self; } interface SubWith(U:! type) { @@ -336,7 +336,7 @@ interface SubWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint Sub { - extends SubWith(Self) where .Result = Self; + extend SubWith(Self) where .Result = Self; } interface MulWith(U:! type) { @@ -345,7 +345,7 @@ interface MulWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint Mul { - extends MulWith(Self) where .Result = Self; + extend MulWith(Self) where .Result = Self; } interface DivWith(U:! type) { @@ -354,7 +354,7 @@ interface DivWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint Div { - extends DivWith(Self) where .Result = Self; + extend DivWith(Self) where .Result = Self; } interface ModWith(U:! type) { @@ -363,26 +363,26 @@ interface ModWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint Mod { - extends ModWith(Self) where .Result = Self; + extend ModWith(Self) where .Result = Self; } // Note, these impl declarations use the builtin addition for i32. -external impl i32 as Negate where .Result = i32 { +impl i32 as Negate where .Result = i32 { fn Op[self: i32]() -> i32 { return -self; } } -external impl i32 as AddWith(i32) where .Result = i32 { +impl i32 as AddWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return self + other; } } -external impl i32 as SubWith(i32) where .Result = i32 { +impl i32 as SubWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return self - other; } } -external impl i32 as MulWith(i32) where .Result = i32 { +impl i32 as MulWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return self * other; } } -external impl i32 as DivWith(i32) where .Result = i32 { +impl i32 as DivWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return self / other; } } -external impl i32 as ModWith(i32) where .Result = i32 { +impl i32 as ModWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return self % other; } } @@ -404,7 +404,7 @@ interface BitAndWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint BitAnd { - extends BitAndWith(Self) where .Result = Self; + extend BitAndWith(Self) where .Result = Self; } // Binary `|`. @@ -414,7 +414,7 @@ interface BitOrWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint BitOr { - extends BitOrWith(Self) where .Result = Self; + extend BitOrWith(Self) where .Result = Self; } // Binary `^`. @@ -424,7 +424,7 @@ interface BitXorWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint BitXor { - extends BitXorWith(Self) where .Result = Self; + extend BitXorWith(Self) where .Result = Self; } // Binary `<<`. @@ -434,7 +434,7 @@ interface LeftShiftWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint LeftShift { - extends LeftShiftWith(Self) where .Result = Self; + extend LeftShiftWith(Self) where .Result = Self; } // Binary `>>`. @@ -444,35 +444,35 @@ interface RightShiftWith(U:! type) { fn Op[self: Self](other: U) -> Result; } constraint RightShift { - extends RightShiftWith(Self) where .Result = Self; + extend RightShiftWith(Self) where .Result = Self; } -external impl i32 as BitComplement where .Result = i32 { +impl i32 as BitComplement where .Result = i32 { fn Op[self: i32]() -> i32 { return __intrinsic_int_bit_complement(self); } } -external impl i32 as BitAndWith(i32) where .Result = i32 { +impl i32 as BitAndWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return __intrinsic_int_bit_and(self, other); } } -external impl i32 as BitOrWith(i32) where .Result = i32 { +impl i32 as BitOrWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return __intrinsic_int_bit_or(self, other); } } -external impl i32 as BitXorWith(i32) where .Result = i32 { +impl i32 as BitXorWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return __intrinsic_int_bit_xor(self, other); } } -external impl i32 as LeftShiftWith(i32) where .Result = i32 { +impl i32 as LeftShiftWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return __intrinsic_int_left_shift(self, other); } } -external impl i32 as RightShiftWith(i32) where .Result = i32 { +impl i32 as RightShiftWith(i32) where .Result = i32 { fn Op[self: i32](other: i32) -> i32 { return __intrinsic_int_right_shift(self, other); } @@ -485,57 +485,57 @@ external impl i32 as RightShiftWith(i32) where .Result = i32 { interface AssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint Assign { extends AssignWith(Self); } +constraint Assign { extend AssignWith(Self); } interface AddAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint AddAssign { extends AddAssignWith(Self); } +constraint AddAssign { extend AddAssignWith(Self); } interface SubAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint SubAssign { extends SubAssignWith(Self); } +constraint SubAssign { extend SubAssignWith(Self); } interface MulAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint MulAssign { extends MulAssignWith(Self); } +constraint MulAssign { extend MulAssignWith(Self); } interface DivAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint DivAssign { extends DivAssignWith(Self); } +constraint DivAssign { extend DivAssignWith(Self); } interface ModAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint ModAssign { extends ModAssignWith(Self); } +constraint ModAssign { extend ModAssignWith(Self); } interface BitAndAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint BitAssignAnd { extends BitAndAssignWith(Self); } +constraint BitAssignAnd { extend BitAndAssignWith(Self); } interface BitOrAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint BitAssignOr { extends BitOrAssignWith(Self); } +constraint BitAssignOr { extend BitOrAssignWith(Self); } interface BitXorAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint BitAssignXor { extends BitXorAssignWith(Self); } +constraint BitAssignXor { extend BitXorAssignWith(Self); } interface LeftShiftAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint LeftShiftAssign { extends LeftShiftAssignWith(Self); } +constraint LeftShiftAssign { extend LeftShiftAssignWith(Self); } interface RightShiftAssignWith(U:! type) { fn Op[addr self: Self*](other: U); } -constraint RightShiftAssign { extends RightShiftAssignWith(Self); } +constraint RightShiftAssign { extend RightShiftAssignWith(Self); } // TODO: This is temporary, and should eventually be replaced by // something more fine-grained. Not all class types should be diff --git a/explorer/fuzzing/ast_to_proto.cpp b/explorer/fuzzing/ast_to_proto.cpp index e3d51f05f8fb..62e7ce0b6d1f 100644 --- a/explorer/fuzzing/ast_to_proto.cpp +++ b/explorer/fuzzing/ast_to_proto.cpp @@ -756,18 +756,20 @@ static auto DeclarationToProto(const Declaration& declaration) break; } - case DeclarationKind::InterfaceExtendsDeclaration: { - const auto& extends = cast(declaration); - auto* extends_proto = declaration_proto.mutable_interface_extends(); - *extends_proto->mutable_base() = ExpressionToProto(*extends.base()); + case DeclarationKind::InterfaceExtendDeclaration: { + const auto& extend = cast(declaration); + auto* extend_proto = declaration_proto.mutable_interface_extend(); + *extend_proto->mutable_base() = ExpressionToProto(*extend.base()); break; } - case DeclarationKind::InterfaceImplDeclaration: { - const auto& impl = cast(declaration); - auto* impl_proto = declaration_proto.mutable_interface_impl(); - *impl_proto->mutable_impl_type() = ExpressionToProto(*impl.impl_type()); - *impl_proto->mutable_constraint() = ExpressionToProto(*impl.constraint()); + case DeclarationKind::InterfaceRequireDeclaration: { + const auto& require = cast(declaration); + auto* require_proto = declaration_proto.mutable_interface_require(); + *require_proto->mutable_impl_type() = + ExpressionToProto(*require.impl_type()); + *require_proto->mutable_constraint() = + ExpressionToProto(*require.constraint()); break; } @@ -841,6 +843,14 @@ static auto DeclarationToProto(const Declaration& declaration) *alias_proto->mutable_target() = ExpressionToProto(alias.target()); break; } + + case DeclarationKind::ExtendBaseDeclaration: { + const auto& extend_base = cast(declaration); + auto* extend_base_proto = declaration_proto.mutable_extend_base(); + *extend_base_proto->mutable_base_class() = + ExpressionToProto(*extend_base.base_class()); + break; + } } return declaration_proto; } diff --git a/explorer/fuzzing/fuzzer_corpus/9a435ff6608006cf717e4ea6d7e22a793081b096 b/explorer/fuzzing/fuzzer_corpus/2291d3e5898c9c430cc6ecf3855f87bcae68cfbc similarity index 96% rename from explorer/fuzzing/fuzzer_corpus/9a435ff6608006cf717e4ea6d7e22a793081b096 rename to explorer/fuzzing/fuzzer_corpus/2291d3e5898c9c430cc6ecf3855f87bcae68cfbc index 90896099f05e..b53426f6bde6 100644 --- a/explorer/fuzzing/fuzzer_corpus/9a435ff6608006cf717e4ea6d7e22a793081b096 +++ b/explorer/fuzzing/fuzzer_corpus/2291d3e5898c9c430cc6ecf3855f87bcae68cfbc @@ -9,7 +9,7 @@ compilation_unit { name: "Vector" } members { - interface_extends { + interface_extend { base { int_type_literal { } diff --git a/explorer/fuzzing/fuzzer_corpus/f4442e613969488b64b568701f015baa552df409 b/explorer/fuzzing/fuzzer_corpus/29cb786e12d8db536d5f0748863f751ef4db52ce similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/f4442e613969488b64b568701f015baa552df409 rename to explorer/fuzzing/fuzzer_corpus/29cb786e12d8db536d5f0748863f751ef4db52ce index 5cdb3a777c42..3692a474cfc4 100644 --- a/explorer/fuzzing/fuzzer_corpus/f4442e613969488b64b568701f015baa552df409 +++ b/explorer/fuzzing/fuzzer_corpus/29cb786e12d8db536d5f0748863f751ef4db52ce @@ -137,7 +137,7 @@ compilation_unit { name: "Constraint" } members { - interface_extends { + interface_extend { base { identifier { name: "Iface" diff --git a/explorer/fuzzing/fuzzer_corpus/693b9959c2755a9a294266be5333fe1a08dd7732 b/explorer/fuzzing/fuzzer_corpus/2b342d5ea73ce8b83dd29a47bda07bb050f62d56 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/693b9959c2755a9a294266be5333fe1a08dd7732 rename to explorer/fuzzing/fuzzer_corpus/2b342d5ea73ce8b83dd29a47bda07bb050f62d56 index 185d63f3f9a8..1497f0aa56fe 100644 --- a/explorer/fuzzing/fuzzer_corpus/693b9959c2755a9a294266be5333fe1a08dd7732 +++ b/explorer/fuzzing/fuzzer_corpus/2b342d5ea73ce8b83dd29a47bda07bb050f62d56 @@ -74,7 +74,7 @@ compilation_unit { name: "MyAdd" } members { - interface_extends { + interface_extend { base { where { base { diff --git a/explorer/fuzzing/fuzzer_corpus/a6cbb1c4cbbae44391bce60832b7f9b034f3839e b/explorer/fuzzing/fuzzer_corpus/2bbd64b5c75365c1644b9823f9cd572ce53acdd4 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/a6cbb1c4cbbae44391bce60832b7f9b034f3839e rename to explorer/fuzzing/fuzzer_corpus/2bbd64b5c75365c1644b9823f9cd572ce53acdd4 index 8fa248d6a982..8038fd6badac 100644 --- a/explorer/fuzzing/fuzzer_corpus/a6cbb1c4cbbae44391bce60832b7f9b034f3839e +++ b/explorer/fuzzing/fuzzer_corpus/2bbd64b5c75365c1644b9823f9cd572ce53acdd4 @@ -47,7 +47,7 @@ compilation_unit { name: "Banana" } members { - interface_extends { + interface_extend { base { call { function { diff --git a/explorer/fuzzing/fuzzer_corpus/6740e9ab30860f2c0277ff36e850c53ca4091e89 b/explorer/fuzzing/fuzzer_corpus/e16ea66236bb097cd84a5366b1b0035149a138f8 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/6740e9ab30860f2c0277ff36e850c53ca4091e89 rename to explorer/fuzzing/fuzzer_corpus/e16ea66236bb097cd84a5366b1b0035149a138f8 index e923bc731c7b..516f6c55aa18 100644 --- a/explorer/fuzzing/fuzzer_corpus/6740e9ab30860f2c0277ff36e850c53ca4091e89 +++ b/explorer/fuzzing/fuzzer_corpus/e16ea66236bb097cd84a5366b1b0035149a138f8 @@ -47,7 +47,7 @@ compilation_unit { name: "IndirectMaker" } members { - interface_extends { + interface_extend { base { call { function { @@ -81,7 +81,7 @@ compilation_unit { name: "MoreIndirectMaker" } members { - interface_extends { + interface_extend { base { call { function { diff --git a/explorer/fuzzing/fuzzer_corpus/1ac93b3166a73257d35daabe1224a4fa02b91438 b/explorer/fuzzing/fuzzer_corpus/e2d470d716b0c66b140be21c060b3cf401703c31 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/1ac93b3166a73257d35daabe1224a4fa02b91438 rename to explorer/fuzzing/fuzzer_corpus/e2d470d716b0c66b140be21c060b3cf401703c31 index eb1e4453d6f5..848327386564 100644 --- a/explorer/fuzzing/fuzzer_corpus/1ac93b3166a73257d35daabe1224a4fa02b91438 +++ b/explorer/fuzzing/fuzzer_corpus/e2d470d716b0c66b140be21c060b3cf401703c31 @@ -83,7 +83,7 @@ compilation_unit { name: "Traversible" } members { - interface_extends { + interface_extend { base { identifier { name: "Runnable" @@ -92,7 +92,7 @@ compilation_unit { } } members { - interface_extends { + interface_extend { base { identifier { name: "Walkable" diff --git a/explorer/fuzzing/fuzzer_corpus/c1dda40eae19225720932d324f3f0610f31ab471 b/explorer/fuzzing/fuzzer_corpus/efa240ed14717324b4e69b96dd37978d9205e4b5 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/c1dda40eae19225720932d324f3f0610f31ab471 rename to explorer/fuzzing/fuzzer_corpus/efa240ed14717324b4e69b96dd37978d9205e4b5 index 25c73cdcb178..239b45645830 100644 --- a/explorer/fuzzing/fuzzer_corpus/c1dda40eae19225720932d324f3f0610f31ab471 +++ b/explorer/fuzzing/fuzzer_corpus/efa240ed14717324b4e69b96dd37978d9205e4b5 @@ -28,7 +28,7 @@ compilation_unit { name: "Extension" } members { - interface_extends { + interface_extend { base { identifier { name: "Base" diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index a0e29830c725..9fa69fc8a2c9 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -2334,13 +2334,14 @@ auto Interpreter::StepDeclaration() -> ErrorOr { case DeclarationKind::ChoiceDeclaration: case DeclarationKind::InterfaceDeclaration: case DeclarationKind::ConstraintDeclaration: - case DeclarationKind::InterfaceExtendsDeclaration: - case DeclarationKind::InterfaceImplDeclaration: + case DeclarationKind::InterfaceExtendDeclaration: + case DeclarationKind::InterfaceRequireDeclaration: case DeclarationKind::AssociatedConstantDeclaration: case DeclarationKind::ImplDeclaration: case DeclarationKind::MatchFirstDeclaration: case DeclarationKind::SelfDeclaration: case DeclarationKind::AliasDeclaration: + case DeclarationKind::ExtendBaseDeclaration: // These declarations have no run-time effects. return todo_.FinishAction(); } diff --git a/explorer/interpreter/resolve_control_flow.cpp b/explorer/interpreter/resolve_control_flow.cpp index 3c5c5b38d915..894038ce5ce7 100644 --- a/explorer/interpreter/resolve_control_flow.cpp +++ b/explorer/interpreter/resolve_control_flow.cpp @@ -183,12 +183,13 @@ auto ResolveControlFlow(Nonnull declaration) -> ErrorOr { case DeclarationKind::NamespaceDeclaration: case DeclarationKind::ChoiceDeclaration: case DeclarationKind::VariableDeclaration: - case DeclarationKind::InterfaceExtendsDeclaration: - case DeclarationKind::InterfaceImplDeclaration: + case DeclarationKind::InterfaceExtendDeclaration: + case DeclarationKind::InterfaceRequireDeclaration: case DeclarationKind::AssociatedConstantDeclaration: case DeclarationKind::SelfDeclaration: case DeclarationKind::AliasDeclaration: case DeclarationKind::MixDeclaration: + case DeclarationKind::ExtendBaseDeclaration: // do nothing break; } diff --git a/explorer/interpreter/resolve_names.cpp b/explorer/interpreter/resolve_names.cpp index c62fce1fbd8a..b7b6d7b556a9 100644 --- a/explorer/interpreter/resolve_names.cpp +++ b/explorer/interpreter/resolve_names.cpp @@ -264,8 +264,9 @@ auto NameResolver::AddExposedNames(const Declaration& declaration, case DeclarationKind::ImplDeclaration: case DeclarationKind::MatchFirstDeclaration: case DeclarationKind::MixDeclaration: - case DeclarationKind::InterfaceExtendsDeclaration: - case DeclarationKind::InterfaceImplDeclaration: { + case DeclarationKind::InterfaceExtendDeclaration: + case DeclarationKind::InterfaceRequireDeclaration: + case DeclarationKind::ExtendBaseDeclaration: { // These declarations don't have a name to expose. break; } @@ -806,9 +807,6 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, ResolveQualifier(class_decl.name(), enclosing_scope)); StaticScope class_scope(scope); scope->MarkDeclared(class_decl.name().inner_name()); - if (auto base_expr = class_decl.base_expr()) { - CARBON_RETURN_IF_ERROR(ResolveNames(**base_expr, class_scope)); - } if (auto type_params = class_decl.type_params()) { CARBON_RETURN_IF_ERROR(ResolveNames(**type_params, class_scope)); } @@ -818,6 +816,12 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, ResolveMemberNames(class_decl.members(), class_scope, bodies)); break; } + case DeclarationKind::ExtendBaseDeclaration: { + auto& extend_base_decl = cast(declaration); + CARBON_RETURN_IF_ERROR( + ResolveNames(*extend_base_decl.base_class(), enclosing_scope)); + break; + } case DeclarationKind::MixinDeclaration: { auto& mixin_decl = cast(declaration); CARBON_ASSIGN_OR_RETURN( @@ -874,15 +878,17 @@ auto NameResolver::ResolveNamesImpl(Declaration& declaration, } break; } - case DeclarationKind::InterfaceExtendsDeclaration: { - auto& extends = cast(declaration); + case DeclarationKind::InterfaceExtendDeclaration: { + auto& extends = cast(declaration); CARBON_RETURN_IF_ERROR(ResolveNames(*extends.base(), enclosing_scope)); break; } - case DeclarationKind::InterfaceImplDeclaration: { - auto& impl = cast(declaration); - CARBON_RETURN_IF_ERROR(ResolveNames(*impl.impl_type(), enclosing_scope)); - CARBON_RETURN_IF_ERROR(ResolveNames(*impl.constraint(), enclosing_scope)); + case DeclarationKind::InterfaceRequireDeclaration: { + auto& require = cast(declaration); + CARBON_RETURN_IF_ERROR( + ResolveNames(*require.impl_type(), enclosing_scope)); + CARBON_RETURN_IF_ERROR( + ResolveNames(*require.constraint(), enclosing_scope)); break; } case DeclarationKind::AssociatedConstantDeclaration: { diff --git a/explorer/interpreter/resolve_unformed.cpp b/explorer/interpreter/resolve_unformed.cpp index 58610fd21001..35c69244eb5c 100644 --- a/explorer/interpreter/resolve_unformed.cpp +++ b/explorer/interpreter/resolve_unformed.cpp @@ -371,11 +371,12 @@ static auto ResolveUnformed(Nonnull declaration) case DeclarationKind::MatchFirstDeclaration: case DeclarationKind::ChoiceDeclaration: case DeclarationKind::VariableDeclaration: - case DeclarationKind::InterfaceExtendsDeclaration: - case DeclarationKind::InterfaceImplDeclaration: + case DeclarationKind::InterfaceExtendDeclaration: + case DeclarationKind::InterfaceRequireDeclaration: case DeclarationKind::AssociatedConstantDeclaration: case DeclarationKind::SelfDeclaration: case DeclarationKind::AliasDeclaration: + case DeclarationKind::ExtendBaseDeclaration: // do nothing break; case DeclarationKind::ClassDeclaration: diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index aaf10059e93d..5e06209a968d 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -5189,29 +5189,55 @@ auto TypeChecker::DeclareClassDeclaration(Nonnull class_decl, ImplScope class_scope(scope_info.innermost_scope); + // Find base class declaration, if any. Verify that is before any data member + // declarations, and there is at most one. std::optional> base_class; - if (class_decl->base_expr().has_value()) { - Nonnull base_class_expr = *class_decl->base_expr(); - CARBON_ASSIGN_OR_RETURN(const auto base_type, - TypeCheckTypeExp(base_class_expr, class_scope)); - if (base_type->kind() != Value::Kind::NominalClassType) { - return ProgramError(class_decl->source_loc()) - << "Unsupported base class type for class `" << class_decl->name() - << "`. Only simple classes are currently supported as base " - "class."; - } + bool after_data_member = false; + for (Nonnull m : class_decl->members()) { + switch (m->kind()) { + case DeclarationKind::VariableDeclaration: + case DeclarationKind::MixDeclaration: { + after_data_member = true; + break; + } + case DeclarationKind::ExtendBaseDeclaration: { + if (after_data_member) { + return ProgramError(m->source_loc()) + << "`extend base:` declaration must not be after `var` or " + "`mix` declarations in a class."; + } + if (base_class.has_value()) { + return ProgramError(m->source_loc()) + << "At most one `extend base:` declaration in a class."; + } + Nonnull base_class_expr = + cast(*m).base_class(); + CARBON_ASSIGN_OR_RETURN(const auto base_type, + TypeCheckTypeExp(base_class_expr, class_scope)); + if (base_type->kind() != Value::Kind::NominalClassType) { + return ProgramError(m->source_loc()) + << "Unsupported base class type for class `" + << class_decl->name() + << "`. Only simple classes are currently supported as base " + "class."; + } - base_class = cast(base_type); - if (base_class.value()->declaration().extensibility() == - ClassExtensibility::None) { - return ProgramError(class_decl->source_loc()) - << "Base class `" << base_class.value()->declaration().name() - << "` is `final` and cannot be inherited. Add the `base` or " - "`abstract` class prefix to `" - << base_class.value()->declaration().name() - << "` to allow it to be inherited"; + base_class = cast(base_type); + if (base_class.value()->declaration().extensibility() == + ClassExtensibility::None) { + return ProgramError(m->source_loc()) + << "Base class `" << base_class.value()->declaration().name() + << "` is `final` and cannot be inherited. Add the `base` or " + "`abstract` class prefix to `" + << base_class.value()->declaration().name() + << "` to allow it to be inherited"; + } + class_decl->set_base_type(base_class); + break; + } + default: + break; } - class_decl->set_base_type(base_class); } std::vector> bindings = scope_info.bindings; @@ -5592,16 +5618,16 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( // TODO: This should probably live in `DeclareDeclaration`, but it needs // to update state that's not available from there. switch (m->kind()) { - case DeclarationKind::InterfaceExtendsDeclaration: { - // For an `extends C;` declaration, add `Self impls C` to our + case DeclarationKind::InterfaceExtendDeclaration: { + // For an `extend C;` declaration, add `Self impls C` to our // constraint. - auto* extends = cast(m); + auto* extend = cast(m); CARBON_ASSIGN_OR_RETURN( Nonnull base, - TypeCheckTypeExp(extends->base(), constraint_scope)); + TypeCheckTypeExp(extend->base(), constraint_scope)); CARBON_ASSIGN_OR_RETURN( Nonnull constraint_type, - ConvertToConstraintType(m->source_loc(), "extends declaration", + ConvertToConstraintType(m->source_loc(), "extend declaration", base)); CARBON_RETURN_IF_ERROR(builder.AddAndSubstitute( *this, constraint_type, builder.GetSelfType(), @@ -5610,18 +5636,19 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( break; } - case DeclarationKind::InterfaceImplDeclaration: { - // For an `impl X as Y;` declaration, add `X impls Y` to our constraint. - auto* impl = cast(m); + case DeclarationKind::InterfaceRequireDeclaration: { + // For an `require X impls Y;` declaration, add `X impls Y` to our + // constraint. + auto* require = cast(m); CARBON_ASSIGN_OR_RETURN( Nonnull impl_type, - TypeCheckTypeExp(impl->impl_type(), constraint_scope)); + TypeCheckTypeExp(require->impl_type(), constraint_scope)); CARBON_ASSIGN_OR_RETURN( Nonnull constraint, - TypeCheckTypeExp(impl->constraint(), constraint_scope)); + TypeCheckTypeExp(require->constraint(), constraint_scope)); CARBON_ASSIGN_OR_RETURN( Nonnull constraint_type, - ConvertToConstraintType(m->source_loc(), "impl as declaration", + ConvertToConstraintType(m->source_loc(), "require declaration", constraint)); CARBON_RETURN_IF_ERROR( builder.AddAndSubstitute(*this, constraint_type, impl_type, @@ -5762,7 +5789,8 @@ auto TypeChecker::CheckImplIsComplete(Nonnull iface_type, << "implementation doesn't provide a concrete value for " << *iface_type << "." << assoc->binding().name(); } - } else if (isa(m)) { + } else if (isa( + m)) { // These get translated into constraints so there's nothing we need to // check here. } else { @@ -6310,8 +6338,8 @@ auto TypeChecker::TypeCheckDeclaration( } break; } - case DeclarationKind::InterfaceExtendsDeclaration: - case DeclarationKind::InterfaceImplDeclaration: + case DeclarationKind::InterfaceExtendDeclaration: + case DeclarationKind::InterfaceRequireDeclaration: case DeclarationKind::AssociatedConstantDeclaration: { // Checked in DeclareConstraintTypeDeclaration. break; @@ -6322,6 +6350,10 @@ auto TypeChecker::TypeCheckDeclaration( case DeclarationKind::AliasDeclaration: { break; } + case DeclarationKind::ExtendBaseDeclaration: { + // Checked in TypeCheckClassDeclaration. + break; + } } d->set_is_type_checked(); return Success(); @@ -6373,6 +6405,10 @@ auto TypeChecker::DeclareDeclaration(Nonnull d, CARBON_RETURN_IF_ERROR(DeclareClassDeclaration(&class_decl, scope_info)); break; } + case DeclarationKind::ExtendBaseDeclaration: { + // Handled in DeclareClassDeclaration. + break; + } case DeclarationKind::MixinDeclaration: { auto& mixin_decl = cast(*d); CARBON_RETURN_IF_ERROR(DeclareMixinDeclaration(&mixin_decl, scope_info)); @@ -6423,8 +6459,8 @@ auto TypeChecker::DeclareDeclaration(Nonnull d, break; } - case DeclarationKind::InterfaceExtendsDeclaration: - case DeclarationKind::InterfaceImplDeclaration: + case DeclarationKind::InterfaceExtendDeclaration: + case DeclarationKind::InterfaceRequireDeclaration: case DeclarationKind::AssociatedConstantDeclaration: { // The semantic effects are handled by DeclareConstraintTypeDeclaration. break; diff --git a/explorer/syntax/lexer.lpp b/explorer/syntax/lexer.lpp index 41449072cfc6..f608f8e0b99b 100644 --- a/explorer/syntax/lexer.lpp +++ b/explorer/syntax/lexer.lpp @@ -60,8 +60,7 @@ DOUBLE_ARROW "=>" ELSE "else" EQUAL "=" EQUAL_EQUAL "==" -EXTENDS "extends" -EXTERNAL "external" +EXTEND "extend" FALSE "false" FN "fn" FN_TYPE "__Fn" @@ -106,6 +105,7 @@ PIPE_EQUAL "|=" PLUS "+" PLUS_EQUAL "+=" PLUS_PLUS "++" +REQUIRE "require" RETURN "return" RETURNED "returned" RIGHT_CURLY_BRACE "}" @@ -179,8 +179,7 @@ operand_start [(A-Za-z0-9_\"] {ELSE} { return CARBON_SIMPLE_TOKEN(ELSE); } {EQUAL_EQUAL} { return CARBON_SIMPLE_TOKEN(EQUAL_EQUAL); } {EQUAL} { return CARBON_SIMPLE_TOKEN(EQUAL); } -{EXTENDS} { return CARBON_SIMPLE_TOKEN(EXTENDS); } -{EXTERNAL} { return CARBON_SIMPLE_TOKEN(EXTERNAL); } +{EXTEND} { return CARBON_SIMPLE_TOKEN(EXTEND); } {FALSE} { return CARBON_SIMPLE_TOKEN(FALSE); } {FN_TYPE} { return CARBON_SIMPLE_TOKEN(FN_TYPE); } {FN} { return CARBON_SIMPLE_TOKEN(FN); } @@ -225,6 +224,7 @@ operand_start [(A-Za-z0-9_\"] {PLUS_EQUAL} { return CARBON_SIMPLE_TOKEN(PLUS_EQUAL); } {PLUS_PLUS} { return CARBON_SIMPLE_TOKEN(PLUS_PLUS); } {PLUS} { return CARBON_SIMPLE_TOKEN(PLUS); } +{REQUIRE} { return CARBON_SIMPLE_TOKEN(REQUIRE); } {RETURNED} { return CARBON_SIMPLE_TOKEN(RETURNED); } {RETURN} { return CARBON_SIMPLE_TOKEN(RETURN); } {SELF} { return CARBON_SIMPLE_TOKEN(SELF); } diff --git a/explorer/syntax/parser.ypp b/explorer/syntax/parser.ypp index ea115208f7ab..834ba6117eda 100644 --- a/explorer/syntax/parser.ypp +++ b/explorer/syntax/parser.ypp @@ -97,8 +97,8 @@ %token sized_type_literal %token string_literal %type designator -%type impl_kind_intro %type > impl_type +%type > no_impl_type %type > package_directive %type import_directive %type > import_directives @@ -107,14 +107,15 @@ %type fn_virtual_override_intro %type destructor_virtual_override_intro %type class_declaration_extensibility -%type >> class_declaration_extends %type > declaration %type > declared_name %type > function_declaration %type > destructor_declaration +%type > extend_base_declaration %type > mix_declaration %type > alias_declaration %type > impl_declaration +%type > extend_impl_declaration %type > match_first_declaration %type >> match_first_declaration_list %type >> declaration_list @@ -236,8 +237,7 @@ ELSE EQUAL EQUAL_EQUAL - EXTENDS - EXTERNAL + EXTEND FALSE FN FN_TYPE @@ -283,6 +283,7 @@ PLUS PLUS_EQUAL PLUS_PLUS + REQUIRE RETURN RETURNED RIGHT_CURLY_BRACE @@ -1390,12 +1391,6 @@ class_declaration_extensibility: | BASE { $$ = Carbon::ClassExtensibility::Base; } ; -class_declaration_extends: - // Empty - { $$ = std::nullopt; } -| EXTENDS expression - { $$ = $[expression]; } -; declaration: NAMESPACE declared_name SEMICOLON { @@ -1407,13 +1402,12 @@ declaration: | destructor_declaration { $$ = $[destructor_declaration]; } | class_declaration_extensibility CLASS declared_name type_params - class_declaration_extends LEFT_CURLY_BRACE class_body RIGHT_CURLY_BRACE + LEFT_CURLY_BRACE class_body RIGHT_CURLY_BRACE { $$ = arena->New( context.source_loc(), std::move($[declared_name]), arena->New(context.source_loc()), - $[class_declaration_extensibility], $[type_params], - $[class_declaration_extends], $[class_body]); + $[class_declaration_extensibility], $[type_params], $[class_body]); } | MIXIN declared_name type_params mixin_import LEFT_CURLY_BRACE mixin_body RIGHT_CURLY_BRACE @@ -1472,12 +1466,28 @@ declaration: { $$ = $[alias_declaration]; } ; impl_declaration: - impl_kind_intro impl_deduced_params impl_type AS type_or_where_expression + IMPL impl_deduced_params impl_type AS type_or_where_expression LEFT_CURLY_BRACE impl_body RIGHT_CURLY_BRACE { ErrorOr impl = ImplDeclaration::Create( - arena, context.source_loc(), $[impl_kind_intro], $[impl_type], - $[type_or_where_expression], $[impl_deduced_params], $[impl_body]); + arena, context.source_loc(), Carbon::ImplKind::ExternalImpl, + $[impl_type], $[type_or_where_expression], $[impl_deduced_params], + $[impl_body]); + if (impl.ok()) { + $$ = *impl; + } else { + context.RecordSyntaxError(std::move(impl).error()); + YYERROR; + } + } +; +extend_impl_declaration: + EXTEND IMPL no_impl_type AS type_or_where_expression + LEFT_CURLY_BRACE impl_body RIGHT_CURLY_BRACE + { + ErrorOr impl = ImplDeclaration::Create( + arena, context.source_loc(), Carbon::ImplKind::InternalImpl, + $[no_impl_type], $[type_or_where_expression], {}, $[impl_body]); if (impl.ok()) { $$ = *impl; } else { @@ -1485,17 +1495,15 @@ impl_declaration: YYERROR; } } -impl_kind_intro: - IMPL // Internal - { $$ = Carbon::ImplKind::InternalImpl; } -| EXTERNAL IMPL - { $$ = Carbon::ImplKind::ExternalImpl; } ; impl_type: // Self { $$ = arena->New(context.source_loc(), "Self"); } | type_expression ; +no_impl_type: + { $$ = arena->New(context.source_loc(), "Self"); } +; match_first_declaration: MATCH_FIRST LEFT_CURLY_BRACE match_first_declaration_list RIGHT_CURLY_BRACE { @@ -1547,6 +1555,13 @@ declaration_list: $$.push_back(Nonnull($[declaration])); } ; +extend_base_declaration: + EXTEND BASE COLON expression SEMICOLON + { + $$ = arena->New(context.source_loc(), + $[expression]); + } +; class_body: // Empty { $$ = {}; } @@ -1560,6 +1575,16 @@ class_body: $$ = std::move($[accumulated_class_body]); $$.push_back(Nonnull($[mix_declaration])); } +| class_body[accumulated_class_body] extend_base_declaration + { + $$ = std::move($[accumulated_class_body]); + $$.push_back(Nonnull($[extend_base_declaration])); + } +| class_body[accumulated_class_body] extend_impl_declaration + { + $$ = std::move($[accumulated_class_body]); + $$.push_back(Nonnull($[extend_impl_declaration])); + } ; // EXPERIMENTAL MIXIN FEATURE mixin_body: @@ -1590,18 +1615,19 @@ interface_body: $$.push_back(arena->New( context.source_loc(), $[generic_binding])); } -| interface_body[accumulated_interface_body] EXTENDS expression SEMICOLON +| interface_body[accumulated_interface_body] EXTEND expression SEMICOLON { $$ = std::move($[accumulated_interface_body]); - $$.push_back(arena->New(context.source_loc(), - $[expression])); + $$.push_back(arena->New(context.source_loc(), + $[expression])); } -| interface_body[accumulated_interface_body] IMPL impl_type AS +| interface_body[accumulated_interface_body] REQUIRE type_expression IMPLS type_or_where_expression SEMICOLON { $$ = std::move($[accumulated_interface_body]); - $$.push_back(arena->New( - context.source_loc(), $[impl_type], $[type_or_where_expression])); + $$.push_back(arena->New( + context.source_loc(), $[type_expression], + $[type_or_where_expression])); } ; impl_body: diff --git a/explorer/testdata/alias/member_name_alias.carbon b/explorer/testdata/alias/member_name_alias.carbon index c663fc809f11..9cdc1992b14e 100644 --- a/explorer/testdata/alias/member_name_alias.carbon +++ b/explorer/testdata/alias/member_name_alias.carbon @@ -13,7 +13,7 @@ interface I { } class A { var n: i32; - impl as I { + extend impl as I { fn F() -> i32 { return 1; } fn M[self: Self]() -> i32 { return 2; } } diff --git a/explorer/testdata/array/element_convertible_to_type.carbon b/explorer/testdata/array/element_convertible_to_type.carbon index ef6978a5c0ea..081f3c5e625b 100644 --- a/explorer/testdata/array/element_convertible_to_type.carbon +++ b/explorer/testdata/array/element_convertible_to_type.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class TypeLike { - impl as ImplicitAs(type) { + extend impl as ImplicitAs(type) { fn Convert[self: Self]() -> type { return i32; } } fn Make() -> Self { return {}; } diff --git a/explorer/testdata/as/convert.carbon b/explorer/testdata/as/convert.carbon index 56b964878c0f..41ccd43e10af 100644 --- a/explorer/testdata/as/convert.carbon +++ b/explorer/testdata/as/convert.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as As(i32) { +impl A as As(i32) { fn Convert[self: Self]() -> i32 { return self.n; } } diff --git a/explorer/testdata/as/implicit_as.carbon b/explorer/testdata/as/implicit_as.carbon index bc11667ec264..5967d6f82ae0 100644 --- a/explorer/testdata/as/implicit_as.carbon +++ b/explorer/testdata/as/implicit_as.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as ImplicitAs(i32) { +impl A as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return self.n; } } diff --git a/explorer/testdata/assert/convert.carbon b/explorer/testdata/assert/convert.carbon index eb22f4789f41..1791f7a3e30c 100644 --- a/explorer/testdata/assert/convert.carbon +++ b/explorer/testdata/assert/convert.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class ConvertTo(T:! type) { var v: T; - impl as ImplicitAs(T) { + extend impl as ImplicitAs(T) { fn Convert[self: Self]() -> T { return self.v; } } } diff --git a/explorer/testdata/assert/fail_convert.carbon b/explorer/testdata/assert/fail_convert.carbon index 548b1742e8c6..14850834eb79 100644 --- a/explorer/testdata/assert/fail_convert.carbon +++ b/explorer/testdata/assert/fail_convert.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class ConvertTo(T:! type) { var v: T; - impl as ImplicitAs(T) { + extend impl as ImplicitAs(T) { fn Convert[self: Self]() -> T { return self.v; } } } diff --git a/explorer/testdata/assert/fail_intrinsic_bool_type.carbon b/explorer/testdata/assert/fail_intrinsic_bool_type.carbon index dfcc36ffc7e6..6f4a8b44da30 100644 --- a/explorer/testdata/assert/fail_intrinsic_bool_type.carbon +++ b/explorer/testdata/assert/fail_intrinsic_bool_type.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class ConvertTo(T:! type) { var v: T; - impl as ImplicitAs(T) { + extend impl as ImplicitAs(T) { fn Convert[self: Self]() -> T { return self.v; } } } diff --git a/explorer/testdata/assert/fail_intrinsic_no_args.carbon b/explorer/testdata/assert/fail_intrinsic_no_args.carbon index a6137a075aaf..9412b3502968 100644 --- a/explorer/testdata/assert/fail_intrinsic_no_args.carbon +++ b/explorer/testdata/assert/fail_intrinsic_no_args.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class ConvertTo(T:! type) { var v: T; - impl as ImplicitAs(T) { + extend impl as ImplicitAs(T) { fn Convert[self: Self]() -> T { return self.v; } } } diff --git a/explorer/testdata/assert/fail_intrinsic_no_convert.carbon b/explorer/testdata/assert/fail_intrinsic_no_convert.carbon index 31085af553fd..717fd816a49f 100644 --- a/explorer/testdata/assert/fail_intrinsic_no_convert.carbon +++ b/explorer/testdata/assert/fail_intrinsic_no_convert.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class ConvertTo(T:! type) { var v: T; - impl as ImplicitAs(T) { + extend impl as ImplicitAs(T) { fn Convert[self: Self]() -> T { return self.v; } } } diff --git a/explorer/testdata/assert/fail_intrinsic_str_type.carbon b/explorer/testdata/assert/fail_intrinsic_str_type.carbon index 3c2a025e5680..6b7f7d9de0ec 100644 --- a/explorer/testdata/assert/fail_intrinsic_str_type.carbon +++ b/explorer/testdata/assert/fail_intrinsic_str_type.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class ConvertTo(T:! type) { var v: T; - impl as ImplicitAs(T) { + extend impl as ImplicitAs(T) { fn Convert[self: Self]() -> T { return self.v; } } } diff --git a/explorer/testdata/assoc_const/bug_multi_impl_scoping.carbon b/explorer/testdata/assoc_const/bug_multi_impl_scoping.carbon index 1748f28a08fb..79e4866f3346 100644 --- a/explorer/testdata/assoc_const/bug_multi_impl_scoping.carbon +++ b/explorer/testdata/assoc_const/bug_multi_impl_scoping.carbon @@ -24,7 +24,7 @@ interface B { } class C(T:! type) { - impl as A & B where .TA = i32 and .TB = i32 { + extend impl as A & B where .TA = i32 and .TB = i32 { fn FA() -> i32 { Print("(C(T) as A).FA()"); // OK, know that TA is i32 here. @@ -44,7 +44,7 @@ class C(T:! type) { } } -external impl C(i32) as A where .TA = (i32, i32) { +impl C(i32) as A where .TA = (i32, i32) { fn FA() -> (i32, i32) { Print("(C(i32) as A).FA()"); return (6, 7); diff --git a/explorer/testdata/assoc_const/fail_different_type.carbon b/explorer/testdata/assoc_const/fail_different_type.carbon index 631b443d3c05..7435a39c8309 100644 --- a/explorer/testdata/assoc_const/fail_different_type.carbon +++ b/explorer/testdata/assoc_const/fail_different_type.carbon @@ -14,8 +14,8 @@ fn F(T:! Iface where .T == i32) {} class Good {} class Bad {} -external impl Good as Iface where .T = i32 {} -external impl Bad as Iface where .T = Bad {} +impl Good as Iface where .T = i32 {} +impl Bad as Iface where .T = Bad {} fn Main() -> i32 { F(Good); diff --git a/explorer/testdata/assoc_const/fail_different_value.carbon b/explorer/testdata/assoc_const/fail_different_value.carbon index 7474596f9808..55917600e6a0 100644 --- a/explorer/testdata/assoc_const/fail_different_value.carbon +++ b/explorer/testdata/assoc_const/fail_different_value.carbon @@ -14,8 +14,8 @@ fn F(T:! Iface where .N == 5) {} class Good {} class Bad {} -external impl Good as Iface where .N = 5 {} -external impl Bad as Iface where .N = 4 {} +impl Good as Iface where .N = 5 {} +impl Bad as Iface where .N = 4 {} fn Main() -> i32 { F(Good); diff --git a/explorer/testdata/assoc_const/fail_equal_indirectly.carbon b/explorer/testdata/assoc_const/fail_equal_indirectly.carbon index 641f34bb8e5a..5fa65e9a1d20 100644 --- a/explorer/testdata/assoc_const/fail_equal_indirectly.carbon +++ b/explorer/testdata/assoc_const/fail_equal_indirectly.carbon @@ -13,7 +13,7 @@ interface Iface { fn F[T:! Iface where .T == i32](x: T) {} class Class { - impl as Iface where .T = i32 {} + extend impl as Iface where .T = i32 {} } // OK, constraint on `F` rewritten to `T:! Iface where U == i32`, which we can diff --git a/explorer/testdata/assoc_const/fail_equal_to_dependent_type.carbon b/explorer/testdata/assoc_const/fail_equal_to_dependent_type.carbon index adfc001ef1a5..49262ef0b7a3 100644 --- a/explorer/testdata/assoc_const/fail_equal_to_dependent_type.carbon +++ b/explorer/testdata/assoc_const/fail_equal_to_dependent_type.carbon @@ -22,7 +22,7 @@ fn H[V:! Iface](x: V) { } class Class { - impl as Iface where .T = i32 {} + extend impl as Iface where .T = i32 {} } fn Main() -> i32 { diff --git a/explorer/testdata/assoc_const/fail_incomplete_impl_1.carbon b/explorer/testdata/assoc_const/fail_incomplete_impl_1.carbon index ee0df8a3d57a..6fc78cae51f8 100644 --- a/explorer/testdata/assoc_const/fail_incomplete_impl_1.carbon +++ b/explorer/testdata/assoc_const/fail_incomplete_impl_1.carbon @@ -13,6 +13,6 @@ interface HasThreeTypes { } // CHECK:STDERR: COMPILATION ERROR: fail_incomplete_impl_1.carbon:[[@LINE+1]]: implementation doesn't provide a concrete value for interface HasThreeTypes.B -external impl i32 as HasThreeTypes where .A = i32 and .C = i32 {} +impl i32 as HasThreeTypes where .A = i32 and .C = i32 {} fn Main() -> i32 { return 0; } diff --git a/explorer/testdata/assoc_const/fail_incomplete_impl_2.carbon b/explorer/testdata/assoc_const/fail_incomplete_impl_2.carbon index 8b706d4874c1..c28e620b92a0 100644 --- a/explorer/testdata/assoc_const/fail_incomplete_impl_2.carbon +++ b/explorer/testdata/assoc_const/fail_incomplete_impl_2.carbon @@ -13,6 +13,6 @@ interface HasThreeTypes { } // CHECK:STDERR: COMPILATION ERROR: fail_incomplete_impl_2.carbon:[[@LINE+1]]: implementation doesn't provide a concrete value for interface HasThreeTypes.C -external impl i32 as HasThreeTypes where .A = i32 and .B = .C {} +impl i32 as HasThreeTypes where .A = i32 and .B = .C {} fn Main() -> i32 { return 0; } diff --git a/explorer/testdata/assoc_const/fail_indirectly_equal.carbon b/explorer/testdata/assoc_const/fail_indirectly_equal.carbon index 03db84b0f18b..89f343d92fb1 100644 --- a/explorer/testdata/assoc_const/fail_indirectly_equal.carbon +++ b/explorer/testdata/assoc_const/fail_indirectly_equal.carbon @@ -25,7 +25,7 @@ fn F3[T:! A where .T == i32, U:! A where .T == i32](x: T.T) -> U.T { return x; } -external impl i32 as A where .T == i32 {} +impl i32 as A where .T == i32 {} fn Main() -> i32 { return F3(0); diff --git a/explorer/testdata/assoc_const/fail_match_in_deduction.carbon b/explorer/testdata/assoc_const/fail_match_in_deduction.carbon index 5d8262dd97df..1e96daef965f 100644 --- a/explorer/testdata/assoc_const/fail_match_in_deduction.carbon +++ b/explorer/testdata/assoc_const/fail_match_in_deduction.carbon @@ -11,7 +11,7 @@ package ExplorerTest api; interface Vector { let Dim:! i32; } -external impl (i32, i32, i32) as Vector where .Dim = 3 {} +impl (i32, i32, i32) as Vector where .Dim = 3 {} class Point(Scalar:! type, Dim:! i32) {} diff --git a/explorer/testdata/assoc_const/fail_overspecified_impl.carbon b/explorer/testdata/assoc_const/fail_overspecified_impl.carbon index 50593515bf53..eeb9118028b8 100644 --- a/explorer/testdata/assoc_const/fail_overspecified_impl.carbon +++ b/explorer/testdata/assoc_const/fail_overspecified_impl.carbon @@ -13,6 +13,6 @@ interface HasType { // CHECK:STDERR: COMPILATION ERROR: fail_overspecified_impl.carbon:[[@LINE+3]]: multiple different rewrites for `(i32).(HasType.T)`: // CHECK:STDERR: i32 // CHECK:STDERR: {.a: i32} -external impl i32 as HasType where .T = i32 and .T = {.a: i32} {} +impl i32 as HasType where .T = i32 and .T = {.a: i32} {} fn Main() -> i32 { return 0; } diff --git a/explorer/testdata/assoc_const/impl_lookup.carbon b/explorer/testdata/assoc_const/impl_lookup.carbon index dc23518f77a7..9dc26a34487c 100644 --- a/explorer/testdata/assoc_const/impl_lookup.carbon +++ b/explorer/testdata/assoc_const/impl_lookup.carbon @@ -19,7 +19,7 @@ fn Use[T:! Frob](x: T) -> T.Result { class AlmostI32 { var val: i32; - impl as ImplicitAs(i32) { + extend impl as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return self.val; } } } diff --git a/explorer/testdata/assoc_const/implement.carbon b/explorer/testdata/assoc_const/implement.carbon index 06aabc8eb6ea..984ded1576a5 100644 --- a/explorer/testdata/assoc_const/implement.carbon +++ b/explorer/testdata/assoc_const/implement.carbon @@ -14,7 +14,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl as Vector where .Dim = 2 {} + extend impl as Vector where .Dim = 2 {} } fn Main() -> i32 { diff --git a/explorer/testdata/assoc_const/lookup_in_rewrite.carbon b/explorer/testdata/assoc_const/lookup_in_rewrite.carbon index 283e402773fc..1427147e60e0 100644 --- a/explorer/testdata/assoc_const/lookup_in_rewrite.carbon +++ b/explorer/testdata/assoc_const/lookup_in_rewrite.carbon @@ -21,7 +21,7 @@ interface Hashable { } class Potato { - external impl as Hashable { + impl as Hashable { fn Hash[self: Self]() -> i32 { Print("Potato.(Hashable.Hash)"); return 1; @@ -39,7 +39,7 @@ interface Maker { fn Make() -> Result; } -external impl i32 as Hashable { +impl i32 as Hashable { fn Hash[self: Self]() -> i32 { Print("i32.Hash"); return self; @@ -69,13 +69,13 @@ fn I[T:! Maker where .Result = Potato](x: T) -> i32 { } class IntFactory { - impl as Maker where .Result = i32 { + extend impl as Maker where .Result = i32 { fn Make() -> i32 { return 0; } } } class PotatoFactory { - impl as Maker where .Result = Potato { + extend impl as Maker where .Result = Potato { fn Make() -> Potato { return {}; } } } diff --git a/explorer/testdata/assoc_const/member_of_value.carbon b/explorer/testdata/assoc_const/member_of_value.carbon index 18730b39c511..599c8ab5897b 100644 --- a/explorer/testdata/assoc_const/member_of_value.carbon +++ b/explorer/testdata/assoc_const/member_of_value.carbon @@ -14,7 +14,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl as Vector where .Dim = 2 {} + extend impl as Vector where .Dim = 2 {} } fn Main() -> i32 { diff --git a/explorer/testdata/assoc_const/pass_equal_to_rewrite.carbon b/explorer/testdata/assoc_const/pass_equal_to_rewrite.carbon index d51e02fe33e2..a3394aff2b8e 100644 --- a/explorer/testdata/assoc_const/pass_equal_to_rewrite.carbon +++ b/explorer/testdata/assoc_const/pass_equal_to_rewrite.carbon @@ -20,7 +20,7 @@ fn B[T:! Container where .Element == i32](x: T) -> T.Element { return A(x); } -external impl (i32, i32) as Container where .Element = i32 { +impl (i32, i32) as Container where .Element = i32 { fn Front[self: Self]() -> i32 { let (a: i32, b: i32) = self; return a; diff --git a/explorer/testdata/assoc_const/pass_rewrite_to_equal.carbon b/explorer/testdata/assoc_const/pass_rewrite_to_equal.carbon index f7d46dc6d9d1..5696bd52b76e 100644 --- a/explorer/testdata/assoc_const/pass_rewrite_to_equal.carbon +++ b/explorer/testdata/assoc_const/pass_rewrite_to_equal.carbon @@ -20,7 +20,7 @@ fn B[T:! Container where .Element = i32](x: T) -> T.Element { return A(x); } -external impl (i32, i32) as Container where .Element = i32 { +impl (i32, i32) as Container where .Element = i32 { fn Front[self: Self]() -> i32 { let (a: i32, b: i32) = self; return a; diff --git a/explorer/testdata/assoc_const/resolve_rewrites.carbon b/explorer/testdata/assoc_const/resolve_rewrites.carbon index 3dfdacd031af..eaf509fd912d 100644 --- a/explorer/testdata/assoc_const/resolve_rewrites.carbon +++ b/explorer/testdata/assoc_const/resolve_rewrites.carbon @@ -37,7 +37,7 @@ fn F[ } class C { - impl as ManyTypes where + extend impl as ManyTypes where .T0 = i32 and .T1 = .T0 and .T2 = .T1 and diff --git a/explorer/testdata/assoc_const/rewrite_large_type.carbon b/explorer/testdata/assoc_const/rewrite_large_type.carbon index 65e968ec0bf6..bf57d096226b 100644 --- a/explorer/testdata/assoc_const/rewrite_large_type.carbon +++ b/explorer/testdata/assoc_const/rewrite_large_type.carbon @@ -72,7 +72,7 @@ fn DoFirst( } class C { - impl as ManyTypes where + extend impl as ManyTypes where .T3 = (.T4, .T4, .T4) and .T1 = (.T2, .T2, .T2) and .T4 = (.T5, .T5, .T5) and diff --git a/explorer/testdata/class/abstract_class.carbon b/explorer/testdata/class/abstract_class.carbon index 08dbb93df81f..d69f559aa0e3 100644 --- a/explorer/testdata/class/abstract_class.carbon +++ b/explorer/testdata/class/abstract_class.carbon @@ -13,7 +13,8 @@ abstract class C { var a: i32; } -class D extends C { +class D { + extend base: C; var b: i32; } diff --git a/explorer/testdata/class/base_constructor.carbon b/explorer/testdata/class/base_constructor.carbon index fec9601abf06..5d6cd5b1688b 100644 --- a/explorer/testdata/class/base_constructor.carbon +++ b/explorer/testdata/class/base_constructor.carbon @@ -16,7 +16,8 @@ base class A { var value_a: i32; } -class B extends A { +class B { + extend base: A; fn Create() -> Self { return {.base = A.Create(), .value_b = 2}; } diff --git a/explorer/testdata/class/class_inheritance_function_call.carbon b/explorer/testdata/class/class_inheritance_function_call.carbon index 2ff05f69f707..acaab676a159 100644 --- a/explorer/testdata/class/class_inheritance_function_call.carbon +++ b/explorer/testdata/class/class_inheritance_function_call.carbon @@ -18,7 +18,8 @@ base class C { } } -class D extends C { +class D { + extend base: C; fn FunctionD(var i: i32) { C.FunctionC(i); Print("Class D, call {0}", i); diff --git a/explorer/testdata/class/class_inheritance_methods.carbon b/explorer/testdata/class/class_inheritance_methods.carbon index 9eaa895cdafc..a949a82d457d 100644 --- a/explorer/testdata/class/class_inheritance_methods.carbon +++ b/explorer/testdata/class/class_inheritance_methods.carbon @@ -20,7 +20,8 @@ base class C { var value_c: i32; } -class D extends C { +class D { + extend base: C; fn Method2[self: Self]() { self.BasePrint(self.value_d); } diff --git a/explorer/testdata/class/class_inheritance_multiple.carbon b/explorer/testdata/class/class_inheritance_multiple.carbon index 6f994c9f6a3f..c2248734ce4c 100644 --- a/explorer/testdata/class/class_inheritance_multiple.carbon +++ b/explorer/testdata/class/class_inheritance_multiple.carbon @@ -17,12 +17,14 @@ base class A { var aa: String; } -base class B extends A { +base class B { + extend base: A; fn FunctionB() {} var b: i32; } -class C extends B { +class C { + extend base: B; fn FunctionC() {} var c: i32; } diff --git a/explorer/testdata/class/class_inheritance_shadow.carbon b/explorer/testdata/class/class_inheritance_shadow.carbon index d8934c38058c..a25e20ee206c 100644 --- a/explorer/testdata/class/class_inheritance_shadow.carbon +++ b/explorer/testdata/class/class_inheritance_shadow.carbon @@ -20,7 +20,8 @@ base class C { var value: i32; } -class D extends C { +class D { + extend base: C; fn Method1() { Print("Class D"); } diff --git a/explorer/testdata/class/class_inheritance_variables.carbon b/explorer/testdata/class/class_inheritance_variables.carbon index d742639f1ac8..c9e3f83feabe 100644 --- a/explorer/testdata/class/class_inheritance_variables.carbon +++ b/explorer/testdata/class/class_inheritance_variables.carbon @@ -15,7 +15,8 @@ base class C { var var_c: i32; } -class D extends C { +class D { + extend base: C; var var_d: i32; } diff --git a/explorer/testdata/class/class_subtyping_argument.carbon b/explorer/testdata/class/class_subtyping_argument.carbon index 799df00957aa..1fa446a9f608 100644 --- a/explorer/testdata/class/class_subtyping_argument.carbon +++ b/explorer/testdata/class/class_subtyping_argument.carbon @@ -15,11 +15,13 @@ base class C { var val: i32; } -base class D extends C { +base class D { + extend base: C; var val: i32; } -class E extends D { +class E { + extend base: D; var val: i32; } diff --git a/explorer/testdata/class/class_subtyping_basic.carbon b/explorer/testdata/class/class_subtyping_basic.carbon index 3b0abcde1d6f..c65e1bfc11ad 100644 --- a/explorer/testdata/class/class_subtyping_basic.carbon +++ b/explorer/testdata/class/class_subtyping_basic.carbon @@ -13,7 +13,8 @@ base class C { var a: i32; } -class D extends C { +class D { + extend base: C; } fn Foo(c: C*) -> i32 { diff --git a/explorer/testdata/class/class_subtyping_multiple.carbon b/explorer/testdata/class/class_subtyping_multiple.carbon index 1d35fbfbd89d..46a22fb578f3 100644 --- a/explorer/testdata/class/class_subtyping_multiple.carbon +++ b/explorer/testdata/class/class_subtyping_multiple.carbon @@ -15,11 +15,13 @@ base class C { var val: i32; } -base class D extends C { +base class D { + extend base: C; var val: i32; } -class E extends D { +class E { + extend base: D; var val: i32; } diff --git a/explorer/testdata/class/fail_abstract_method_not_supported.carbon b/explorer/testdata/class/fail_abstract_method_not_supported.carbon index 824d3ef87aa9..10f1468b9377 100644 --- a/explorer/testdata/class/fail_abstract_method_not_supported.carbon +++ b/explorer/testdata/class/fail_abstract_method_not_supported.carbon @@ -9,7 +9,8 @@ package ExplorerTest api; base class C { } -class D extends C { +class D { + extend base: C; abstract fn Foo[self:Self]() -> i32 { return 1; // CHECK:STDERR: COMPILATION ERROR: fail_abstract_method_not_supported.carbon:[[@LINE+1]]: Error declaring `Foo`: `abstract` methods are not yet supported. diff --git a/explorer/testdata/class/fail_direct_base_class_init.carbon b/explorer/testdata/class/fail_direct_base_class_init.carbon index 67c898a77f0d..599ba361527e 100644 --- a/explorer/testdata/class/fail_direct_base_class_init.carbon +++ b/explorer/testdata/class/fail_direct_base_class_init.carbon @@ -10,7 +10,8 @@ base class A { var a: i32; } -class B extends A { +class B { + extend base: A; var b: i32; } diff --git a/explorer/testdata/class/fail_extend_after_var.carbon b/explorer/testdata/class/fail_extend_after_var.carbon new file mode 100644 index 000000000000..db4a31cd67b3 --- /dev/null +++ b/explorer/testdata/class/fail_extend_after_var.carbon @@ -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 +// +// AUTOUPDATE + +package ExplorerTest api; + +base class C { +} + +class E { + var x: i32; + // CHECK:STDERR: COMPILATION ERROR: fail_extend_after_var.carbon:[[@LINE+1]]: `extend base:` declaration must not be after `var` or `mix` declarations in a class. + extend base: C; +} + +fn Main() -> i32 { + return 0; +} diff --git a/explorer/testdata/class/fail_extends_final_class.carbon b/explorer/testdata/class/fail_extend_final_class.carbon similarity index 56% rename from explorer/testdata/class/fail_extends_final_class.carbon rename to explorer/testdata/class/fail_extend_final_class.carbon index 9cfe488840d5..1f402c50a9e3 100644 --- a/explorer/testdata/class/fail_extends_final_class.carbon +++ b/explorer/testdata/class/fail_extend_final_class.carbon @@ -10,9 +10,10 @@ class C { fn F() {} } -class D extends C { +class D { + // CHECK:STDERR: COMPILATION ERROR: fail_extend_final_class.carbon:[[@LINE+1]]: Base class `C` is `final` and cannot be inherited. Add the `base` or `abstract` class prefix to `C` to allow it to be inherited + extend base: C; fn G() {} -// CHECK:STDERR: COMPILATION ERROR: fail_extends_final_class.carbon:[[@LINE+1]]: Base class `C` is `final` and cannot be inherited. Add the `base` or `abstract` class prefix to `C` to allow it to be inherited } fn Main() -> i32 { diff --git a/explorer/testdata/class/fail_extends_non_class.carbon b/explorer/testdata/class/fail_extend_non_class.carbon similarity index 61% rename from explorer/testdata/class/fail_extends_non_class.carbon rename to explorer/testdata/class/fail_extend_non_class.carbon index eb8d67ee9ce3..8f929ed1e2d0 100644 --- a/explorer/testdata/class/fail_extends_non_class.carbon +++ b/explorer/testdata/class/fail_extend_non_class.carbon @@ -6,8 +6,9 @@ package ExplorerTest api; -// CHECK:STDERR: COMPILATION ERROR: fail_extends_non_class.carbon:[[@LINE+1]]: type error in type expression: 'i32' is not implicitly convertible to 'type' -class C extends 3 { +class C { + // CHECK:STDERR: COMPILATION ERROR: fail_extend_non_class.carbon:[[@LINE+1]]: type error in type expression: 'i32' is not implicitly convertible to 'type' + extend base: 3; var x: i32; var y: i32; } diff --git a/explorer/testdata/class/fail_extend_twice.carbon b/explorer/testdata/class/fail_extend_twice.carbon new file mode 100644 index 000000000000..10ae94595f6d --- /dev/null +++ b/explorer/testdata/class/fail_extend_twice.carbon @@ -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 +// +// AUTOUPDATE + +package ExplorerTest api; + +base class C { +} + +base class D { +} + +class E { + extend base: C; + // CHECK:STDERR: COMPILATION ERROR: fail_extend_twice.carbon:[[@LINE+1]]: At most one `extend base:` declaration in a class. + extend base: D; +} + +fn Main() -> i32 { + return 0; +} diff --git a/explorer/testdata/class/fail_field_access_mismatch_base.carbon b/explorer/testdata/class/fail_field_access_mismatch_base.carbon index 294395ab7f1b..e36db8ca84ed 100644 --- a/explorer/testdata/class/fail_field_access_mismatch_base.carbon +++ b/explorer/testdata/class/fail_field_access_mismatch_base.carbon @@ -11,7 +11,8 @@ base class Point { var y: i32; } -class Point3D extends Point { +class Point3D { + extend base: Point; var z: i32; } diff --git a/explorer/testdata/class/fail_field_assign_mismatch_base.carbon b/explorer/testdata/class/fail_field_assign_mismatch_base.carbon index 40585a3c37ef..0028ea6bc8dd 100644 --- a/explorer/testdata/class/fail_field_assign_mismatch_base.carbon +++ b/explorer/testdata/class/fail_field_assign_mismatch_base.carbon @@ -11,7 +11,8 @@ base class Point { var y: i32; } -class Point3D extends Point { +class Point3D { + extend base: Point; var z: i32; } diff --git a/explorer/testdata/class/fail_impl_method_not_existing.carbon b/explorer/testdata/class/fail_impl_method_not_existing.carbon index 44612a9cf872..c30a4ab10102 100644 --- a/explorer/testdata/class/fail_impl_method_not_existing.carbon +++ b/explorer/testdata/class/fail_impl_method_not_existing.carbon @@ -9,7 +9,8 @@ package ExplorerTest api; base class C { } -class D extends C { +class D { + extend base: C; impl fn Foo[self:Self]() -> i32 { return 1; // CHECK:STDERR: COMPILATION ERROR: fail_impl_method_not_existing.carbon:[[@LINE+1]]: Error declaring `Foo`: cannot override a method that is not declared `abstract` or `virtual` in base class. diff --git a/explorer/testdata/class/fail_impl_method_not_virtual.carbon b/explorer/testdata/class/fail_impl_method_not_virtual.carbon index 0a64d878e17c..c845993d8ada 100644 --- a/explorer/testdata/class/fail_impl_method_not_virtual.carbon +++ b/explorer/testdata/class/fail_impl_method_not_virtual.carbon @@ -12,7 +12,8 @@ base class C { } } -class D extends C { +class D { + extend base: C; impl fn Foo[self:Self]() -> i32 { return 1; // CHECK:STDERR: COMPILATION ERROR: fail_impl_method_not_virtual.carbon:[[@LINE+1]]: Error declaring `Foo`: cannot override a method that is not declared `abstract` or `virtual` in base class. diff --git a/explorer/testdata/class/fail_override_virtual_with_non_virtual.carbon b/explorer/testdata/class/fail_override_virtual_with_non_virtual.carbon index 68e64d120c49..7d85fd17e872 100644 --- a/explorer/testdata/class/fail_override_virtual_with_non_virtual.carbon +++ b/explorer/testdata/class/fail_override_virtual_with_non_virtual.carbon @@ -10,7 +10,8 @@ base class A { virtual fn Foo[self: Self]() {} } -class B extends A { +class B { + extend base: A; // CHECK:STDERR: COMPILATION ERROR: fail_override_virtual_with_non_virtual.carbon:[[@LINE+1]]: Error declaring `Foo`: method is declared virtual in base class, use `impl` to override it. fn Foo[self: Self]() {} } diff --git a/explorer/testdata/class/fail_redeclare_virtual_method.carbon b/explorer/testdata/class/fail_redeclare_virtual_method.carbon index 0f7a21f1dc86..fa04c7c06dc3 100644 --- a/explorer/testdata/class/fail_redeclare_virtual_method.carbon +++ b/explorer/testdata/class/fail_redeclare_virtual_method.carbon @@ -10,7 +10,8 @@ base class C { virtual fn Foo[self:Self]() {} } -class D extends C { +class D { + extend base: C; // CHECK:STDERR: COMPILATION ERROR: fail_redeclare_virtual_method.carbon:[[@LINE+1]]: Error declaring `Foo`: method is declared virtual in base class, use `impl` to override it. virtual fn Foo[self:Self]() {} } diff --git a/explorer/testdata/class/fail_virtual_method_absent.carbon b/explorer/testdata/class/fail_virtual_method_absent.carbon index 0ba4bc6605a3..1342aed680aa 100644 --- a/explorer/testdata/class/fail_virtual_method_absent.carbon +++ b/explorer/testdata/class/fail_virtual_method_absent.carbon @@ -8,7 +8,8 @@ package ExplorerTest api; base class A {} -class B extends A { +class B { + extend base: A; virtual fn Foo[self: Self]() -> i32 { return 0; } } diff --git a/explorer/testdata/class/new_and_delete_hierarchy.carbon b/explorer/testdata/class/new_and_delete_hierarchy.carbon index 02308737b5a5..277fb11989fa 100644 --- a/explorer/testdata/class/new_and_delete_hierarchy.carbon +++ b/explorer/testdata/class/new_and_delete_hierarchy.carbon @@ -21,7 +21,8 @@ base class A{ } } -class B extends A { +class B { + extend base: A; fn Create() -> Self{ return {.base={}}; } diff --git a/explorer/testdata/class/non_virtual_dispatch.carbon b/explorer/testdata/class/non_virtual_dispatch.carbon index fb09c480df98..6df132e2d9ee 100644 --- a/explorer/testdata/class/non_virtual_dispatch.carbon +++ b/explorer/testdata/class/non_virtual_dispatch.carbon @@ -20,7 +20,8 @@ base class C { } } -class D extends C { +class D { + extend base: C; var b: i32; fn Foo[self: Self]() -> i32 { return 2; diff --git a/explorer/testdata/class/non_virtual_dispatch_abstract.carbon b/explorer/testdata/class/non_virtual_dispatch_abstract.carbon index 488c849ca621..f8dc4e695696 100644 --- a/explorer/testdata/class/non_virtual_dispatch_abstract.carbon +++ b/explorer/testdata/class/non_virtual_dispatch_abstract.carbon @@ -20,7 +20,8 @@ abstract class C { } } -class D extends C { +class D { + extend base: C; var b: i32; fn Foo[self: Self]() -> i32 { return 2; diff --git a/explorer/testdata/class/parametrized_base_class.carbon b/explorer/testdata/class/parametrized_base_class.carbon index cbffaf301ca4..d2cd9c8537e6 100644 --- a/explorer/testdata/class/parametrized_base_class.carbon +++ b/explorer/testdata/class/parametrized_base_class.carbon @@ -14,7 +14,7 @@ interface Number { fn Add[self: Self](other: Self) -> Self; } -external impl i32 as Number { +impl i32 as Number { fn Zero() -> i32 { return 0; } fn Add[self: i32](other: i32) -> i32 { return self + other; } } @@ -23,7 +23,8 @@ base class A(T:! Number) { var value_a: T; } -class B extends A(i32) { +class B { + extend base: A(i32); var value_b: i32; } diff --git a/explorer/testdata/class/pointer_conversion.carbon b/explorer/testdata/class/pointer_conversion.carbon index 57830559ef73..4bdf729d8ee5 100644 --- a/explorer/testdata/class/pointer_conversion.carbon +++ b/explorer/testdata/class/pointer_conversion.carbon @@ -14,11 +14,13 @@ base class A { var a: i32; } -base class B extends A { +base class B { + extend base: A; var b: i32; } -class C extends B { +class C { + extend base: B; var c: i32; } diff --git a/explorer/testdata/class/virtual_method.carbon b/explorer/testdata/class/virtual_method.carbon index 5f753f6965c9..cf224b8f9a76 100644 --- a/explorer/testdata/class/virtual_method.carbon +++ b/explorer/testdata/class/virtual_method.carbon @@ -22,7 +22,8 @@ base class C { } } -class D extends C { +class D { + extend base: C; impl fn Foo[self: Self]() -> i32 { return 3; } diff --git a/explorer/testdata/class/virtual_method_self.carbon b/explorer/testdata/class/virtual_method_self.carbon index 5e63af1308c2..b9d27ad8d582 100644 --- a/explorer/testdata/class/virtual_method_self.carbon +++ b/explorer/testdata/class/virtual_method_self.carbon @@ -19,14 +19,16 @@ base class C { } } -base class D extends C { +base class D { + extend base: C; var value_d: i32; impl fn Foo[self: Self]() -> i32 { return self.value_d; } } -class E extends D { +class E { + extend base: D; var value_e: i32; impl fn Foo[self: Self]() -> i32 { return self.value_e; diff --git a/explorer/testdata/class/virtual_method_shadowed_attr.carbon b/explorer/testdata/class/virtual_method_shadowed_attr.carbon index 8a1d66b4f3dd..2323032373c3 100644 --- a/explorer/testdata/class/virtual_method_shadowed_attr.carbon +++ b/explorer/testdata/class/virtual_method_shadowed_attr.carbon @@ -17,7 +17,8 @@ base class C { } } -base class D extends C { +base class D { + extend base: C; var value: i32; impl fn Foo[self: Self]() -> i32 { return self.value; diff --git a/explorer/testdata/comparison/custom_equality.carbon b/explorer/testdata/comparison/custom_equality.carbon index 04a848e3d986..00f834652339 100644 --- a/explorer/testdata/comparison/custom_equality.carbon +++ b/explorer/testdata/comparison/custom_equality.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class MyType { var value: i32; - impl as EqWith(Self) { + extend impl as EqWith(Self) { fn Equal[self: Self](other: Self) -> bool { return self.value == other.value; } diff --git a/explorer/testdata/comparison/empty_struct.carbon b/explorer/testdata/comparison/empty_struct.carbon index 2f1f7c47303d..5c62a9783ce3 100644 --- a/explorer/testdata/comparison/empty_struct.carbon +++ b/explorer/testdata/comparison/empty_struct.carbon @@ -7,7 +7,7 @@ package ExplorerTest api; -external impl {} as EqWith({}) { +impl {} as EqWith({}) { fn Equal[self: Self](other: Self) -> bool { return true; } diff --git a/explorer/testdata/constraint/rewrite.carbon b/explorer/testdata/constraint/rewrite.carbon index 3c789e91bc80..91cc6bcaaf80 100644 --- a/explorer/testdata/constraint/rewrite.carbon +++ b/explorer/testdata/constraint/rewrite.carbon @@ -12,7 +12,7 @@ interface HasAssoc { let AssocVal:! i32; } class X { - external impl as HasAssoc where .Assoc = i32 and .AssocVal = 2 {} + impl as HasAssoc where .Assoc = i32 and .AssocVal = 2 {} } fn F[T:! HasAssoc where .Assoc = i32](x: T) -> i32 { diff --git a/explorer/testdata/constraint/rewrite_compound.carbon b/explorer/testdata/constraint/rewrite_compound.carbon index ecd83ef11fb0..765c1d5b3807 100644 --- a/explorer/testdata/constraint/rewrite_compound.carbon +++ b/explorer/testdata/constraint/rewrite_compound.carbon @@ -11,7 +11,7 @@ interface HasAssoc { let Assoc:! type; } class X { - external impl as HasAssoc where .Assoc = i32 {} + impl as HasAssoc where .Assoc = i32 {} } alias WithoutRewrite = HasAssoc where .Assoc == i32; diff --git a/explorer/testdata/constraint/rewrite_compound_2.carbon b/explorer/testdata/constraint/rewrite_compound_2.carbon index 66c1e582d3a7..11e7bc4b6c73 100644 --- a/explorer/testdata/constraint/rewrite_compound_2.carbon +++ b/explorer/testdata/constraint/rewrite_compound_2.carbon @@ -11,7 +11,7 @@ interface HasAssoc { let Assoc:! i32; } class X { - external impl as HasAssoc where .Assoc = 1 {} + impl as HasAssoc where .Assoc = 1 {} } alias WithoutRewrite = HasAssoc where .Assoc == 1; diff --git a/explorer/testdata/constraint/rewrite_in_qualifier.carbon b/explorer/testdata/constraint/rewrite_in_qualifier.carbon index ef3ee37b6182..e8af1c206cbd 100644 --- a/explorer/testdata/constraint/rewrite_in_qualifier.carbon +++ b/explorer/testdata/constraint/rewrite_in_qualifier.carbon @@ -11,7 +11,7 @@ interface HasAssoc { let Assoc:! type; } class X { - external impl as HasAssoc where .Assoc = i32 {} + impl as HasAssoc where .Assoc = i32 {} } alias WithoutRewrite = HasAssoc where .Assoc == i32; diff --git a/explorer/testdata/constraint/rewrite_in_qualifier_and_type.carbon b/explorer/testdata/constraint/rewrite_in_qualifier_and_type.carbon index ae1de8e7f70c..239c7fb6bfd8 100644 --- a/explorer/testdata/constraint/rewrite_in_qualifier_and_type.carbon +++ b/explorer/testdata/constraint/rewrite_in_qualifier_and_type.carbon @@ -11,7 +11,7 @@ interface HasAssoc { let Assoc:! type; } class X { - external impl as HasAssoc where .Assoc = i32 {} + impl as HasAssoc where .Assoc = i32 {} } fn H[T:! HasAssoc where .Assoc = i32, U:! type where .Self == i32](a: T, b: U) -> i32 { diff --git a/explorer/testdata/constraint/where_impls.carbon b/explorer/testdata/constraint/where_impls.carbon index 8d071898d48b..e019b0b7663d 100644 --- a/explorer/testdata/constraint/where_impls.carbon +++ b/explorer/testdata/constraint/where_impls.carbon @@ -13,7 +13,7 @@ interface Base { } interface Extension { - extends Base; + extend Base; } fn F[T:! type where .Self impls Extension](x: T) { diff --git a/explorer/testdata/destructor/destroy_base_class.carbon b/explorer/testdata/destructor/destroy_base_class.carbon index 228a2416fb47..6fd572e76215 100644 --- a/explorer/testdata/destructor/destroy_base_class.carbon +++ b/explorer/testdata/destructor/destroy_base_class.carbon @@ -10,21 +10,23 @@ package ExplorerTest api; base class A { - destructor[self: Self]{ - Print("DESTRUCTOR A {0}", self.a); - } - var a: i32; + destructor[self: Self]{ + Print("DESTRUCTOR A {0}", self.a); + } + var a: i32; } -base class B extends A { - var b: i32; +base class B { + extend base: A; + var b: i32; } -class C extends B { - destructor[self: Self]{ - Print("DESTRUCTOR C {0}", self.c); - } - var c: i32; +class C { + extend base: B; + destructor[self: Self]{ + Print("DESTRUCTOR C {0}", self.c); + } + var c: i32; } fn Main() -> i32 { diff --git a/explorer/testdata/destructor/destroy_base_class_and_members.carbon b/explorer/testdata/destructor/destroy_base_class_and_members.carbon index 1864db29a3d6..beb16d0caa48 100644 --- a/explorer/testdata/destructor/destroy_base_class_and_members.carbon +++ b/explorer/testdata/destructor/destroy_base_class_and_members.carbon @@ -33,7 +33,8 @@ base class A { var a2: Data; } -base class B extends A { +base class B { + extend base: A; fn Make() -> B { return {.base = A.Make(), .b1=Data.Make(5), .b2=Data.Make(4)}; } destructor[self: Self]{ Print("Destroying 3 (B)"); @@ -42,7 +43,8 @@ base class B extends A { var b2: Data; } -class C extends B { +class C { + extend base: B; fn Make() -> C { return {.base = B.Make(), .c1=Data.Make(2), .c2=Data.Make(1)}; } destructor[self: Self]{ Print("Destroying 0 (C)"); diff --git a/explorer/testdata/destructor/fail_delete_base_without_virtual_destructor.carbon b/explorer/testdata/destructor/fail_delete_base_without_virtual_destructor.carbon index 062aa77905d0..b41544187c28 100644 --- a/explorer/testdata/destructor/fail_delete_base_without_virtual_destructor.carbon +++ b/explorer/testdata/destructor/fail_delete_base_without_virtual_destructor.carbon @@ -9,14 +9,15 @@ package ExplorerTest api; base class A{ - destructor[self: Self]{} + destructor[self: Self]{} } -class B extends A { - fn Create() -> Self { - return {.base={}}; - } - destructor[self: Self]{} +class B { + extend base: A; + fn Create() -> Self { + return {.base={}}; + } + destructor[self: Self]{} } fn Main() -> i32 { diff --git a/explorer/testdata/destructor/fail_override_virtual_virtual.carbon b/explorer/testdata/destructor/fail_override_virtual_virtual.carbon index 263e09099dac..6aebab29b58e 100644 --- a/explorer/testdata/destructor/fail_override_virtual_virtual.carbon +++ b/explorer/testdata/destructor/fail_override_virtual_virtual.carbon @@ -11,9 +11,10 @@ base class A { virtual destructor[self: Self]{} } -class B extends A { - // CHECK:STDERR: COMPILATION ERROR: fail_override_virtual_virtual.carbon:[[@LINE+1]]: Error declaring destructor for `B`: use `impl` to implement virtual destructor in child class. - virtual destructor[self: Self]{} +class B { + extend base: A; + // CHECK:STDERR: COMPILATION ERROR: fail_override_virtual_virtual.carbon:[[@LINE+1]]: Error declaring destructor for `B`: use `impl` to implement virtual destructor in child class. + virtual destructor[self: Self]{} } fn Main() -> i32 { diff --git a/explorer/testdata/destructor/virtual_destructor.carbon b/explorer/testdata/destructor/virtual_destructor.carbon index a3459eb713a4..022faf7d9e07 100644 --- a/explorer/testdata/destructor/virtual_destructor.carbon +++ b/explorer/testdata/destructor/virtual_destructor.carbon @@ -17,24 +17,26 @@ package ExplorerTest api; base class A { - virtual destructor[self: Self] { - Print("DESTRUCTOR A"); - } + virtual destructor[self: Self] { + Print("DESTRUCTOR A"); + } } -base class B extends A { - impl destructor[self: Self] { - Print("DESTRUCTOR B"); - } +base class B { + extend base: A; + impl destructor[self: Self] { + Print("DESTRUCTOR B"); + } } -class C extends B { - fn Create() -> Self{ - return {.base={.base={}}}; - } - impl destructor[self: Self] { - Print("DESTRUCTOR C"); - } +class C { + extend base: B; + fn Create() -> Self{ + return {.base={.base={}}}; + } + impl destructor[self: Self] { + Print("DESTRUCTOR C"); + } } fn Main() -> i32 { diff --git a/explorer/testdata/destructor/virtual_destructor_nested.carbon b/explorer/testdata/destructor/virtual_destructor_nested.carbon index 9857f1079095..ccc4905c53c4 100644 --- a/explorer/testdata/destructor/virtual_destructor_nested.carbon +++ b/explorer/testdata/destructor/virtual_destructor_nested.carbon @@ -18,36 +18,37 @@ package ExplorerTest api; - base class A { - virtual destructor[self: Self] { - Print("DESTRUCTOR A"); - } + virtual destructor[self: Self] { + Print("DESTRUCTOR A"); + } } -class B extends A { - fn Create() -> Self{ - return {.base={}}; - } - impl destructor[self: Self] { - Print("DESTRUCTOR B"); - } +class B { + extend base: A; + fn Create() -> Self{ + return {.base={}}; + } + impl destructor[self: Self] { + Print("DESTRUCTOR B"); + } } base class C { - virtual destructor[self: Self] { - Print("DESTRUCTOR C"); - } + virtual destructor[self: Self] { + Print("DESTRUCTOR C"); + } } -class D extends C { - fn Create() -> Self{ - return {.base={}, .d_pa=heap.New(B.Create())}; - } - impl destructor[self: Self] { - Print("DESTRUCTOR D"); - } - var d_pa: A*; +class D { + extend base: C; + fn Create() -> Self{ + return {.base={}, .d_pa=heap.New(B.Create())}; + } + impl destructor[self: Self] { + Print("DESTRUCTOR D"); + } + var d_pa: A*; } fn Main() -> i32 { diff --git a/explorer/testdata/function/convert_args.carbon b/explorer/testdata/function/convert_args.carbon index e584ba7b6929..4ccccc61bfcf 100644 --- a/explorer/testdata/function/convert_args.carbon +++ b/explorer/testdata/function/convert_args.carbon @@ -8,19 +8,19 @@ package ExplorerTest api; class One { - impl One as ImplicitAs(i32) { + extend impl as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return 1; } } } class Two { - impl Two as ImplicitAs(i32) { + extend impl as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return 2; } } } class N { - impl N as ImplicitAs(i32) { + extend impl as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return self.n; } } var n: i32; diff --git a/explorer/testdata/function/return_convertible_to_type.carbon b/explorer/testdata/function/return_convertible_to_type.carbon index cf7d833f3dc5..7fa114111e8a 100644 --- a/explorer/testdata/function/return_convertible_to_type.carbon +++ b/explorer/testdata/function/return_convertible_to_type.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class TypeLike { - impl as ImplicitAs(type) { + extend impl as ImplicitAs(type) { fn Convert[self: Self]() -> type { return i32; } } fn Make() -> Self { return {}; } diff --git a/explorer/testdata/generic_class/class_function.carbon b/explorer/testdata/generic_class/class_function.carbon index ddbea4fdb629..fbb86aaa5d5b 100644 --- a/explorer/testdata/generic_class/class_function.carbon +++ b/explorer/testdata/generic_class/class_function.carbon @@ -26,7 +26,7 @@ class Point(T:! Number) { var y: T; } -external impl i32 as Number { +impl i32 as Number { fn Zero() -> i32 { return 0; } fn Add[self: i32](other: i32) -> i32 { return self + other; } } diff --git a/explorer/testdata/generic_class/generic_class_substitution.carbon b/explorer/testdata/generic_class/generic_class_substitution.carbon index fb44d1b5f40f..38c21f708184 100644 --- a/explorer/testdata/generic_class/generic_class_substitution.carbon +++ b/explorer/testdata/generic_class/generic_class_substitution.carbon @@ -20,7 +20,7 @@ class Point(T:! Number) { var y: T; } -external impl i32 as Number { +impl i32 as Number { fn Zero() -> i32 { return 0; } fn Add[self: i32](other: i32) -> i32 { return self + other; } } diff --git a/explorer/testdata/generic_class/generic_fun_and_class.carbon b/explorer/testdata/generic_class/generic_fun_and_class.carbon index 0e14b70dbb02..e964137baa89 100644 --- a/explorer/testdata/generic_class/generic_fun_and_class.carbon +++ b/explorer/testdata/generic_class/generic_fun_and_class.carbon @@ -29,7 +29,7 @@ fn SumXY[U :! Number](other: Point(U)) -> U { return other.x.Add(other.y); } -external impl i32 as Number { +impl i32 as Number { fn Zero() -> i32 { return 0; } fn Add[self: i32](other: i32) -> i32 { return self + other; } } diff --git a/explorer/testdata/generic_class/impl_with_argument.carbon b/explorer/testdata/generic_class/impl_with_argument.carbon index 0d46ad68dc0a..579b463c2830 100644 --- a/explorer/testdata/generic_class/impl_with_argument.carbon +++ b/explorer/testdata/generic_class/impl_with_argument.carbon @@ -19,7 +19,7 @@ class Point(T:! type) { } // Can implement `Vector` for just `Point(i32)`, not all `Point(T)`. -external impl Point(i32) as Vector { +impl Point(i32) as Vector { fn Zero() -> Point(i32) { return {.x = 0, .y = 0}; } diff --git a/explorer/testdata/generic_class/impl_with_self.carbon b/explorer/testdata/generic_class/impl_with_self.carbon index 475491276586..2999dd63533a 100644 --- a/explorer/testdata/generic_class/impl_with_self.carbon +++ b/explorer/testdata/generic_class/impl_with_self.carbon @@ -18,7 +18,7 @@ class Point(T:! type) { var y: T; } -external impl Point(i32) as Vector { +impl Point(i32) as Vector { // Allowed: `Self` means `Point(i32)` here. fn Zero() -> Self { return {.x = 0, .y = 0}; diff --git a/explorer/testdata/generic_class/parameter_type_conversion.carbon b/explorer/testdata/generic_class/parameter_type_conversion.carbon index 3923a0003b7c..377cd356c715 100644 --- a/explorer/testdata/generic_class/parameter_type_conversion.carbon +++ b/explorer/testdata/generic_class/parameter_type_conversion.carbon @@ -14,7 +14,7 @@ class Holder(N:! i32) { } class IntLike { - impl as ImplicitAs(i32) { + extend impl as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return 4; } } fn Make() -> IntLike { return {}; } diff --git a/explorer/testdata/generic_class/point_with_interface.carbon b/explorer/testdata/generic_class/point_with_interface.carbon index 8f8bfeaadfc1..f6562f988e01 100644 --- a/explorer/testdata/generic_class/point_with_interface.carbon +++ b/explorer/testdata/generic_class/point_with_interface.carbon @@ -26,7 +26,7 @@ class Point(T:! Number) { var y: T; } -external impl i32 as Number { +impl i32 as Number { fn Zero() -> i32 { return 0; } fn Add[self: i32](other: i32) -> i32 { return self + other; } } diff --git a/explorer/testdata/if_else/convert_condition.carbon b/explorer/testdata/if_else/convert_condition.carbon index 1d404ea5e91c..cfdace868eba 100644 --- a/explorer/testdata/if_else/convert_condition.carbon +++ b/explorer/testdata/if_else/convert_condition.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; class LazyEq { var v1: i32; var v2: i32; - impl as ImplicitAs(bool) { + extend impl as ImplicitAs(bool) { fn Convert[self: Self]() -> bool { return self.v1 == self.v2; } diff --git a/explorer/testdata/if_expression/convert_condition.carbon b/explorer/testdata/if_expression/convert_condition.carbon index 0cba534605b0..3f91fb716e63 100644 --- a/explorer/testdata/if_expression/convert_condition.carbon +++ b/explorer/testdata/if_expression/convert_condition.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; class LazyEq { var v1: i32; var v2: i32; - impl as ImplicitAs(bool) { + extend impl as ImplicitAs(bool) { fn Convert[self: Self]() -> bool { return self.v1 == self.v2; } diff --git a/explorer/testdata/impl/deducible_parameter.carbon b/explorer/testdata/impl/deducible_parameter.carbon index aa4f891e8e92..11f97fef4e43 100644 --- a/explorer/testdata/impl/deducible_parameter.carbon +++ b/explorer/testdata/impl/deducible_parameter.carbon @@ -14,7 +14,7 @@ interface B { class C(T:! type) {} -external impl forall [T:! type] C(T) as A(T) & B { +impl forall [T:! type] C(T) as A(T) & B { fn F() -> i32 { return 1; } } diff --git a/explorer/testdata/impl/fail_bad_member_kind.carbon b/explorer/testdata/impl/fail_bad_member_kind.carbon index b641e10b00c1..074dc8e0bb7e 100644 --- a/explorer/testdata/impl/fail_bad_member_kind.carbon +++ b/explorer/testdata/impl/fail_bad_member_kind.carbon @@ -11,7 +11,7 @@ interface A { fn T(); } -external impl i32 as A { +impl i32 as A { // CHECK:STDERR: SYNTAX ERROR: fail_bad_member_kind.carbon:[[@LINE+1]]: syntax error, unexpected CLASS class T {} } diff --git a/explorer/testdata/impl/fail_impl_as.carbon b/explorer/testdata/impl/fail_impl_as.carbon index 1f44cb8ced89..3159f48f65be 100644 --- a/explorer/testdata/impl/fail_impl_as.carbon +++ b/explorer/testdata/impl/fail_impl_as.carbon @@ -7,7 +7,7 @@ package ExplorerTest api; // CHECK:STDERR: COMPILATION ERROR: fail_impl_as.carbon:[[@LINE+1]]: expected a constraint in impl declaration, found i32 -external impl i32 as i32 {} +impl i32 as i32 {} fn Main() -> i32 { } diff --git a/explorer/testdata/impl/fail_impl_as_non_interface.carbon b/explorer/testdata/impl/fail_impl_as_non_interface.carbon index c5fdb070db3b..48ffe4302a5a 100644 --- a/explorer/testdata/impl/fail_impl_as_non_interface.carbon +++ b/explorer/testdata/impl/fail_impl_as_non_interface.carbon @@ -7,7 +7,7 @@ package ExplorerTest api; // CHECK:STDERR: COMPILATION ERROR: fail_impl_as_non_interface.carbon:[[@LINE+1]]: expected a constraint in impl declaration, found String -external impl i32 as String {} +impl i32 as String {} fn Main() -> i32 { } diff --git a/explorer/testdata/impl/fail_impl_as_not_constraint.carbon b/explorer/testdata/impl/fail_impl_as_not_constraint.carbon index 358b0d06501b..de018bf6b63b 100644 --- a/explorer/testdata/impl/fail_impl_as_not_constraint.carbon +++ b/explorer/testdata/impl/fail_impl_as_not_constraint.carbon @@ -7,7 +7,7 @@ package ExplorerTest api; // CHECK:STDERR: COMPILATION ERROR: fail_impl_as_not_constraint.carbon:[[@LINE+1]]: expected a constraint in impl declaration, found i32 -external impl i32 as i32 {} +impl i32 as i32 {} fn Main() -> i32 { } diff --git a/explorer/testdata/impl/fail_impl_as_parameterized.carbon b/explorer/testdata/impl/fail_impl_as_parameterized.carbon index c6f89363485d..a8849f26b42e 100644 --- a/explorer/testdata/impl/fail_impl_as_parameterized.carbon +++ b/explorer/testdata/impl/fail_impl_as_parameterized.carbon @@ -10,7 +10,7 @@ interface Vector(Scalar:! type) { } // CHECK:STDERR: COMPILATION ERROR: fail_impl_as_parameterized.carbon:[[@LINE+1]]: 'Vector' must be given an argument list -external impl i32 as Vector {} +impl i32 as Vector {} fn Main() -> i32 { } diff --git a/explorer/testdata/impl/fail_impl_redefinition.carbon b/explorer/testdata/impl/fail_impl_redefinition.carbon index 3302e7445352..82adf285bcf1 100644 --- a/explorer/testdata/impl/fail_impl_redefinition.carbon +++ b/explorer/testdata/impl/fail_impl_redefinition.carbon @@ -17,7 +17,7 @@ class Point { var y: i32; } -external impl Point as Vector { +impl Point as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } @@ -26,7 +26,7 @@ external impl Point as Vector { } } -external impl Point as Vector { +impl Point as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/impl/fail_nondeducible_parameter.carbon b/explorer/testdata/impl/fail_nondeducible_parameter.carbon index 242f0c2fe97e..2f00770e5a77 100644 --- a/explorer/testdata/impl/fail_nondeducible_parameter.carbon +++ b/explorer/testdata/impl/fail_nondeducible_parameter.carbon @@ -10,6 +10,6 @@ interface A(T:! type) {} interface B {} // CHECK:STDERR: COMPILATION ERROR: fail_nondeducible_parameter.carbon:[[@LINE+1]]: parameter `T:! type` is not deducible from `impl i32 as interface B` -external impl forall [T:! type] i32 as A(T) & B {} +impl forall [T:! type] i32 as A(T) & B {} fn Main() -> i32 { return 0; } diff --git a/explorer/testdata/impl/fail_unmet_impls_constraint.carbon b/explorer/testdata/impl/fail_unmet_impls_constraint.carbon index fdc857173859..c2c2ede35d6b 100644 --- a/explorer/testdata/impl/fail_unmet_impls_constraint.carbon +++ b/explorer/testdata/impl/fail_unmet_impls_constraint.carbon @@ -10,7 +10,7 @@ interface A {} interface B {} // CHECK:STDERR: COMPILATION ERROR: fail_unmet_impls_constraint.carbon:[[@LINE+1]]: could not find implementation of interface B for i32 -external impl i32 as A where i32 impls B {} +impl i32 as A where i32 impls B {} fn Main() -> i32 { return 0; diff --git a/explorer/testdata/impl/impl_in_generic_class.carbon b/explorer/testdata/impl/impl_in_generic_class.carbon index 80264c6d66aa..fc0eaf15368e 100644 --- a/explorer/testdata/impl/impl_in_generic_class.carbon +++ b/explorer/testdata/impl/impl_in_generic_class.carbon @@ -12,7 +12,7 @@ interface I(T:! type) { } class X(U:! type) { - impl as I(U) { + extend impl as I(U) { fn F[self: Self](u: U, o: Self) -> Self { return {.m = u, .n = self.n + o.n}; } } var m: U; diff --git a/explorer/testdata/impl/impls_constraint.carbon b/explorer/testdata/impl/impls_constraint.carbon index 4ee7ef54b1bc..5f3377aa8111 100644 --- a/explorer/testdata/impl/impls_constraint.carbon +++ b/explorer/testdata/impl/impls_constraint.carbon @@ -18,11 +18,11 @@ interface C(T:! type) { fn H() -> T; } -external impl i32 as A { +impl i32 as A { fn F() -> i32 { return 1; } } -external impl i32 as B & C(i32) where .Self impls A { +impl i32 as B & C(i32) where .Self impls A { fn F() -> i32 { return 2; } fn G() -> i32 { return 3; } fn H() -> i32 { return 4; } diff --git a/explorer/testdata/impl/param_impl.carbon b/explorer/testdata/impl/param_impl.carbon index 4a453832b799..e725c5c76e87 100644 --- a/explorer/testdata/impl/param_impl.carbon +++ b/explorer/testdata/impl/param_impl.carbon @@ -17,12 +17,12 @@ class Point(T:! Number) { var y: T; } -external impl i32 as Number { +impl i32 as Number { fn Zero() -> i32 { return 0; } fn Add[self: i32](other: i32) -> i32 { return self + other; } } -external impl forall [U:! Number] Point(U) as Number { +impl forall [U:! Number] Point(U) as Number { fn Zero() -> Point(U) { return {.x = U.Zero(), .y = U.Zero() }; } fn Add[self: Point(U)](other: Point(U)) -> Point(U) { return {.x = self.x.Add(other.x), .y = self.y.Add(other.y)}; diff --git a/explorer/testdata/impl/param_impl2.carbon b/explorer/testdata/impl/param_impl2.carbon index 0352a7fc4a58..a655dd2b8f95 100644 --- a/explorer/testdata/impl/param_impl2.carbon +++ b/explorer/testdata/impl/param_impl2.carbon @@ -17,12 +17,12 @@ class Point(T:! Number) { var y: T; } -external impl i32 as Number { +impl i32 as Number { fn Zero() -> i32 { return 0; } fn Add[self: i32](other: i32) -> i32 { return self + other; } } -external impl forall [U:! Number] Point(U) as Number { +impl forall [U:! Number] Point(U) as Number { fn Zero() -> Point(U) { return {.x = U.Zero(), .y = U.Zero() }; } fn Add[self: Point(U)](other: Point(U)) -> Point(U) { return {.x = self.x.Add(other.x), .y = self.y.Add(other.y)}; diff --git a/explorer/testdata/impl/param_impl_with_self.carbon b/explorer/testdata/impl/param_impl_with_self.carbon index 8c9caa4c5726..6a013d8ea2c9 100644 --- a/explorer/testdata/impl/param_impl_with_self.carbon +++ b/explorer/testdata/impl/param_impl_with_self.carbon @@ -17,12 +17,12 @@ class Point(T:! Number) { var y: T; } -external impl i32 as Number { +impl i32 as Number { fn Zero() -> i32 { return 0; } fn Add[self: i32](other: i32) -> i32 { return self + other; } } -external impl forall [U:! Number] Point(U) as Number { +impl forall [U:! Number] Point(U) as Number { // Allowed: `Self` means `Point(U)` here. fn Zero() -> Self { return {.x = U.Zero(), .y = U.Zero() }; } fn Add[self: Self](other: Self) -> Self { diff --git a/explorer/testdata/impl_match/match_first.carbon b/explorer/testdata/impl_match/match_first.carbon index f1391499a046..fbcd60d67e52 100644 --- a/explorer/testdata/impl_match/match_first.carbon +++ b/explorer/testdata/impl_match/match_first.carbon @@ -24,16 +24,16 @@ interface Y {} interface Z {} __match_first { - external impl forall [T:! X] T as A { + impl forall [T:! X] T as A { fn Which() -> i32 { return 1; } } - external impl forall [T:! Y] T as A { + impl forall [T:! Y] T as A { fn Which() -> i32 { return 2; } } - external impl forall [T:! Z] T as A { + impl forall [T:! Z] T as A { fn Which() -> i32 { return 3; } } - external impl forall [T:! type] T as A { + impl forall [T:! type] T as A { fn Which() -> i32 { return 4; } } } diff --git a/explorer/testdata/impl_match/non_overlapping_labels.carbon b/explorer/testdata/impl_match/non_overlapping_labels.carbon index eead26225bc7..e8f4360fd6c3 100644 --- a/explorer/testdata/impl_match/non_overlapping_labels.carbon +++ b/explorer/testdata/impl_match/non_overlapping_labels.carbon @@ -18,7 +18,7 @@ interface Iface { fn F(); } -external impl forall [T:! HasType where .Self.AssocType impls Iface] T as Iface { +impl forall [T:! HasType where .Self.AssocType impls Iface] T as Iface { fn F() { Print("T as Iface"); T.AssocType.(Iface.F)(); @@ -26,17 +26,17 @@ external impl forall [T:! HasType where .Self.AssocType impls Iface] T as Iface } class A { - impl as Iface { + extend impl as Iface { fn F() { Print("A as Iface"); } } } class B { - impl as HasType where .AssocType = A {} + extend impl as HasType where .AssocType = A {} } class C { - impl as HasType where .AssocType = B {} + extend impl as HasType where .AssocType = B {} } fn Main() -> i32 { diff --git a/explorer/testdata/impl_match/specialization.carbon b/explorer/testdata/impl_match/specialization.carbon index 6c6a75e64d60..72278a7a0261 100644 --- a/explorer/testdata/impl_match/specialization.carbon +++ b/explorer/testdata/impl_match/specialization.carbon @@ -17,7 +17,7 @@ class Point(T:! type) { var y: T; } -external impl Point(i32) as Vector(i32) { +impl Point(i32) as Vector(i32) { fn Add[self: Self](b: Self) -> Self { return {.x = self.x + b.x, .y = self.y + b.y}; } @@ -26,7 +26,7 @@ external impl Point(i32) as Vector(i32) { } } -external impl forall [T:! type] Point(T) as Vector(T) { +impl forall [T:! type] Point(T) as Vector(T) { fn Add[self: Self](b: Self) -> Self { return self; } diff --git a/explorer/testdata/impl_match/type_structure_bindings.carbon b/explorer/testdata/impl_match/type_structure_bindings.carbon index 4b989b91d582..b2cd39e6c5e1 100644 --- a/explorer/testdata/impl_match/type_structure_bindings.carbon +++ b/explorer/testdata/impl_match/type_structure_bindings.carbon @@ -18,25 +18,25 @@ package ExplorerTest api; class A(T:! type, U:! type) {} interface B(T:! type, U:! type) { fn F(); } -external impl forall [T:! type] A(T, i32) as B(i32, i32) { +impl forall [T:! type] A(T, i32) as B(i32, i32) { fn F() { Print("1"); } } -external impl forall [T:! type] A(i32, T) as B(i32, i32) { +impl forall [T:! type] A(i32, T) as B(i32, i32) { fn F() { Print("2"); } } // Intentionally out of order so that explorer can't get the right answer by // chance, by just picking the first or last matching impl. -external impl forall [T:! type] A(i32, i32) as B(i32, T) { +impl forall [T:! type] A(i32, i32) as B(i32, T) { fn F() { Print("4"); } } -external impl forall [T:! type] A(i32, i32) as B(T, i32) { +impl forall [T:! type] A(i32, i32) as B(T, i32) { fn F() { Print("3"); } } -external impl forall [T:! type, U:! type] A(T, i32*) as B(i32*, U) { +impl forall [T:! type, U:! type] A(T, i32*) as B(i32*, U) { fn F() { Print("5"); } } -external impl forall [T:! type, U:! type] A(i32*, T) as B(U, i32*) { +impl forall [T:! type, U:! type] A(i32*, T) as B(U, i32*) { fn F() { Print("6"); } } diff --git a/explorer/testdata/impl_match/type_structure_order.carbon b/explorer/testdata/impl_match/type_structure_order.carbon index b6404ade4512..d31df7a8b1b9 100644 --- a/explorer/testdata/impl_match/type_structure_order.carbon +++ b/explorer/testdata/impl_match/type_structure_order.carbon @@ -16,13 +16,13 @@ interface B(T:! type) { fn F(); } -external impl forall [T:! type] A(T) as B(i32) { +impl forall [T:! type] A(T) as B(i32) { fn F() { Print("A(T) as B(i32)"); } } -external impl forall [T:! type] A(i32) as B(T) { +impl forall [T:! type] A(i32) as B(T) { fn F() { Print("A(i32) as B(T)"); } } -external impl forall [T:! type, U:! type] A(T) as B(U) { +impl forall [T:! type, U:! type] A(T) as B(U) { fn F() { Print("A(T) as B(U)"); } } diff --git a/explorer/testdata/impl_match/type_structure_vs_match_first.carbon b/explorer/testdata/impl_match/type_structure_vs_match_first.carbon index 6d65ee99e337..23bdc5df6b32 100644 --- a/explorer/testdata/impl_match/type_structure_vs_match_first.carbon +++ b/explorer/testdata/impl_match/type_structure_vs_match_first.carbon @@ -19,19 +19,19 @@ interface B(T:! type) { // Note: this match_first has no effect, because it only orders impls with the // same type structure. __match_first { - external impl forall [T:! type] A(T) as B(i32) { + impl forall [T:! type] A(T) as B(i32) { fn F() { Print("A(T) as B(i32)"); } } - external impl forall [T:! type] A(i32) as B(T) { + impl forall [T:! type] A(i32) as B(T) { fn F() { Print("A(i32) as B(T)"); } } } -external impl forall [T:! type, U:! type] A(T) as B(U) { +impl forall [T:! type, U:! type] A(T) as B(U) { fn F() { Print("A(T) as B(U)"); } diff --git a/explorer/testdata/interface/addr_self.carbon b/explorer/testdata/interface/addr_self.carbon index 2dc9c25cb1f8..f00d5ef381f1 100644 --- a/explorer/testdata/interface/addr_self.carbon +++ b/explorer/testdata/interface/addr_self.carbon @@ -18,7 +18,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl as Vector { + extend impl as Vector { fn Zero() -> Self { return {.x = 1, .y = 1}; } diff --git a/explorer/testdata/interface/assoc_constant_constraints_in_scope.carbon b/explorer/testdata/interface/assoc_constant_constraints_in_scope.carbon index 24d77f034199..e7d023e35bca 100644 --- a/explorer/testdata/interface/assoc_constant_constraints_in_scope.carbon +++ b/explorer/testdata/interface/assoc_constant_constraints_in_scope.carbon @@ -16,13 +16,13 @@ interface I(T:! type) { } class CA { - impl as A(i32) where .AResult = i32 {} + extend impl as A(i32) where .AResult = i32 {} } class CB { - impl as B(i32) where .BResult = CA {} + extend impl as B(i32) where .BResult = CA {} } class CI { - impl as I(i32) where .X = CB and .Y = 5 {} + extend impl as I(i32) where .X = CB and .Y = 5 {} } fn Main() -> i32 { diff --git a/explorer/testdata/interface/class_function.carbon b/explorer/testdata/interface/class_function.carbon index 94e75093b92a..36c69e6d2d6e 100644 --- a/explorer/testdata/interface/class_function.carbon +++ b/explorer/testdata/interface/class_function.carbon @@ -16,7 +16,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl Point as Vector { + extend impl as Vector { fn Zero() -> Point { return {.x = 0, .y = 0}; } diff --git a/explorer/testdata/interface/constrained_parameter.carbon b/explorer/testdata/interface/constrained_parameter.carbon index d8b40a33318f..e21c2e0619cb 100644 --- a/explorer/testdata/interface/constrained_parameter.carbon +++ b/explorer/testdata/interface/constrained_parameter.carbon @@ -12,7 +12,7 @@ interface AddMul { fn Mul[self: Self](o: Self) -> Self; } -external impl i32 as AddMul { +impl i32 as AddMul { fn Add[self: i32](o: i32) -> i32 { return self + o; } @@ -35,7 +35,7 @@ interface Vector(Scalar:! AddMul) { class Point { var x: i32; var y: i32; - impl Point as Vector(i32) { + extend impl as Vector(i32) { fn Zero() -> Point { return {.x = 0, .y = 0}; } diff --git a/explorer/testdata/interface/extends.carbon b/explorer/testdata/interface/extend.carbon similarity index 92% rename from explorer/testdata/interface/extends.carbon rename to explorer/testdata/interface/extend.carbon index 79cfaa4f8f12..4e3d4ab30fb1 100644 --- a/explorer/testdata/interface/extends.carbon +++ b/explorer/testdata/interface/extend.carbon @@ -13,7 +13,7 @@ interface Apple(T:! type) { } interface Banana { - extends Apple(i32); + extend Apple(i32); fn G[self: Self](); } @@ -22,7 +22,7 @@ class Carrot { } // This impl also provides an `impl Carrot as Apple(i32)`. -external impl Carrot as Banana { +impl Carrot as Banana { fn F[self: Self]() -> i32 { return self.n; } fn G[self: Self]() { Print("Carrot.G"); } } diff --git a/explorer/testdata/interface/external_impl_point_vector.carbon b/explorer/testdata/interface/external_impl_point_vector.carbon index 835b22edbe4b..cb5a5e4fefb7 100644 --- a/explorer/testdata/interface/external_impl_point_vector.carbon +++ b/explorer/testdata/interface/external_impl_point_vector.carbon @@ -17,7 +17,7 @@ class Point { var y: i32; } -external impl Point as Vector { +impl Point as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/external_impl_use_self.carbon b/explorer/testdata/interface/external_impl_use_self.carbon index 9d04bc5375c1..4b1bb0c40871 100644 --- a/explorer/testdata/interface/external_impl_use_self.carbon +++ b/explorer/testdata/interface/external_impl_use_self.carbon @@ -17,7 +17,7 @@ class Point { var y: i32; } -external impl Point as Vector { +impl Point as Vector { // Allowed: `Self` means `Point` here. fn Add[self: Self](b: Self) -> Self { return {.x = self.x + b.x, .y = self.y + b.y}; diff --git a/explorer/testdata/interface/fail_extend_external.carbon b/explorer/testdata/interface/fail_extend_external.carbon new file mode 100644 index 000000000000..e65d63c2a3cb --- /dev/null +++ b/explorer/testdata/interface/fail_extend_external.carbon @@ -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 +// +// AUTOUPDATE + +package ExplorerTest api; + +class IntHolder { + var n: i32; +} + +// CHECK:STDERR: SYNTAX ERROR: fail_extend_external.carbon:[[@LINE+1]]: syntax error, unexpected EXTEND, expecting END_OF_FILE +extend impl IntHolder as ImplicitAs(i32) { + fn Convert[self: Self]() -> i32 { return self.n; } +} + +fn Main() -> i32 { + return ({.n = 5} as IntHolder).(ImplicitAs(i32).Convert)(); +} diff --git a/explorer/testdata/interface/fail_extends_not_constraint.carbon b/explorer/testdata/interface/fail_extend_not_constraint.carbon similarity index 65% rename from explorer/testdata/interface/fail_extends_not_constraint.carbon rename to explorer/testdata/interface/fail_extend_not_constraint.carbon index a7f18f15357e..db8c33165c0b 100644 --- a/explorer/testdata/interface/fail_extends_not_constraint.carbon +++ b/explorer/testdata/interface/fail_extend_not_constraint.carbon @@ -7,8 +7,8 @@ package ExplorerTest api; interface Vector { - // CHECK:STDERR: COMPILATION ERROR: fail_extends_not_constraint.carbon:[[@LINE+1]]: expected a constraint in extends declaration, found i32 - extends i32; + // CHECK:STDERR: COMPILATION ERROR: fail_extend_not_constraint.carbon:[[@LINE+1]]: expected a constraint in extend declaration, found i32 + extend i32; } fn Main() -> i32 { diff --git a/explorer/testdata/interface/fail_extend_with_self.carbon b/explorer/testdata/interface/fail_extend_with_self.carbon new file mode 100644 index 000000000000..06c7208301c5 --- /dev/null +++ b/explorer/testdata/interface/fail_extend_with_self.carbon @@ -0,0 +1,28 @@ +// 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 +// +// AUTOUPDATE + +package ExplorerTest api; + +interface Z { + fn Zero() -> Self; +} + +class Point { + var x: i32; + var y: i32; + // `Self` not allowed after `extend impl`. + // CHECK:STDERR: SYNTAX ERROR: fail_extend_with_self.carbon:[[@LINE+1]]: syntax error, unexpected SELF, expecting AS + extend impl Self as Z { + fn Zero() -> Self { + return {.x = 0, .y = 0}; + } + } +} + +fn Main() -> i32 { + var a: Point = Point.Zero(); + return p.x; +} diff --git a/explorer/testdata/interface/fail_external_impl_omit_self.carbon b/explorer/testdata/interface/fail_external_impl_omit_self.carbon index 22b31eaff477..d5842b456e9f 100644 --- a/explorer/testdata/interface/fail_external_impl_omit_self.carbon +++ b/explorer/testdata/interface/fail_external_impl_omit_self.carbon @@ -18,7 +18,7 @@ class Point { // Error: need to specify which type implementing `Vector` for. // CHECK:STDERR: COMPILATION ERROR: fail_external_impl_omit_self.carbon:[[@LINE+1]]: could not resolve 'Self' -external impl as Vector { +impl as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/fail_external_impl_self.carbon b/explorer/testdata/interface/fail_external_impl_self.carbon index 1cc91318d6ad..f3ae01daea93 100644 --- a/explorer/testdata/interface/fail_external_impl_self.carbon +++ b/explorer/testdata/interface/fail_external_impl_self.carbon @@ -17,7 +17,7 @@ class Point { } // CHECK:STDERR: COMPILATION ERROR: fail_external_impl_self.carbon:[[@LINE+1]]: could not resolve 'Self' -external impl Self as Vector { +impl Self as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/fail_impl_bad_member.carbon b/explorer/testdata/interface/fail_impl_bad_member.carbon index a529b571311c..2d12557fa64f 100644 --- a/explorer/testdata/interface/fail_impl_bad_member.carbon +++ b/explorer/testdata/interface/fail_impl_bad_member.carbon @@ -14,7 +14,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl Point as Vector { + extend impl as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/fail_impl_missing_member.carbon b/explorer/testdata/interface/fail_impl_missing_member.carbon index f0d79cc2e792..d6a565674555 100644 --- a/explorer/testdata/interface/fail_impl_missing_member.carbon +++ b/explorer/testdata/interface/fail_impl_missing_member.carbon @@ -14,7 +14,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl Point as Vector { + extend impl as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/fail_interface_missing_member.carbon b/explorer/testdata/interface/fail_interface_missing_member.carbon index 248eb3374ffb..69bcdcbc93f1 100644 --- a/explorer/testdata/interface/fail_interface_missing_member.carbon +++ b/explorer/testdata/interface/fail_interface_missing_member.carbon @@ -18,7 +18,7 @@ fn ScaleGeneric[T:! Vector](a: T, s: i32) -> T { class Point { var x: i32; var y: i32; - impl Point as Vector { + extend impl as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/fail_impl_as_not_constraint.carbon b/explorer/testdata/interface/fail_require_not_constraint.carbon similarity index 66% rename from explorer/testdata/interface/fail_impl_as_not_constraint.carbon rename to explorer/testdata/interface/fail_require_not_constraint.carbon index 8b074fad424b..4c431eabc2a8 100644 --- a/explorer/testdata/interface/fail_impl_as_not_constraint.carbon +++ b/explorer/testdata/interface/fail_require_not_constraint.carbon @@ -7,8 +7,8 @@ package ExplorerTest api; interface Vector { - // CHECK:STDERR: COMPILATION ERROR: fail_impl_as_not_constraint.carbon:[[@LINE+1]]: expected a constraint in impl as declaration, found i32 - impl Self as i32; + // CHECK:STDERR: COMPILATION ERROR: fail_require_not_constraint.carbon:[[@LINE+1]]: expected a constraint in require declaration, found i32 + require Self impls i32; } fn Main() -> i32 { diff --git a/explorer/testdata/interface/fail_impl_as_not_type.carbon b/explorer/testdata/interface/fail_require_not_type.carbon similarity index 82% rename from explorer/testdata/interface/fail_impl_as_not_type.carbon rename to explorer/testdata/interface/fail_require_not_type.carbon index eb7fd399b3e9..a98af48fb7d6 100644 --- a/explorer/testdata/interface/fail_impl_as_not_type.carbon +++ b/explorer/testdata/interface/fail_require_not_type.carbon @@ -9,8 +9,8 @@ package ExplorerTest api; interface A {} interface B { - // CHECK:STDERR: COMPILATION ERROR: fail_impl_as_not_type.carbon:[[@LINE+1]]: type error in type expression: 'i32' is not implicitly convertible to 'type' - impl 5 as A; + // CHECK:STDERR: COMPILATION ERROR: fail_require_not_type.carbon:[[@LINE+1]]: type error in type expression: 'i32' is not implicitly convertible to 'type' + require 5 impls A; } fn Main() -> i32 { diff --git a/explorer/testdata/interface/generic_call_generic.carbon b/explorer/testdata/interface/generic_call_generic.carbon index 1e44084b1b24..82570013a8f6 100644 --- a/explorer/testdata/interface/generic_call_generic.carbon +++ b/explorer/testdata/interface/generic_call_generic.carbon @@ -15,7 +15,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl Point as Vector { + extend impl as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/generic_with_two_params.carbon b/explorer/testdata/interface/generic_with_two_params.carbon index 0966d5dd4f0e..fcba0882728d 100644 --- a/explorer/testdata/interface/generic_with_two_params.carbon +++ b/explorer/testdata/interface/generic_with_two_params.carbon @@ -15,7 +15,7 @@ interface Vector { class Point1 { var x: i32; var y: i32; - impl Point1 as Vector { + extend impl as Vector { fn Add[self: Point1](b: Point1) -> Point1 { return {.x = self.x + b.x, .y = self.y + b.y}; } @@ -28,7 +28,7 @@ class Point1 { class Point2 { var x: i32; var y: i32; - impl Point2 as Vector { + extend impl as Vector { fn Add[self: Point2](b: Point2) -> Point2 { return {.x = self.x + b.x + 1, .y = self.y + b.y + 1}; } diff --git a/explorer/testdata/interface/omit_self.carbon b/explorer/testdata/interface/omit_self.carbon index a12fc7025b66..4e17bb8b1509 100644 --- a/explorer/testdata/interface/omit_self.carbon +++ b/explorer/testdata/interface/omit_self.carbon @@ -18,7 +18,7 @@ class Point { var y: i32; // Allowed: means the same as `impl Self as Vector` // or `impl Point as Vector`. - impl as Vector { + extend impl as Vector { fn Zero() -> Point { return {.x = 0, .y = 0}; } diff --git a/explorer/testdata/interface/parameterized.carbon b/explorer/testdata/interface/parameterized.carbon index 2ba1a699350e..725cd4590cd2 100644 --- a/explorer/testdata/interface/parameterized.carbon +++ b/explorer/testdata/interface/parameterized.carbon @@ -16,7 +16,7 @@ interface Vector(Scalar:! type) { class Point { var x: i32; var y: i32; - impl Point as Vector(i32) { + extend impl as Vector(i32) { fn Zero() -> Point { return {.x = 0, .y = 0}; } diff --git a/explorer/testdata/interface/impl_as.carbon b/explorer/testdata/interface/require.carbon similarity index 87% rename from explorer/testdata/interface/impl_as.carbon rename to explorer/testdata/interface/require.carbon index 38a7ece9ef65..67f0dd9cd4b6 100644 --- a/explorer/testdata/interface/impl_as.carbon +++ b/explorer/testdata/interface/require.carbon @@ -13,7 +13,7 @@ interface Apple(T:! type) { } interface Banana { - impl as Apple(i32); + require Self impls Apple(i32); fn G[self: Self](); } @@ -21,11 +21,11 @@ class Carrot { var n: i32; } -external impl Carrot as Apple(i32) { +impl Carrot as Apple(i32) { fn F[self: Self]() -> i32 { return self.n; } } -external impl Carrot as Banana { +impl Carrot as Banana { fn G[self: Self]() { Print("Carrot.G"); } } diff --git a/explorer/testdata/interface/impl_as_not_self.carbon b/explorer/testdata/interface/require_not_self.carbon similarity index 80% rename from explorer/testdata/interface/impl_as_not_self.carbon rename to explorer/testdata/interface/require_not_self.carbon index 674cb9bd2cfa..67765a9097f9 100644 --- a/explorer/testdata/interface/impl_as_not_self.carbon +++ b/explorer/testdata/interface/require_not_self.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; interface ConvertsFromInt { - impl i32 as ImplicitAs(Self); + require i32 impls ImplicitAs(Self); } fn ConvertIntTo(T:! ConvertsFromInt, n: i32) -> T { @@ -18,10 +18,10 @@ fn ConvertIntTo(T:! ConvertsFromInt, n: i32) -> T { class IntHolder { var n: i32; } -external impl i32 as ImplicitAs(IntHolder) { +impl i32 as ImplicitAs(IntHolder) { fn Convert[self: Self]() -> IntHolder { return {.n = self}; } } -external impl IntHolder as ConvertsFromInt {} +impl IntHolder as ConvertsFromInt {} fn Main() -> i32 { return ConvertIntTo(IntHolder, 5).n; diff --git a/explorer/testdata/interface/tuple_vector_add_scale.carbon b/explorer/testdata/interface/tuple_vector_add_scale.carbon index 13c0e82c6366..e7c0682fcade 100644 --- a/explorer/testdata/interface/tuple_vector_add_scale.carbon +++ b/explorer/testdata/interface/tuple_vector_add_scale.carbon @@ -15,7 +15,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl Point as Vector { + extend impl as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/vector_point_add_scale.carbon b/explorer/testdata/interface/vector_point_add_scale.carbon index e8aba50d6442..3cf4be518a44 100644 --- a/explorer/testdata/interface/vector_point_add_scale.carbon +++ b/explorer/testdata/interface/vector_point_add_scale.carbon @@ -15,7 +15,7 @@ interface Vector { class Point { var x: i32; var y: i32; - impl Point as Vector { + extend impl as Vector { fn Add[self: Point](b: Point) -> Point { return {.x = self.x + b.x, .y = self.y + b.y}; } diff --git a/explorer/testdata/interface/with_self.carbon b/explorer/testdata/interface/with_self.carbon index 6378b06e22f3..bb740990bea5 100644 --- a/explorer/testdata/interface/with_self.carbon +++ b/explorer/testdata/interface/with_self.carbon @@ -16,7 +16,7 @@ interface Vector { class Point { var x: i32; var y: i32; - // Allowed: `Self` means `Point` here. + // Allowed without `extend`: `Self` means `Point` here. impl Self as Vector { fn Zero() -> Self { return {.x = 0, .y = 0}; diff --git a/explorer/testdata/let/implicit_conversion.carbon b/explorer/testdata/let/implicit_conversion.carbon index 06b41abd2f19..50a487ac716a 100644 --- a/explorer/testdata/let/implicit_conversion.carbon +++ b/explorer/testdata/let/implicit_conversion.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class A { - impl as ImplicitAs(i32) { + extend impl as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return self.n; } } var n: i32; diff --git a/explorer/testdata/member_access/convert_lhs_class.carbon b/explorer/testdata/member_access/convert_lhs_class.carbon index a77369c39506..613cf84c690f 100644 --- a/explorer/testdata/member_access/convert_lhs_class.carbon +++ b/explorer/testdata/member_access/convert_lhs_class.carbon @@ -14,7 +14,7 @@ class X { class Y { var m: i32; - impl as ImplicitAs(X) { + extend impl as ImplicitAs(X) { fn Convert[self: Self]() -> X { return {.n = self.m}; } } } diff --git a/explorer/testdata/member_access/convert_lhs_interface.carbon b/explorer/testdata/member_access/convert_lhs_interface.carbon index cc42235632cc..05a5c019f2d6 100644 --- a/explorer/testdata/member_access/convert_lhs_interface.carbon +++ b/explorer/testdata/member_access/convert_lhs_interface.carbon @@ -12,7 +12,7 @@ interface HasF { } class X { - impl as HasF { + extend impl as HasF { fn F[self: Self](o: Self) -> Self { return {.n = self.n + o.n}; } } var n: i32; @@ -20,7 +20,7 @@ class X { class Y { var m: i32; - impl as ImplicitAs(X) { + extend impl as ImplicitAs(X) { fn Convert[self: Self]() -> X { return {.n = self.m}; } } } diff --git a/explorer/testdata/member_access/fail_vacuous_access.carbon b/explorer/testdata/member_access/fail_vacuous_access.carbon index 54e4542b3fe1..b907693c91ea 100644 --- a/explorer/testdata/member_access/fail_vacuous_access.carbon +++ b/explorer/testdata/member_access/fail_vacuous_access.carbon @@ -7,7 +7,7 @@ package Foo api; interface A { fn F() -> i32; } class X { - impl as A { + extend impl as A { fn F() -> i32 { return 1; } } } diff --git a/explorer/testdata/member_access/fail_vacuous_access_via_type_param.carbon b/explorer/testdata/member_access/fail_vacuous_access_via_type_param.carbon index 34bf7c601911..cb05a1e25919 100644 --- a/explorer/testdata/member_access/fail_vacuous_access_via_type_param.carbon +++ b/explorer/testdata/member_access/fail_vacuous_access_via_type_param.carbon @@ -7,7 +7,7 @@ package Foo api; interface A { fn F() -> i32; } class X { - impl as A { + extend impl as A { fn F() -> i32 { return 1; } } } diff --git a/explorer/testdata/member_access/nearly_vacuous_access_with_impl_lookup.carbon b/explorer/testdata/member_access/nearly_vacuous_access_with_impl_lookup.carbon index aaf2822992c6..fa0be137c45e 100644 --- a/explorer/testdata/member_access/nearly_vacuous_access_with_impl_lookup.carbon +++ b/explorer/testdata/member_access/nearly_vacuous_access_with_impl_lookup.carbon @@ -8,7 +8,7 @@ package Foo api; interface A { fn F() -> i32; } class X { - impl as A { + extend impl as A { fn F() -> i32 { return 1; } } } diff --git a/explorer/testdata/member_access/nearly_vacuous_access_with_instance_binding.carbon b/explorer/testdata/member_access/nearly_vacuous_access_with_instance_binding.carbon index d731290da077..23ef654fbd7d 100644 --- a/explorer/testdata/member_access/nearly_vacuous_access_with_instance_binding.carbon +++ b/explorer/testdata/member_access/nearly_vacuous_access_with_instance_binding.carbon @@ -8,7 +8,7 @@ package Foo api; interface A { fn F[self: Self]() -> i32; } class X { - impl as A { + extend impl as A { fn F[self: Self]() -> i32 { return 1; } } } diff --git a/explorer/testdata/member_access/param_qualified_interface_member.carbon b/explorer/testdata/member_access/param_qualified_interface_member.carbon index 1d7b9cc5d8c8..c778eb7b6ab9 100644 --- a/explorer/testdata/member_access/param_qualified_interface_member.carbon +++ b/explorer/testdata/member_access/param_qualified_interface_member.carbon @@ -10,7 +10,7 @@ interface A { fn F[self: Self](o: Self) -> Self; } class X { - impl as A { + extend impl as A { fn F[self: Self](o: Self) -> Self { return {.n = self.n + o.n}; } } var n: i32; diff --git a/explorer/testdata/member_access/qualified_constraint_member.carbon b/explorer/testdata/member_access/qualified_constraint_member.carbon index e000e82b44bb..dadcc9096844 100644 --- a/explorer/testdata/member_access/qualified_constraint_member.carbon +++ b/explorer/testdata/member_access/qualified_constraint_member.carbon @@ -14,10 +14,10 @@ interface B { } alias C = A & B; class X { - impl as A { + extend impl as A { fn F[self: Self]() -> i32 { return 10 * self.n; } } - impl as B { + extend impl as B { fn G(o: Self) -> i32 { return o.n; } } var n: i32; diff --git a/explorer/testdata/member_access/qualified_interface_member.carbon b/explorer/testdata/member_access/qualified_interface_member.carbon index 4ffb97aa1bd0..e686b0785372 100644 --- a/explorer/testdata/member_access/qualified_interface_member.carbon +++ b/explorer/testdata/member_access/qualified_interface_member.carbon @@ -10,7 +10,7 @@ interface A { fn F[self: Self](o: Self) -> Self; } class X { - impl as A { + extend impl as A { fn F[self: Self](o: Self) -> Self { return {.n = self.n + o.n}; } } var n: i32; diff --git a/explorer/testdata/member_access/qualified_param_member.carbon b/explorer/testdata/member_access/qualified_param_member.carbon index 412e6805ec33..d371b20d1f65 100644 --- a/explorer/testdata/member_access/qualified_param_member.carbon +++ b/explorer/testdata/member_access/qualified_param_member.carbon @@ -10,7 +10,7 @@ interface A { fn F[self: Self](o: Self) -> Self; } class X { - impl as A { + extend impl as A { fn F[self: Self](o: Self) -> Self { return {.n = self.n + o.n}; } } var n: i32; diff --git a/explorer/testdata/mixin/fail_mix_in_impl.carbon b/explorer/testdata/mixin/fail_mix_in_impl.carbon index 5dc774dd7d89..a10f0df2d157 100644 --- a/explorer/testdata/mixin/fail_mix_in_impl.carbon +++ b/explorer/testdata/mixin/fail_mix_in_impl.carbon @@ -16,7 +16,7 @@ interface A { fn F(); } -external impl i32 as A { +impl i32 as A { // CHECK:STDERR: SYNTAX ERROR: fail_mix_in_impl.carbon:[[@LINE+1]]: syntax error, unexpected MIX __mix Operations; fn F() {} diff --git a/explorer/testdata/named_constraint/extends.carbon b/explorer/testdata/named_constraint/extend.carbon similarity index 92% rename from explorer/testdata/named_constraint/extends.carbon rename to explorer/testdata/named_constraint/extend.carbon index 88bb0696d91c..b1837a4989e9 100644 --- a/explorer/testdata/named_constraint/extends.carbon +++ b/explorer/testdata/named_constraint/extend.carbon @@ -17,16 +17,16 @@ interface Maker(T:! type) { } constraint IndirectMaker(T:! type) { - extends Maker(T*); + extend Maker(T*); } constraint MoreIndirectMaker { - extends IndirectMaker(i32); + extend IndirectMaker(i32); } class PointerFactory { var p: i32*; - external impl as Maker(i32*) { + impl as Maker(i32*) { fn Make[self: Self]() -> i32* { return self.p; } } } diff --git a/explorer/testdata/named_constraint/fail_compound_member_access.carbon b/explorer/testdata/named_constraint/fail_compound_member_access.carbon index adebecdbdb8f..fac9ae2dadf5 100644 --- a/explorer/testdata/named_constraint/fail_compound_member_access.carbon +++ b/explorer/testdata/named_constraint/fail_compound_member_access.carbon @@ -12,10 +12,10 @@ interface MyAddWith(T:! type) { } constraint MyAdd { - extends MyAddWith(Self) where .Result = Self; + extend MyAddWith(Self) where .Result = Self; } -external impl i32 as MyAdd { +impl i32 as MyAdd { fn Op[self: i32](other: i32) -> i32 { return self + other; } } diff --git a/explorer/testdata/named_constraint/fail_impl_as_member_access.carbon b/explorer/testdata/named_constraint/fail_require_member_access.carbon similarity index 84% rename from explorer/testdata/named_constraint/fail_impl_as_member_access.carbon rename to explorer/testdata/named_constraint/fail_require_member_access.carbon index 7149a0cd52a5..93ee327efeef 100644 --- a/explorer/testdata/named_constraint/fail_impl_as_member_access.carbon +++ b/explorer/testdata/named_constraint/fail_require_member_access.carbon @@ -11,13 +11,13 @@ interface HasFoo { } constraint ImplAsHasFoo { - impl as HasFoo; + require Self impls HasFoo; } fn CallFoo[T:! ImplAsHasFoo](x: T) { // OK, T is HasFoo. x.(HasFoo.Foo)(); - // CHECK:STDERR: COMPILATION ERROR: fail_impl_as_member_access.carbon:[[@LINE+1]]: member access, Foo not in constraint ImplAsHasFoo where T impls interface HasFoo + // CHECK:STDERR: COMPILATION ERROR: fail_require_member_access.carbon:[[@LINE+1]]: member access, Foo not in constraint ImplAsHasFoo where T impls interface HasFoo x.Foo(); } diff --git a/explorer/testdata/named_constraint/impl_constraint.carbon b/explorer/testdata/named_constraint/impl_constraint.carbon index 2691c1f5bfd5..de0de82df432 100644 --- a/explorer/testdata/named_constraint/impl_constraint.carbon +++ b/explorer/testdata/named_constraint/impl_constraint.carbon @@ -16,11 +16,11 @@ interface Walkable { } constraint Traversible { - extends Runnable; - extends Walkable; + extend Runnable; + extend Walkable; } -external impl i32 as Traversible { +impl i32 as Traversible { fn Run[self: i32]() -> i32 { return 10 * self; } diff --git a/explorer/testdata/named_constraint/impl_as.carbon b/explorer/testdata/named_constraint/require.carbon similarity index 80% rename from explorer/testdata/named_constraint/impl_as.carbon rename to explorer/testdata/named_constraint/require.carbon index 89cafeaf383c..a1450b98e2e8 100644 --- a/explorer/testdata/named_constraint/impl_as.carbon +++ b/explorer/testdata/named_constraint/require.carbon @@ -13,18 +13,18 @@ interface MyHashable { } constraint HashToIntConvertible { - impl as MyHashable; - impl Self.(MyHashable.Result) as ImplicitAs(i32); + require Self impls MyHashable; + require Self.(MyHashable.Result) impls ImplicitAs(i32); } class MyHashValue { - external impl as ImplicitAs(i32) { + impl as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return 4; } } } class Widget { - external impl as MyHashable where .Result = MyHashValue { + impl as MyHashable where .Result = MyHashValue { fn Hash[self: Self]() -> MyHashValue { return {}; } } } diff --git a/explorer/testdata/namespace/members.carbon b/explorer/testdata/namespace/members.carbon index f9546323e568..7549949d3721 100644 --- a/explorer/testdata/namespace/members.carbon +++ b/explorer/testdata/namespace/members.carbon @@ -17,7 +17,9 @@ base class N.BaseClass { __mix Mixin; } -class N.DerivedClass extends BaseClass {} +class N.DerivedClass { + extend base: BaseClass; +} namespace N.Inner; @@ -30,7 +32,7 @@ interface N.Iface { } constraint N.Constraint { - extends Iface; + extend Iface; } var v: N.DerivedClass = {.base = {}}; diff --git a/explorer/testdata/operators/add.carbon b/explorer/testdata/operators/add.carbon index 0851bc1d0b6c..2c7ce332e531 100644 --- a/explorer/testdata/operators/add.carbon +++ b/explorer/testdata/operators/add.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as Add { +impl A as Add { fn Op[self: Self](rhs: A) -> A { return {.n = self.n + rhs.n}; } } diff --git a/explorer/testdata/operators/add_with.carbon b/explorer/testdata/operators/add_with.carbon index 7a591a86e5e2..5b22225bcc77 100644 --- a/explorer/testdata/operators/add_with.carbon +++ b/explorer/testdata/operators/add_with.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as AddWith(i32) where .Result = A { +impl A as AddWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n + rhs}; } } diff --git a/explorer/testdata/operators/bit_and.carbon b/explorer/testdata/operators/bit_and.carbon index c0fb208ceada..a47f197db9bd 100644 --- a/explorer/testdata/operators/bit_and.carbon +++ b/explorer/testdata/operators/bit_and.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as BitAndWith(i32) where .Result = A { +impl A as BitAndWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n & rhs}; } } diff --git a/explorer/testdata/operators/bit_complement.carbon b/explorer/testdata/operators/bit_complement.carbon index d15149b1c974..05acaaa57284 100644 --- a/explorer/testdata/operators/bit_complement.carbon +++ b/explorer/testdata/operators/bit_complement.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as BitComplement where .Result = A { +impl A as BitComplement where .Result = A { fn Op[self: Self]() -> A { return {.n = ^self.n}; } } diff --git a/explorer/testdata/operators/bit_or.carbon b/explorer/testdata/operators/bit_or.carbon index fa544e937c92..724d0b98a5e6 100644 --- a/explorer/testdata/operators/bit_or.carbon +++ b/explorer/testdata/operators/bit_or.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as BitOrWith(i32) where .Result = A { +impl A as BitOrWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n | rhs}; } } diff --git a/explorer/testdata/operators/bit_xor.carbon b/explorer/testdata/operators/bit_xor.carbon index c0c73c8056c8..ded9d15a7355 100644 --- a/explorer/testdata/operators/bit_xor.carbon +++ b/explorer/testdata/operators/bit_xor.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as BitXorWith(i32) where .Result = A { +impl A as BitXorWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n ^ rhs}; } } diff --git a/explorer/testdata/operators/div.carbon b/explorer/testdata/operators/div.carbon index 0d252c14ed58..976faf397261 100644 --- a/explorer/testdata/operators/div.carbon +++ b/explorer/testdata/operators/div.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as DivWith(i32) where .Result = A { +impl A as DivWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n / rhs}; } } diff --git a/explorer/testdata/operators/inc_dec.carbon b/explorer/testdata/operators/inc_dec.carbon index 26999f372058..f8db3b2fbe66 100644 --- a/explorer/testdata/operators/inc_dec.carbon +++ b/explorer/testdata/operators/inc_dec.carbon @@ -17,10 +17,10 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as Inc { +impl A as Inc { fn Op[addr self: Self*]() { ++self->n; } } -external impl A as Dec { +impl A as Dec { fn Op[addr self: Self*]() { --self->n; } } diff --git a/explorer/testdata/operators/left_shift.carbon b/explorer/testdata/operators/left_shift.carbon index 1c5ee373e75c..536da92e5663 100644 --- a/explorer/testdata/operators/left_shift.carbon +++ b/explorer/testdata/operators/left_shift.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as LeftShiftWith(i32) where .Result = A { +impl A as LeftShiftWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n << rhs}; } } diff --git a/explorer/testdata/operators/mod.carbon b/explorer/testdata/operators/mod.carbon index 887ac629af9e..cf599fd2bade 100644 --- a/explorer/testdata/operators/mod.carbon +++ b/explorer/testdata/operators/mod.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as ModWith(i32) where .Result = A { +impl A as ModWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n % rhs}; } } diff --git a/explorer/testdata/operators/mul.carbon b/explorer/testdata/operators/mul.carbon index 68513990322d..4cdb1378da07 100644 --- a/explorer/testdata/operators/mul.carbon +++ b/explorer/testdata/operators/mul.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as MulWith(i32) where .Result = A { +impl A as MulWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n * rhs}; } } diff --git a/explorer/testdata/operators/negate.carbon b/explorer/testdata/operators/negate.carbon index afb19cf6be9f..84ccb1574f77 100644 --- a/explorer/testdata/operators/negate.carbon +++ b/explorer/testdata/operators/negate.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as Negate where .Result = A { +impl A as Negate where .Result = A { fn Op[self: Self]() -> A { return {.n = -self.n}; } } diff --git a/explorer/testdata/operators/right_shift.carbon b/explorer/testdata/operators/right_shift.carbon index c9091bbc4bbd..7fe4ddc58f92 100644 --- a/explorer/testdata/operators/right_shift.carbon +++ b/explorer/testdata/operators/right_shift.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as RightShiftWith(i32) where .Result = A { +impl A as RightShiftWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n >> rhs}; } } diff --git a/explorer/testdata/operators/sub.carbon b/explorer/testdata/operators/sub.carbon index cd1d458d7d42..30c171caa3ef 100644 --- a/explorer/testdata/operators/sub.carbon +++ b/explorer/testdata/operators/sub.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; class A { var n: i32; } -external impl A as SubWith(i32) where .Result = A { +impl A as SubWith(i32) where .Result = A { fn Op[self: Self](rhs: i32) -> A { return {.n = self.n - rhs}; } } diff --git a/explorer/testdata/pointer/pointer_to_type_like.carbon b/explorer/testdata/pointer/pointer_to_type_like.carbon index 02f48735d392..258d2bc582b5 100644 --- a/explorer/testdata/pointer/pointer_to_type_like.carbon +++ b/explorer/testdata/pointer/pointer_to_type_like.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; class TypeLike { var v: type; - impl as ImplicitAs(type) { + extend impl as ImplicitAs(type) { fn Convert[self: Self]() -> type { return i32; } } } diff --git a/explorer/testdata/print/associated_constant.carbon b/explorer/testdata/print/associated_constant.carbon index e222e70bcf59..42b58272ee4f 100644 --- a/explorer/testdata/print/associated_constant.carbon +++ b/explorer/testdata/print/associated_constant.carbon @@ -13,8 +13,8 @@ interface HasName { let Name:! String; } -external impl i32 as HasName where .Name = "i32" {} -external impl String as HasName where .Name = "String" {} +impl i32 as HasName where .Name = "i32" {} +impl String as HasName where .Name = "String" {} fn Main() -> i32 { Print(i32.(HasName.Name)); diff --git a/explorer/testdata/return/convert_return_value.carbon b/explorer/testdata/return/convert_return_value.carbon index 04efb76fcc80..e9b031374b80 100644 --- a/explorer/testdata/return/convert_return_value.carbon +++ b/explorer/testdata/return/convert_return_value.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class A { - impl as ImplicitAs(i32) { + extend impl as ImplicitAs(i32) { fn Convert[self: Self]() -> i32 { return 42; } } } diff --git a/explorer/testdata/struct/equality.carbon b/explorer/testdata/struct/equality.carbon index fc5d81a52fa1..24247bf5615b 100644 --- a/explorer/testdata/struct/equality.carbon +++ b/explorer/testdata/struct/equality.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; // TODO: Implement this with some kind of reflection? -external impl {.x: i32, .y: i32} as EqWith(Self) { +impl {.x: i32, .y: i32} as EqWith(Self) { fn Equal[self: Self](other: Self) -> bool { return self.x == other.x and self.y == other.y; } diff --git a/explorer/testdata/struct/equality_false.carbon b/explorer/testdata/struct/equality_false.carbon index 536fb7f16c10..e08969a7de47 100644 --- a/explorer/testdata/struct/equality_false.carbon +++ b/explorer/testdata/struct/equality_false.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; // TODO: Implement this with some kind of reflection? -external impl {.x: i32, .y: i32} as EqWith(Self) { +impl {.x: i32, .y: i32} as EqWith(Self) { fn Equal[self: Self](other: Self) -> bool { return self.x == other.x and self.y == other.y; } diff --git a/explorer/testdata/struct/fail_equality_type.carbon b/explorer/testdata/struct/fail_equality_type.carbon index 6d9e4c050a75..8e5514e31611 100644 --- a/explorer/testdata/struct/fail_equality_type.carbon +++ b/explorer/testdata/struct/fail_equality_type.carbon @@ -7,7 +7,7 @@ package ExplorerTest api; // TODO: Implement this with some kind of reflection? -external impl {.x: i32, .y: i32} as EqWith(Self) { +impl {.x: i32, .y: i32} as EqWith(Self) { fn Equal[self: Self](other: Self) -> bool { return self.x == other.x and self.y == other.y; } diff --git a/explorer/testdata/struct/field_convertible_to_type.carbon b/explorer/testdata/struct/field_convertible_to_type.carbon index 22752cd3c5e1..eff5ba92c4ab 100644 --- a/explorer/testdata/struct/field_convertible_to_type.carbon +++ b/explorer/testdata/struct/field_convertible_to_type.carbon @@ -8,7 +8,7 @@ package ExplorerTest api; class TypeLike { - impl as ImplicitAs(type) { + extend impl as ImplicitAs(type) { fn Convert[self: Self]() -> type { return i32; } } fn Make() -> Self { return {}; } diff --git a/explorer/testdata/template/fail_name_lookup.carbon b/explorer/testdata/template/fail_name_lookup.carbon index 5a02bb3c4605..4aa5e88eb820 100644 --- a/explorer/testdata/template/fail_name_lookup.carbon +++ b/explorer/testdata/template/fail_name_lookup.carbon @@ -25,13 +25,13 @@ class ClassWithInternalF { fn F[self: Self]() { Print("ClassWithInternalF.F"); } } -external impl ClassWithInternalF as HasF { +impl ClassWithInternalF as HasF { fn F[self: Self]() { Print("ClassWithInternalF.(HasF.F)"); } } class ClassWithExternalF {} -external impl ClassWithExternalF as HasF { +impl ClassWithExternalF as HasF { fn F[self: Self]() { Print("ClassWithExternalF.(HasF.F)"); } } diff --git a/explorer/testdata/template/name_lookup.carbon b/explorer/testdata/template/name_lookup.carbon index bf7e27fe4c05..7cae1fe42d40 100644 --- a/explorer/testdata/template/name_lookup.carbon +++ b/explorer/testdata/template/name_lookup.carbon @@ -43,14 +43,14 @@ class MemberF { } class ImplF {} -external impl ImplF as HasF { +impl ImplF as HasF { fn F[self: Self]() { Print("ImplF.(HasF.F)"); } } class BothFs { fn F[self: Self]() { Print("BothFs.F"); } } -external impl BothFs as HasF { +impl BothFs as HasF { fn F[self: Self]() { Print("BothFs.(HasF.F)"); } } diff --git a/explorer/testdata/tuple/convert.carbon b/explorer/testdata/tuple/convert.carbon index 48e6125a20ef..dd2e0d357cc9 100644 --- a/explorer/testdata/tuple/convert.carbon +++ b/explorer/testdata/tuple/convert.carbon @@ -21,10 +21,10 @@ class C { var c: i32; } -external impl A as ImplicitAs(B) { +impl A as ImplicitAs(B) { fn Convert[self: Self]() -> B { return {.b = self.a + 1}; } } -external impl B as As(C) { +impl B as As(C) { fn Convert[self: Self]() -> C { return {.c = self.b + 2}; } } diff --git a/explorer/testdata/tuple/fail_implicit_convert_with_as.carbon b/explorer/testdata/tuple/fail_implicit_convert_with_as.carbon index 7f6167ff7f49..423abc77d999 100644 --- a/explorer/testdata/tuple/fail_implicit_convert_with_as.carbon +++ b/explorer/testdata/tuple/fail_implicit_convert_with_as.carbon @@ -13,7 +13,7 @@ class B { var b: i32; } -external impl A as As(B) { +impl A as As(B) { fn Convert[self: Self]() -> B { return {.b = self.a}; } } diff --git a/explorer/testdata/unformed/fail_base_access.carbon b/explorer/testdata/unformed/fail_base_access.carbon index 13e2ca3405f7..abd6a2d8fed0 100644 --- a/explorer/testdata/unformed/fail_base_access.carbon +++ b/explorer/testdata/unformed/fail_base_access.carbon @@ -10,7 +10,9 @@ base class B { var n: i32; } -class D extends B {} +class D { + extend base: B; +} fn Main() -> i32 { var d: D; diff --git a/explorer/testdata/while/convert_condition.carbon b/explorer/testdata/while/convert_condition.carbon index 5f549868bc45..863722207a25 100644 --- a/explorer/testdata/while/convert_condition.carbon +++ b/explorer/testdata/while/convert_condition.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; class LazyNe { var v1: i32; var v2: i32; - impl as ImplicitAs(bool) { + extend impl as ImplicitAs(bool) { fn Convert[self: Self]() -> bool { return self.v1 != self.v2; }