diff --git a/common/fuzzing/carbon.proto b/common/fuzzing/carbon.proto index bb4b72a494a2..38eb424c6dde 100644 --- a/common/fuzzing/carbon.proto +++ b/common/fuzzing/carbon.proto @@ -179,6 +179,10 @@ message VarPattern { optional Pattern pattern = 1; } +message AddrPattern { + optional BindingPattern binding_pattern = 1; +} + message Pattern { oneof kind { BindingPattern binding_pattern = 1; @@ -188,6 +192,7 @@ message Pattern { AutoPattern auto_pattern = 5; VarPattern var_pattern = 6; GenericBinding generic_binding = 7; + AddrPattern addr_pattern = 8; } } @@ -286,7 +291,7 @@ message ReturnTerm { message FunctionDeclaration { optional string name = 1; repeated GenericBinding deduced_parameters = 2; - optional BindingPattern me_pattern = 3; + optional Pattern me_pattern = 3; optional TuplePattern param_pattern = 4; optional ReturnTerm return_term = 5; optional BlockStatement body = 6; diff --git a/common/fuzzing/proto_to_carbon.cpp b/common/fuzzing/proto_to_carbon.cpp index 9234fd9fa3df..bd778072a700 100644 --- a/common/fuzzing/proto_to_carbon.cpp +++ b/common/fuzzing/proto_to_carbon.cpp @@ -425,6 +425,11 @@ static auto PatternToCarbon(const Fuzzing::Pattern& pattern, case Fuzzing::Pattern::kGenericBinding: GenericBindingToCarbon(pattern.generic_binding(), out); break; + + case Fuzzing::Pattern::kAddrPattern: + out << "addr "; + BindingPatternToCarbon(pattern.addr_pattern().binding_pattern(), out); + break; } } @@ -598,7 +603,7 @@ static auto DeclarationToCarbon(const Fuzzing::Declaration& declaration, if (function.has_me_pattern()) { // This is a class method. out << sep; - BindingPatternToCarbon(function.me_pattern(), out); + PatternToCarbon(function.me_pattern(), out); } out << "]"; } diff --git a/explorer/ast/ast_rtti.txt b/explorer/ast/ast_rtti.txt index ce3f1619f412..e3f367fcabff 100644 --- a/explorer/ast/ast_rtti.txt +++ b/explorer/ast/ast_rtti.txt @@ -6,6 +6,7 @@ root class AstNode; abstract class Pattern : AstNode; class AutoPattern : Pattern; class VarPattern : Pattern; + class AddrPattern : Pattern; class BindingPattern : Pattern; class GenericBinding : Pattern; class TuplePattern : Pattern; diff --git a/explorer/ast/declaration.cpp b/explorer/ast/declaration.cpp index d6d3ea59ef48..f44a25dd5e0f 100644 --- a/explorer/ast/declaration.cpp +++ b/explorer/ast/declaration.cpp @@ -185,12 +185,13 @@ void ReturnTerm::Print(llvm::raw_ostream& out) const { } } -auto FunctionDeclaration::Create( - Nonnull arena, SourceLocation source_loc, std::string name, - std::vector> deduced_params, - std::optional> me_pattern, - Nonnull param_pattern, ReturnTerm return_term, - std::optional> body) +auto FunctionDeclaration::Create(Nonnull arena, + SourceLocation source_loc, std::string name, + std::vector> deduced_params, + std::optional> me_pattern, + Nonnull param_pattern, + ReturnTerm return_term, + std::optional> body) -> ErrorOr> { std::vector> resolved_params; // Look for the `me` parameter in the `deduced_parameters` @@ -209,6 +210,16 @@ auto FunctionDeclaration::Create( me_pattern = bp; break; } + case AstNodeKind::AddrPattern: { + Nonnull abp = &cast(*param); + Nonnull bp = &cast(abp->binding()); + if (me_pattern.has_value() || bp->name() != "me") { + return CompilationError(source_loc) + << "illegal binding pattern in implicit parameter list"; + } + me_pattern = abp; + break; + } default: return CompilationError(source_loc) << "illegal AST node in implicit parameter list"; diff --git a/explorer/ast/declaration.h b/explorer/ast/declaration.h index fda0f7610bdb..dd3f39b4be55 100644 --- a/explorer/ast/declaration.h +++ b/explorer/ast/declaration.h @@ -104,7 +104,7 @@ class FunctionDeclaration : public Declaration { static auto Create(Nonnull arena, SourceLocation source_loc, std::string name, std::vector> deduced_params, - std::optional> me_pattern, + std::optional> me_pattern, Nonnull param_pattern, ReturnTerm return_term, std::optional> body) @@ -113,7 +113,7 @@ class FunctionDeclaration : public Declaration { // Use `Create()` instead. This is public only so Arena::New() can call it. FunctionDeclaration(SourceLocation source_loc, std::string name, std::vector> deduced_params, - std::optional> me_pattern, + std::optional> me_pattern, Nonnull param_pattern, ReturnTerm return_term, std::optional> body) @@ -139,8 +139,8 @@ class FunctionDeclaration : public Declaration { auto deduced_parameters() -> llvm::ArrayRef> { return deduced_parameters_; } - auto me_pattern() const -> const BindingPattern& { return **me_pattern_; } - auto me_pattern() -> BindingPattern& { return **me_pattern_; } + auto me_pattern() const -> const Pattern& { return **me_pattern_; } + auto me_pattern() -> Pattern& { return **me_pattern_; } auto param_pattern() const -> const TuplePattern& { return *param_pattern_; } auto param_pattern() -> TuplePattern& { return *param_pattern_; } auto return_term() const -> const ReturnTerm& { return return_term_; } @@ -155,7 +155,7 @@ class FunctionDeclaration : public Declaration { private: std::string name_; std::vector> deduced_parameters_; - std::optional> me_pattern_; + std::optional> me_pattern_; Nonnull param_pattern_; ReturnTerm return_term_; std::optional> body_; diff --git a/explorer/ast/expression.h b/explorer/ast/expression.h index 9a61c28f66a7..754195f0f97c 100644 --- a/explorer/ast/expression.h +++ b/explorer/ast/expression.h @@ -168,6 +168,14 @@ class SimpleMemberAccessExpression : public Expression { auto object() const -> const Expression& { return *object_; } auto object() -> Expression& { return *object_; } auto member() const -> const std::string& { return member_; } + // Returns true if the field is a method that has a "me" declaration in an + // AddrPattern. + auto is_field_addr_me_method() const -> bool { + return is_field_addr_me_method_; + } + + // Can only be called once, during typechecking. + void set_is_field_addr_me_method() { is_field_addr_me_method_ = true; } // If `object` has a generic type, returns the `ImplBinding` that // identifies its witness table. Otherwise, returns `std::nullopt`. Should not @@ -186,6 +194,7 @@ class SimpleMemberAccessExpression : public Expression { Nonnull object_; std::string member_; std::optional> impl_; + bool is_field_addr_me_method_ = false; }; // A compound member access expression of the form `object.(path)`. diff --git a/explorer/ast/pattern.cpp b/explorer/ast/pattern.cpp index 610bc86c9144..4be25458b1b8 100644 --- a/explorer/ast/pattern.cpp +++ b/explorer/ast/pattern.cpp @@ -56,6 +56,9 @@ void Pattern::Print(llvm::raw_ostream& out) const { case PatternKind::VarPattern: out << "var" << cast(*this).pattern(); break; + case PatternKind::AddrPattern: + out << "addr" << cast(*this).binding(); + break; } } @@ -87,6 +90,9 @@ void Pattern::PrintID(llvm::raw_ostream& out) const { case PatternKind::VarPattern: out << "var ..."; break; + case PatternKind::AddrPattern: + out << "addr ..."; + break; case PatternKind::ExpressionPattern: out << "..."; break; @@ -112,6 +118,8 @@ auto VisitNestedPatterns(const Pattern& pattern, visitor); case PatternKind::VarPattern: return VisitNestedPatterns(cast(pattern).pattern(), visitor); + case PatternKind::AddrPattern: + return VisitNestedPatterns(cast(pattern).binding(), visitor); case PatternKind::BindingPattern: case PatternKind::AutoPattern: case PatternKind::ExpressionPattern: diff --git a/explorer/ast/pattern.h b/explorer/ast/pattern.h index 9a8bdb0932a6..cd1ef4246fa7 100644 --- a/explorer/ast/pattern.h +++ b/explorer/ast/pattern.h @@ -184,6 +184,23 @@ class BindingPattern : public Pattern { std::optional value_category_; }; +class AddrPattern : public Pattern { + public: + explicit AddrPattern(SourceLocation source_loc, + Nonnull binding) + : Pattern(AstNodeKind::AddrPattern, source_loc), binding_(binding) {} + + static auto classof(const AstNode* node) -> bool { + return InheritsFromAddrPattern(node->kind()); + } + + auto binding() const -> const BindingPattern& { return *binding_; } + auto binding() -> BindingPattern& { return *binding_; } + + private: + Nonnull binding_; +}; + // A pattern that matches a tuple value field-wise. class TuplePattern : public Pattern { public: diff --git a/explorer/fuzzing/ast_to_proto.cpp b/explorer/fuzzing/ast_to_proto.cpp index 8e6dd45acee9..38192704623f 100644 --- a/explorer/fuzzing/ast_to_proto.cpp +++ b/explorer/fuzzing/ast_to_proto.cpp @@ -322,6 +322,10 @@ static auto PatternToProto(const Pattern& pattern) -> Fuzzing::Pattern { *pattern_proto.mutable_var_pattern()->mutable_pattern() = PatternToProto(cast(pattern).pattern()); break; + case PatternKind::AddrPattern: + *pattern_proto.mutable_addr_pattern()->mutable_binding_pattern() = + BindingPatternToProto(cast(pattern).binding()); + break; } return pattern_proto; } @@ -479,8 +483,23 @@ static auto DeclarationToProto(const Declaration& declaration) GenericBindingToProto(*binding); } if (function.is_method()) { - *function_proto->mutable_me_pattern() = - BindingPatternToProto(function.me_pattern()); + switch (function.me_pattern().kind()) { + case PatternKind::AddrPattern: + *function_proto->mutable_me_pattern() = + PatternToProto(cast(function.me_pattern())); + break; + case PatternKind::BindingPattern: + *function_proto->mutable_me_pattern() = + PatternToProto(cast(function.me_pattern())); + break; + default: + // Parser shouldn't allow me_pattern to be anything other than + // AddrPattern or BindingPattern + CARBON_FATAL() << "me_pattern in method declaration can be either " + "AddrPattern or BindingPattern. Actual pattern: " + << function.me_pattern(); + break; + } } *function_proto->mutable_param_pattern() = TuplePatternToProto(function.param_pattern()); diff --git a/explorer/fuzzing/fuzzer_corpus/886a1cbc0a58fed099ca0dc0d9da01ff9c0d0a75.textproto b/explorer/fuzzing/fuzzer_corpus/017a765e283355ded618ed95de5da4e3f2dd4b52.textproto similarity index 96% rename from explorer/fuzzing/fuzzer_corpus/886a1cbc0a58fed099ca0dc0d9da01ff9c0d0a75.textproto rename to explorer/fuzzing/fuzzer_corpus/017a765e283355ded618ed95de5da4e3f2dd4b52.textproto index f33c41d254a3..4de48decfd4f 100644 --- a/explorer/fuzzing/fuzzer_corpus/886a1cbc0a58fed099ca0dc0d9da01ff9c0d0a75.textproto +++ b/explorer/fuzzing/fuzzer_corpus/017a765e283355ded618ed95de5da4e3f2dd4b52.textproto @@ -10,12 +10,14 @@ compilation_unit { function { name: "Add" me_pattern { - name: "me" - type { - expression_pattern { - expression { - identifier { - name: "Self" + binding_pattern { + name: "me" + type { + expression_pattern { + expression { + identifier { + name: "Self" + } } } } @@ -51,12 +53,14 @@ compilation_unit { function { name: "Mul" me_pattern { - name: "me" - type { - expression_pattern { - expression { - identifier { - name: "Self" + binding_pattern { + name: "me" + type { + expression_pattern { + expression { + identifier { + name: "Self" + } } } } @@ -113,6 +117,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -122,6 +127,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -172,6 +178,7 @@ compilation_unit { function { name: "Mul" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -181,6 +188,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -284,6 +292,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -294,6 +303,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -325,6 +335,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -335,6 +346,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -366,6 +378,7 @@ compilation_unit { function { name: "Hold" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -376,6 +389,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -528,6 +542,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -538,6 +553,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -635,6 +651,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -645,6 +662,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -731,6 +749,7 @@ compilation_unit { function { name: "Hold" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -741,6 +760,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/93dcb9eeaeeff3b36f8201ae4f1ad5893bb39aa8.textproto b/explorer/fuzzing/fuzzer_corpus/0ee3d72e3cab1b0907f04f35b2d33fb946ab32c9.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/93dcb9eeaeeff3b36f8201ae4f1ad5893bb39aa8.textproto rename to explorer/fuzzing/fuzzer_corpus/0ee3d72e3cab1b0907f04f35b2d33fb946ab32c9.textproto index 8ba9ae578ebe..1e1fb7b6af62 100644 --- a/explorer/fuzzing/fuzzer_corpus/93dcb9eeaeeff3b36f8201ae4f1ad5893bb39aa8.textproto +++ b/explorer/fuzzing/fuzzer_corpus/0ee3d72e3cab1b0907f04f35b2d33fb946ab32c9.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -66,6 +68,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -76,6 +79,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -241,6 +245,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -263,6 +268,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -384,6 +390,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -406,6 +413,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/d27c6d16e838d3a2fb3e829f92718ea93271d45a.textproto b/explorer/fuzzing/fuzzer_corpus/1844089b39db6518836420fcb6a5d37b3e99424f.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/d27c6d16e838d3a2fb3e829f92718ea93271d45a.textproto rename to explorer/fuzzing/fuzzer_corpus/1844089b39db6518836420fcb6a5d37b3e99424f.textproto index 120810b399d6..d8618786223a 100644 --- a/explorer/fuzzing/fuzzer_corpus/d27c6d16e838d3a2fb3e829f92718ea93271d45a.textproto +++ b/explorer/fuzzing/fuzzer_corpus/1844089b39db6518836420fcb6a5d37b3e99424f.textproto @@ -10,6 +10,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -20,6 +21,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -51,6 +53,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -61,6 +64,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -146,6 +150,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -156,6 +161,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -253,6 +259,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -263,6 +270,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/a8047c2f828519a1384aade7624c73d912acd0a0.textproto b/explorer/fuzzing/fuzzer_corpus/2caf42dcf02bff184fa653bf36054b9d83704e30.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/a8047c2f828519a1384aade7624c73d912acd0a0.textproto rename to explorer/fuzzing/fuzzer_corpus/2caf42dcf02bff184fa653bf36054b9d83704e30.textproto index eb2d47603879..2c7b0163df84 100644 --- a/explorer/fuzzing/fuzzer_corpus/a8047c2f828519a1384aade7624c73d912acd0a0.textproto +++ b/explorer/fuzzing/fuzzer_corpus/2caf42dcf02bff184fa653bf36054b9d83704e30.textproto @@ -10,6 +10,7 @@ compilation_unit { function { name: "Op" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -20,6 +21,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -121,6 +123,7 @@ compilation_unit { function { name: "Op" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -131,6 +134,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/3dc8675eb42820ac93e26afbc4af62d157382861.textproto b/explorer/fuzzing/fuzzer_corpus/32e0eb929035d7c53b3d8566ac48ef0c3b82b32e.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/3dc8675eb42820ac93e26afbc4af62d157382861.textproto rename to explorer/fuzzing/fuzzer_corpus/32e0eb929035d7c53b3d8566ac48ef0c3b82b32e.textproto index 94a00ba896d0..97189db61713 100644 --- a/explorer/fuzzing/fuzzer_corpus/3dc8675eb42820ac93e26afbc4af62d157382861.textproto +++ b/explorer/fuzzing/fuzzer_corpus/32e0eb929035d7c53b3d8566ac48ef0c3b82b32e.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -161,6 +163,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -170,6 +173,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -315,6 +319,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -325,6 +330,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/cc5f0c26bf337000aa697c93880d18f0d9668b13.textproto b/explorer/fuzzing/fuzzer_corpus/5357de7edef4e3bff993192d9538493ae80f5fa8.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/cc5f0c26bf337000aa697c93880d18f0d9668b13.textproto rename to explorer/fuzzing/fuzzer_corpus/5357de7edef4e3bff993192d9538493ae80f5fa8.textproto index b8f1a0ec3ca3..36344b9b2eb5 100644 --- a/explorer/fuzzing/fuzzer_corpus/cc5f0c26bf337000aa697c93880d18f0d9668b13.textproto +++ b/explorer/fuzzing/fuzzer_corpus/5357de7edef4e3bff993192d9538493ae80f5fa8.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -158,6 +160,7 @@ compilation_unit { function { name: "Clone" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -181,6 +184,7 @@ compilation_unit { } } } + } } param_pattern { } @@ -247,6 +251,7 @@ compilation_unit { function { name: "SumXY" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -270,6 +275,7 @@ compilation_unit { } } } + } } param_pattern { } @@ -409,6 +415,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -418,6 +425,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/79551d0f40545d4aa5e988baa9ec1e946f91e601.textproto b/explorer/fuzzing/fuzzer_corpus/5e4bce73c210e45269126773f257d95d4d269072.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/79551d0f40545d4aa5e988baa9ec1e946f91e601.textproto rename to explorer/fuzzing/fuzzer_corpus/5e4bce73c210e45269126773f257d95d4d269072.textproto index 50b49f126bc7..e9aa35dfc447 100644 --- a/explorer/fuzzing/fuzzer_corpus/79551d0f40545d4aa5e988baa9ec1e946f91e601.textproto +++ b/explorer/fuzzing/fuzzer_corpus/5e4bce73c210e45269126773f257d95d4d269072.textproto @@ -10,6 +10,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -20,6 +21,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -51,6 +53,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -61,6 +64,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -148,6 +152,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -158,6 +163,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -255,6 +261,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -265,6 +272,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/e4cdfa4f32f0adc18ed39f6a9a483835db596ee5.textproto b/explorer/fuzzing/fuzzer_corpus/63979179f0b4279dbf7a98a3a7b9837393d43e8a.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/e4cdfa4f32f0adc18ed39f6a9a483835db596ee5.textproto rename to explorer/fuzzing/fuzzer_corpus/63979179f0b4279dbf7a98a3a7b9837393d43e8a.textproto index 496b6b50175d..adec5eb19b21 100644 --- a/explorer/fuzzing/fuzzer_corpus/e4cdfa4f32f0adc18ed39f6a9a483835db596ee5.textproto +++ b/explorer/fuzzing/fuzzer_corpus/63979179f0b4279dbf7a98a3a7b9837393d43e8a.textproto @@ -65,6 +65,7 @@ compilation_unit { function { name: "GetX" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -75,6 +76,7 @@ compilation_unit { } } } + } } param_pattern { } diff --git a/explorer/fuzzing/fuzzer_corpus/f0c1f0eaa05127e95e5d9b167051b84b2fa54359.textproto b/explorer/fuzzing/fuzzer_corpus/6c86299b17c54466628587a48c2ec0e9d3029fc7.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/f0c1f0eaa05127e95e5d9b167051b84b2fa54359.textproto rename to explorer/fuzzing/fuzzer_corpus/6c86299b17c54466628587a48c2ec0e9d3029fc7.textproto index b250e2a71d1a..5f5a0d1e2f80 100644 --- a/explorer/fuzzing/fuzzer_corpus/f0c1f0eaa05127e95e5d9b167051b84b2fa54359.textproto +++ b/explorer/fuzzing/fuzzer_corpus/6c86299b17c54466628587a48c2ec0e9d3029fc7.textproto @@ -10,6 +10,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -20,6 +21,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -51,6 +53,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -61,6 +64,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -146,6 +150,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -156,6 +161,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -253,6 +259,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -263,6 +270,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -399,6 +407,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -409,6 +418,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -526,6 +536,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -536,6 +547,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/d6f13d6e870f2cde1ac1985bd386bbb22ec19f1a.textproto b/explorer/fuzzing/fuzzer_corpus/6f589265e1e503d2e01043d6a332026d1693095e.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/d6f13d6e870f2cde1ac1985bd386bbb22ec19f1a.textproto rename to explorer/fuzzing/fuzzer_corpus/6f589265e1e503d2e01043d6a332026d1693095e.textproto index 3fe53ff88c43..d8c3f5bd4f70 100644 --- a/explorer/fuzzing/fuzzer_corpus/d6f13d6e870f2cde1ac1985bd386bbb22ec19f1a.textproto +++ b/explorer/fuzzing/fuzzer_corpus/6f589265e1e503d2e01043d6a332026d1693095e.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -66,6 +68,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -76,6 +79,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -202,6 +206,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -212,6 +217,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -309,6 +315,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -319,6 +326,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/53c90be68e61d528ae738d538007572079edecfb.textproto b/explorer/fuzzing/fuzzer_corpus/72624c04b293dcee7ecc0129b6e196195ca84332.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/53c90be68e61d528ae738d538007572079edecfb.textproto rename to explorer/fuzzing/fuzzer_corpus/72624c04b293dcee7ecc0129b6e196195ca84332.textproto index 21ff4078ebe4..d475e844bb21 100644 --- a/explorer/fuzzing/fuzzer_corpus/53c90be68e61d528ae738d538007572079edecfb.textproto +++ b/explorer/fuzzing/fuzzer_corpus/72624c04b293dcee7ecc0129b6e196195ca84332.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -241,6 +243,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -250,6 +253,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/f0791c1c35ad07c87e3b12ad58bdfd3757fa7397.textproto b/explorer/fuzzing/fuzzer_corpus/7b7e24319e8f63e6c3e99f8cbc81da7e9e47390a.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/f0791c1c35ad07c87e3b12ad58bdfd3757fa7397.textproto rename to explorer/fuzzing/fuzzer_corpus/7b7e24319e8f63e6c3e99f8cbc81da7e9e47390a.textproto index a370ca824f65..e13d1cf4d475 100644 --- a/explorer/fuzzing/fuzzer_corpus/f0791c1c35ad07c87e3b12ad58bdfd3757fa7397.textproto +++ b/explorer/fuzzing/fuzzer_corpus/7b7e24319e8f63e6c3e99f8cbc81da7e9e47390a.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -66,6 +68,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -76,6 +79,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -202,6 +206,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -212,6 +217,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -309,6 +315,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -319,6 +326,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/defec684307f53851236f5f0cd91353e44b522e8.textproto b/explorer/fuzzing/fuzzer_corpus/81b5d416277f5b28d98ac9b175f73389d9857655.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/defec684307f53851236f5f0cd91353e44b522e8.textproto rename to explorer/fuzzing/fuzzer_corpus/81b5d416277f5b28d98ac9b175f73389d9857655.textproto index 07422d8a86bf..d52266788357 100644 --- a/explorer/fuzzing/fuzzer_corpus/defec684307f53851236f5f0cd91353e44b522e8.textproto +++ b/explorer/fuzzing/fuzzer_corpus/81b5d416277f5b28d98ac9b175f73389d9857655.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -66,6 +68,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -76,6 +79,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -229,6 +233,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -239,6 +244,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -336,6 +342,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -346,6 +353,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/f2f794705121fc76bfb94de7a7507becbc6ad10a.textproto b/explorer/fuzzing/fuzzer_corpus/8fa92df904a230ee4b0ecf1362170a2551aec98b.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/f2f794705121fc76bfb94de7a7507becbc6ad10a.textproto rename to explorer/fuzzing/fuzzer_corpus/8fa92df904a230ee4b0ecf1362170a2551aec98b.textproto index 81110e7a4905..0abb7fb7c2f9 100644 --- a/explorer/fuzzing/fuzzer_corpus/f2f794705121fc76bfb94de7a7507becbc6ad10a.textproto +++ b/explorer/fuzzing/fuzzer_corpus/8fa92df904a230ee4b0ecf1362170a2551aec98b.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -66,6 +68,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -76,6 +79,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -202,6 +206,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -212,6 +217,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -309,6 +315,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -319,6 +326,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/6d89c0f37960217a1aed0d102cb41057306ba2ad.textproto b/explorer/fuzzing/fuzzer_corpus/9a79849f37e616453382dcd0ff273c080d3b4f7f.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/6d89c0f37960217a1aed0d102cb41057306ba2ad.textproto rename to explorer/fuzzing/fuzzer_corpus/9a79849f37e616453382dcd0ff273c080d3b4f7f.textproto index 9fbe28687c09..2cdbe10db4a3 100644 --- a/explorer/fuzzing/fuzzer_corpus/6d89c0f37960217a1aed0d102cb41057306ba2ad.textproto +++ b/explorer/fuzzing/fuzzer_corpus/9a79849f37e616453382dcd0ff273c080d3b4f7f.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -161,6 +163,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -170,6 +173,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -328,6 +332,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -351,6 +356,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/605b1f6a1f0b6806f5da052014a56403a3691024.textproto b/explorer/fuzzing/fuzzer_corpus/9bb0b055035cb4965aa9432c34bdb1be0f8c3b80.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/605b1f6a1f0b6806f5da052014a56403a3691024.textproto rename to explorer/fuzzing/fuzzer_corpus/9bb0b055035cb4965aa9432c34bdb1be0f8c3b80.textproto index 29700da725ef..ec0a2dd28ec8 100644 --- a/explorer/fuzzing/fuzzer_corpus/605b1f6a1f0b6806f5da052014a56403a3691024.textproto +++ b/explorer/fuzzing/fuzzer_corpus/9bb0b055035cb4965aa9432c34bdb1be0f8c3b80.textproto @@ -10,6 +10,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -20,6 +21,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -51,6 +53,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -61,6 +64,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -146,6 +150,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -156,6 +161,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -253,6 +259,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -263,6 +270,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/bade121153d00cc778f13538192f224f6d215d55.textproto b/explorer/fuzzing/fuzzer_corpus/a04fd176eb32a1a2500bf298f4f5deb37b9fa406.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/bade121153d00cc778f13538192f224f6d215d55.textproto rename to explorer/fuzzing/fuzzer_corpus/a04fd176eb32a1a2500bf298f4f5deb37b9fa406.textproto index f68acf6c579e..986e6f18d715 100644 --- a/explorer/fuzzing/fuzzer_corpus/bade121153d00cc778f13538192f224f6d215d55.textproto +++ b/explorer/fuzzing/fuzzer_corpus/a04fd176eb32a1a2500bf298f4f5deb37b9fa406.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -390,6 +392,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -399,6 +402,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/dc02f2222475e43c33fb8d9713ade9cc67f52edc.textproto b/explorer/fuzzing/fuzzer_corpus/a88508d94032d0429d1cba11c1df90deb142c155.textproto similarity index 94% rename from explorer/fuzzing/fuzzer_corpus/dc02f2222475e43c33fb8d9713ade9cc67f52edc.textproto rename to explorer/fuzzing/fuzzer_corpus/a88508d94032d0429d1cba11c1df90deb142c155.textproto index cd1f6b6e59fd..5634f6b14f11 100644 --- a/explorer/fuzzing/fuzzer_corpus/dc02f2222475e43c33fb8d9713ade9cc67f52edc.textproto +++ b/explorer/fuzzing/fuzzer_corpus/a88508d94032d0429d1cba11c1df90deb142c155.textproto @@ -51,12 +51,14 @@ compilation_unit { function { name: "GetX" me_pattern { - name: "me" - type { - expression_pattern { - expression { - identifier { - name: "Point" + binding_pattern { + name: "me" + type { + expression_pattern { + expression { + identifier { + name: "Point" + } } } } diff --git a/explorer/fuzzing/fuzzer_corpus/d76dbdfb3092a4e7d4368223e4b4d7208a4d2805.textproto b/explorer/fuzzing/fuzzer_corpus/d44b1b3f6ff018d0829e0d73f551d0144b39e638.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/d76dbdfb3092a4e7d4368223e4b4d7208a4d2805.textproto rename to explorer/fuzzing/fuzzer_corpus/d44b1b3f6ff018d0829e0d73f551d0144b39e638.textproto index c7ac859063b1..29e8b2dde783 100644 --- a/explorer/fuzzing/fuzzer_corpus/d76dbdfb3092a4e7d4368223e4b4d7208a4d2805.textproto +++ b/explorer/fuzzing/fuzzer_corpus/d44b1b3f6ff018d0829e0d73f551d0144b39e638.textproto @@ -10,6 +10,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -20,6 +21,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -51,6 +53,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -61,6 +64,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -148,6 +152,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -158,6 +163,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -255,6 +261,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -265,6 +272,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/854bb3af6f9f1f6a0e31a7103720864316abf3bc.textproto b/explorer/fuzzing/fuzzer_corpus/f0249ef671686916199dbce1467d741102a68717.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/854bb3af6f9f1f6a0e31a7103720864316abf3bc.textproto rename to explorer/fuzzing/fuzzer_corpus/f0249ef671686916199dbce1467d741102a68717.textproto index 07196c33ca44..6d5544f5b956 100644 --- a/explorer/fuzzing/fuzzer_corpus/854bb3af6f9f1f6a0e31a7103720864316abf3bc.textproto +++ b/explorer/fuzzing/fuzzer_corpus/f0249ef671686916199dbce1467d741102a68717.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -161,6 +163,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -170,6 +173,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -328,6 +332,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -351,6 +356,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/dba92dce40512177d3bf143b088da7eccc8fa214.textproto b/explorer/fuzzing/fuzzer_corpus/f986b7976441ebd0928d8f4d13c6ff2be6a05f50.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/dba92dce40512177d3bf143b088da7eccc8fa214.textproto rename to explorer/fuzzing/fuzzer_corpus/f986b7976441ebd0928d8f4d13c6ff2be6a05f50.textproto index 74c2c4d028e9..9c474643a6a1 100644 --- a/explorer/fuzzing/fuzzer_corpus/dba92dce40512177d3bf143b088da7eccc8fa214.textproto +++ b/explorer/fuzzing/fuzzer_corpus/f986b7976441ebd0928d8f4d13c6ff2be6a05f50.textproto @@ -10,6 +10,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -20,6 +21,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -51,6 +53,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -61,6 +64,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -146,6 +150,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -156,6 +161,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -253,6 +259,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -263,6 +270,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/ea5f89368e963868e6ff283238f3d2811e828b2f.textproto b/explorer/fuzzing/fuzzer_corpus/fc5f5e4f348579cedbecae8dccafc9f9dae68237.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/ea5f89368e963868e6ff283238f3d2811e828b2f.textproto rename to explorer/fuzzing/fuzzer_corpus/fc5f5e4f348579cedbecae8dccafc9f9dae68237.textproto index 62264be7a01a..7b789e3a426a 100644 --- a/explorer/fuzzing/fuzzer_corpus/ea5f89368e963868e6ff283238f3d2811e828b2f.textproto +++ b/explorer/fuzzing/fuzzer_corpus/fc5f5e4f348579cedbecae8dccafc9f9dae68237.textproto @@ -78,6 +78,7 @@ compilation_unit { function { name: "GetX" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -101,6 +102,7 @@ compilation_unit { } } } + } } param_pattern { } diff --git a/explorer/fuzzing/fuzzer_corpus/da3113c74912fae50b4d30bf6351ad30985b4695.textproto b/explorer/fuzzing/fuzzer_corpus/fda984fd483f47ca29fd55b54173f77ef690b4ee.textproto similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/da3113c74912fae50b4d30bf6351ad30985b4695.textproto rename to explorer/fuzzing/fuzzer_corpus/fda984fd483f47ca29fd55b54173f77ef690b4ee.textproto index c79930799820..68f73f1db476 100644 --- a/explorer/fuzzing/fuzzer_corpus/da3113c74912fae50b4d30bf6351ad30985b4695.textproto +++ b/explorer/fuzzing/fuzzer_corpus/fda984fd483f47ca29fd55b54173f77ef690b4ee.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -451,6 +453,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -460,6 +463,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/fuzzing/fuzzer_corpus/5ae7e1ab2593f54e01e0f1f2b9cacc06701c17a8.textproto b/explorer/fuzzing/fuzzer_corpus/fe3c5db046e0dae74603f2c43ed1af68eea9a6ae.textproto similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/5ae7e1ab2593f54e01e0f1f2b9cacc06701c17a8.textproto rename to explorer/fuzzing/fuzzer_corpus/fe3c5db046e0dae74603f2c43ed1af68eea9a6ae.textproto index 219aad545403..9bc4df435ada 100644 --- a/explorer/fuzzing/fuzzer_corpus/5ae7e1ab2593f54e01e0f1f2b9cacc06701c17a8.textproto +++ b/explorer/fuzzing/fuzzer_corpus/fe3c5db046e0dae74603f2c43ed1af68eea9a6ae.textproto @@ -25,6 +25,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -35,6 +36,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -66,6 +68,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -76,6 +79,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -215,6 +219,7 @@ compilation_unit { function { name: "Add" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -225,6 +230,7 @@ compilation_unit { } } } + } } param_pattern { fields { @@ -322,6 +328,7 @@ compilation_unit { function { name: "Scale" me_pattern { + binding_pattern { name: "me" type { expression_pattern { @@ -332,6 +339,7 @@ compilation_unit { } } } + } } param_pattern { fields { diff --git a/explorer/interpreter/heap.cpp b/explorer/interpreter/heap.cpp index 6883582c6fde..7dd1b71cd4f2 100644 --- a/explorer/interpreter/heap.cpp +++ b/explorer/interpreter/heap.cpp @@ -24,8 +24,8 @@ auto Heap::AllocateValue(Nonnull v) -> AllocationId { auto Heap::Read(const Address& a, SourceLocation source_loc) const -> ErrorOr> { CARBON_RETURN_IF_ERROR(this->CheckAlive(a.allocation_, source_loc)); - return values_[a.allocation_.index_]->GetMember(arena_, a.field_path_, - source_loc); + Nonnull value = values_[a.allocation_.index_]; + return value->GetMember(arena_, a.field_path_, source_loc, value); } auto Heap::Write(const Address& a, Nonnull v, diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index a2c96e89eed7..bc96e9351972 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -209,8 +209,8 @@ auto PatternMatch(Nonnull p, Nonnull v, SourceLocation source_loc, std::optional> bindings, BindingMap& generic_args, - std::optional> trace_stream) - -> bool { + std::optional> trace_stream, + Nonnull arena) -> bool { if (trace_stream) { **trace_stream << "match pattern " << *p << "\nwith value " << *v << "\n"; } @@ -223,6 +223,14 @@ auto PatternMatch(Nonnull p, Nonnull v, } return true; } + case Value::Kind::AddrValue: { + const auto& addr = cast(*p); + CARBON_CHECK(v->kind() == Value::Kind::LValue); + const auto& lvalue = cast(*v); + return PatternMatch( + &addr.pattern(), arena->New(lvalue.address()), + source_loc, bindings, generic_args, trace_stream, arena); + } case Value::Kind::VariableType: { const auto& var_type = cast(*p); generic_args[&var_type.binding()] = v; @@ -236,8 +244,8 @@ auto PatternMatch(Nonnull p, Nonnull v, CARBON_CHECK(p_tup.elements().size() == v_tup.elements().size()); for (size_t i = 0; i < p_tup.elements().size(); ++i) { if (!PatternMatch(p_tup.elements()[i], v_tup.elements()[i], - source_loc, bindings, generic_args, - trace_stream)) { + source_loc, bindings, generic_args, trace_stream, + arena)) { return false; } } // for @@ -255,7 +263,7 @@ auto PatternMatch(Nonnull p, Nonnull v, v_struct.elements()[i].name); if (!PatternMatch(p_struct.elements()[i].value, v_struct.elements()[i].value, source_loc, bindings, - generic_args, trace_stream)) { + generic_args, trace_stream, arena)) { return false; } } @@ -271,7 +279,7 @@ auto PatternMatch(Nonnull p, Nonnull v, return false; } return PatternMatch(&p_alt.argument(), &v_alt.argument(), source_loc, - bindings, generic_args, trace_stream); + bindings, generic_args, trace_stream, arena); } default: CARBON_FATAL() << "expected a choice alternative in pattern, not " @@ -283,11 +291,12 @@ auto PatternMatch(Nonnull p, Nonnull v, const auto& p_fn = cast(*p); const auto& v_fn = cast(*v); if (!PatternMatch(&p_fn.parameters(), &v_fn.parameters(), source_loc, - bindings, generic_args, trace_stream)) { + bindings, generic_args, trace_stream, arena)) { return false; } if (!PatternMatch(&p_fn.return_type(), &v_fn.return_type(), - source_loc, bindings, generic_args, trace_stream)) { + source_loc, bindings, generic_args, trace_stream, + arena)) { return false; } return true; @@ -503,6 +512,7 @@ auto Interpreter::Convert(Nonnull value, case Value::Kind::ContinuationType: case Value::Kind::VariableType: case Value::Kind::BindingPlaceholderValue: + case Value::Kind::AddrValue: case Value::Kind::AlternativeConstructorValue: case Value::Kind::ContinuationValue: case Value::Kind::StringType: @@ -637,9 +647,9 @@ auto Interpreter::CallFunction(const CallExpression& call, RuntimeScope function_scope(&heap_); BindingMap generic_args; - CARBON_CHECK(PatternMatch(&function.param_pattern().value(), - converted_args, call.source_loc(), - &function_scope, generic_args, trace_stream_)); + CARBON_CHECK(PatternMatch( + &function.param_pattern().value(), converted_args, call.source_loc(), + &function_scope, generic_args, trace_stream_, this->arena_)); CARBON_CHECK(function.body().has_value()) << "Calling a function that's missing a body"; return todo_.Spawn(std::make_unique(*function.body()), @@ -657,10 +667,10 @@ auto Interpreter::CallFunction(const CallExpression& call, BindingMap generic_args; CARBON_CHECK(PatternMatch(&method.me_pattern().value(), m.receiver(), call.source_loc(), &method_scope, generic_args, - trace_stream_)); + trace_stream_, this->arena_)); CARBON_CHECK(PatternMatch(&method.param_pattern().value(), converted_args, call.source_loc(), &method_scope, generic_args, - trace_stream_)); + trace_stream_, this->arena_)); // Bring the class type arguments into scope. for (const auto& [bind, val] : m.type_args()) { method_scope.Initialize(bind, val); @@ -681,7 +691,8 @@ auto Interpreter::CallFunction(const CallExpression& call, RuntimeScope params_scope(&heap_); BindingMap generic_args; CARBON_CHECK(PatternMatch(&name.params().value(), arg, call.source_loc(), - ¶ms_scope, generic_args, trace_stream_)); + ¶ms_scope, generic_args, trace_stream_, + this->arena_)); switch (decl.kind()) { case DeclarationKind::ClassDeclaration: { switch (phase()) { @@ -804,9 +815,17 @@ auto Interpreter::StepExp() -> ErrorOr { case ExpressionKind::SimpleMemberAccessExpression: { const auto& access = cast(exp); if (act.pos() == 0) { - return todo_.Spawn( - std::make_unique(&access.object())); + // { { e.f :: C, E, F} :: S, H} + // -> { { e :: [].f :: C, E, F} :: S, H} + if (access.is_field_addr_me_method()) { + return todo_.Spawn(std::make_unique(&access.object())); + } else { + return todo_.Spawn( + std::make_unique(&access.object())); + } } else { + // { { v :: [].f :: C, E, F} :: S, H} + // -> { { v_f :: C, E, F} : S, H} if (const auto* member_name_type = dyn_cast(&access.static_type())) { // The result is a member name, such as in `Type.field_name`. Form a @@ -842,10 +861,18 @@ auto Interpreter::StepExp() -> ErrorOr { witness = cast(witness_value); } FieldPath::Component member(access.member(), witness); + const Value* aggregate; + if (const auto* lvalue = dyn_cast(act.results()[0])) { + CARBON_ASSIGN_OR_RETURN( + aggregate, + this->heap_.Read(lvalue->address(), exp.source_loc())); + } else { + aggregate = act.results()[0]; + } CARBON_ASSIGN_OR_RETURN( Nonnull member_value, - act.results()[0]->GetMember(arena_, FieldPath(member), - exp.source_loc())); + aggregate->GetMember(arena_, FieldPath(member), exp.source_loc(), + act.results()[0])); return todo_.FinishAction(member_value); } } @@ -892,9 +919,9 @@ auto Interpreter::StepExp() -> ErrorOr { exp.source_loc())); } FieldPath::Component field(access.member().name(), witness); - CARBON_ASSIGN_OR_RETURN( - Nonnull member, - object->GetMember(arena_, FieldPath(field), exp.source_loc())); + CARBON_ASSIGN_OR_RETURN(Nonnull member, + object->GetMember(arena_, FieldPath(field), + exp.source_loc(), object)); return todo_.FinishAction(member); } } @@ -1148,6 +1175,14 @@ auto Interpreter::StepPattern() -> ErrorOr { } else { return todo_.FinishAction(act.results()[0]); } + case PatternKind::AddrPattern: + const auto& addr = cast(pattern); + if (act.pos() == 0) { + return todo_.Spawn(std::make_unique(&addr.binding())); + } else { + return todo_.FinishAction(arena_->New(act.results()[0])); + } + break; } } @@ -1181,7 +1216,7 @@ auto Interpreter::StepStmt() -> ErrorOr { Convert(act.results()[0], &c.pattern().static_type(), stmt.source_loc())); if (PatternMatch(&c.pattern().value(), val, stmt.source_loc(), &matches, - generic_args, trace_stream_)) { + generic_args, trace_stream_, this->arena_)) { // Ensure we don't process any more clauses. act.set_pos(match_stmt.clauses().size() + 1); todo_.MergeScope(std::move(matches)); @@ -1262,7 +1297,7 @@ auto Interpreter::StepStmt() -> ErrorOr { RuntimeScope matches(&heap_); BindingMap generic_args; CARBON_CHECK(PatternMatch(p, v, stmt.source_loc(), &matches, - generic_args, trace_stream_)) + generic_args, trace_stream_, this->arena_)) << stmt.source_loc() << ": internal error in variable definition, match failed"; todo_.MergeScope(std::move(matches)); diff --git a/explorer/interpreter/interpreter.h b/explorer/interpreter/interpreter.h index f05bdaa36ddb..beb714e4ac89 100644 --- a/explorer/interpreter/interpreter.h +++ b/explorer/interpreter/interpreter.h @@ -53,7 +53,8 @@ auto InterpPattern(Nonnull p, Nonnull arena, [[nodiscard]] auto PatternMatch( Nonnull p, Nonnull v, SourceLocation source_loc, std::optional> bindings, BindingMap& generic_args, - std::optional> trace_stream) -> bool; + std::optional> trace_stream, + Nonnull arena) -> bool; } // namespace Carbon diff --git a/explorer/interpreter/resolve_names.cpp b/explorer/interpreter/resolve_names.cpp index 1524fe6a8849..49c90c906ae7 100644 --- a/explorer/interpreter/resolve_names.cpp +++ b/explorer/interpreter/resolve_names.cpp @@ -242,6 +242,10 @@ static auto ResolveNames(Pattern& pattern, StaticScope& enclosing_scope) CARBON_RETURN_IF_ERROR( ResolveNames(cast(pattern).pattern(), enclosing_scope)); break; + case PatternKind::AddrPattern: + CARBON_RETURN_IF_ERROR( + ResolveNames(cast(pattern).binding(), enclosing_scope)); + break; } return Success(); } diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index 6c8d759f7928..d8f15136ac34 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -77,6 +77,7 @@ static auto IsTypeOfType(Nonnull value) -> bool { case Value::Kind::NominalClassValue: case Value::Kind::AlternativeValue: case Value::Kind::BindingPlaceholderValue: + case Value::Kind::AddrValue: case Value::Kind::AlternativeConstructorValue: case Value::Kind::ContinuationValue: case Value::Kind::StringValue: @@ -129,6 +130,7 @@ static auto IsType(Nonnull value, bool concrete = false) -> bool { case Value::Kind::NominalClassValue: case Value::Kind::AlternativeValue: case Value::Kind::BindingPlaceholderValue: + case Value::Kind::AddrValue: case Value::Kind::AlternativeConstructorValue: case Value::Kind::ContinuationValue: case Value::Kind::StringValue: @@ -145,7 +147,6 @@ static auto IsType(Nonnull value, bool concrete = false) -> bool { case Value::Kind::BoolType: case Value::Kind::TypeType: case Value::Kind::FunctionType: - case Value::Kind::PointerType: case Value::Kind::StructType: case Value::Kind::NominalClassType: case Value::Kind::InterfaceType: @@ -169,6 +170,9 @@ static auto IsType(Nonnull value, bool concrete = false) -> bool { } return true; } + case Value::Kind::PointerType: { + return IsType(&cast(*value).type(), concrete); + } } } @@ -438,7 +442,7 @@ auto TypeChecker::GetBuiltinInterfaceType(SourceLocation source_loc, if (has_arguments) { TupleValue args(interface.arguments); if (!PatternMatch(&iface_decl->params().value()->value(), &args, source_loc, - std::nullopt, bindings, trace_stream_)) { + std::nullopt, bindings, trace_stream_, this->arena_)) { return bad_builtin(); } } @@ -703,6 +707,7 @@ auto TypeChecker::ArgumentDeduction( case Value::Kind::NominalClassValue: case Value::Kind::AlternativeValue: case Value::Kind::BindingPlaceholderValue: + case Value::Kind::AddrValue: case Value::Kind::AlternativeConstructorValue: case Value::Kind::ContinuationValue: case Value::Kind::StringValue: { @@ -814,6 +819,7 @@ auto TypeChecker::Substitute( case Value::Kind::NominalClassValue: case Value::Kind::AlternativeValue: case Value::Kind::BindingPlaceholderValue: + case Value::Kind::AddrValue: case Value::Kind::AlternativeConstructorValue: case Value::Kind::ContinuationValue: case Value::Kind::StringValue: @@ -1141,9 +1147,24 @@ auto TypeChecker::TypeCheckExp(Nonnull e, case DeclarationKind::VariableDeclaration: access.set_value_category(access.object().value_category()); break; - case DeclarationKind::FunctionDeclaration: + case DeclarationKind::FunctionDeclaration: { + auto func_decl = cast(*member); + if (func_decl->is_method() && func_decl->me_pattern().kind() == + PatternKind::AddrPattern) { + access.set_is_field_addr_me_method(); + CARBON_RETURN_IF_ERROR( + ExpectType(e->source_loc(), "method access", + &func_decl->me_pattern().static_type(), + &access.object().static_type(), &impl_scope)); + if (access.object().value_category() != ValueCategory::Var) { + return CompilationError(e->source_loc()) + << "method " << access.member() + << " requires its receiver to be an lvalue"; + } + } access.set_value_category(ValueCategory::Let); break; + } default: CARBON_FATAL() << "member " << access.member() << " is not a field or method"; @@ -1512,8 +1533,9 @@ auto TypeChecker::TypeCheckExp(Nonnull e, op.set_value_category(ValueCategory::Var); return Success(); case Operator::Ptr: - CARBON_RETURN_IF_ERROR(ExpectExactType( - e->source_loc(), "*", arena_->New(), ts[0])); + CARBON_RETURN_IF_ERROR(ExpectType(e->source_loc(), "*", + arena_->New(), ts[0], + &impl_scope)); op.set_static_type(arena_->New()); op.set_value_category(ValueCategory::Let); return Success(); @@ -1805,7 +1827,8 @@ auto TypeChecker::TypeCheckPattern( } else { BindingMap generic_args; if (!PatternMatch(type, *expected, binding.type().source_loc(), - std::nullopt, generic_args, trace_stream_)) { + std::nullopt, generic_args, trace_stream_, + this->arena_)) { return CompilationError(binding.type().source_loc()) << "Type pattern '" << *type << "' does not match actual type '" << **expected << "'"; @@ -1921,17 +1944,40 @@ auto TypeChecker::TypeCheckPattern( SetValue(p, expr_value); return Success(); } - case PatternKind::VarPattern: - auto& let_var_pattern = cast(*p); + case PatternKind::VarPattern: { + auto& var_pattern = cast(*p); - CARBON_RETURN_IF_ERROR( - TypeCheckPattern(&let_var_pattern.pattern(), expected, impl_scope, - let_var_pattern.value_category())); - let_var_pattern.set_static_type(&let_var_pattern.pattern().static_type()); + CARBON_RETURN_IF_ERROR(TypeCheckPattern(&var_pattern.pattern(), expected, + impl_scope, + var_pattern.value_category())); + var_pattern.set_static_type(&var_pattern.pattern().static_type()); CARBON_ASSIGN_OR_RETURN( Nonnull pattern_value, - InterpPattern(&let_var_pattern, arena_, trace_stream_)); - SetValue(&let_var_pattern, pattern_value); + InterpPattern(&var_pattern, arena_, trace_stream_)); + SetValue(&var_pattern, pattern_value); + return Success(); + } + case PatternKind::AddrPattern: + std::optional> expected_ptr; + auto& addr_pattern = cast(*p); + if (expected) { + expected_ptr = arena_->New(expected.value()); + } + CARBON_RETURN_IF_ERROR(TypeCheckPattern(&addr_pattern.binding(), + expected_ptr, impl_scope, + enclosing_value_category)); + + if (auto* inner_binding_type = + dyn_cast(&addr_pattern.binding().static_type())) { + addr_pattern.set_static_type(&inner_binding_type->type()); + } else { + return CompilationError(addr_pattern.source_loc()) + << "Type associated with addr must be a pointer type."; + } + CARBON_ASSIGN_OR_RETURN( + Nonnull pattern_value, + InterpPattern(&addr_pattern, arena_, trace_stream_)); + SetValue(&addr_pattern, pattern_value); return Success(); } } @@ -2605,6 +2651,7 @@ static bool IsValidTypeForAliasTarget(Nonnull type) { case Value::Kind::ParameterizedEntityName: case Value::Kind::MemberName: case Value::Kind::BindingPlaceholderValue: + case Value::Kind::AddrValue: case Value::Kind::AlternativeConstructorValue: case Value::Kind::ContinuationValue: case Value::Kind::StringValue: diff --git a/explorer/interpreter/value.cpp b/explorer/interpreter/value.cpp index fe28ac3a6dd3..107f0fbb380c 100644 --- a/explorer/interpreter/value.cpp +++ b/explorer/interpreter/value.cpp @@ -31,7 +31,7 @@ auto StructValue::FindField(const std::string& name) const static auto GetMember(Nonnull arena, Nonnull v, const FieldPath::Component& field, - SourceLocation source_loc) + SourceLocation source_loc, Nonnull me_value) -> ErrorOr> { const std::string& f = field.name(); @@ -93,7 +93,7 @@ static auto GetMember(Nonnull arena, Nonnull v, } else if ((*func)->declaration().is_method()) { // Found a method. Turn it into a bound method. const FunctionValue& m = cast(**func); - return arena->New(&m.declaration(), &object, + return arena->New(&m.declaration(), me_value, class_type.type_args(), class_type.witnesses()); } else { @@ -131,12 +131,13 @@ static auto GetMember(Nonnull arena, Nonnull v, } auto Value::GetMember(Nonnull arena, const FieldPath& path, - SourceLocation source_loc) const + SourceLocation source_loc, + Nonnull me_value) const -> ErrorOr> { Nonnull value(this); for (const FieldPath::Component& field : path.components_) { - CARBON_ASSIGN_OR_RETURN(value, - Carbon::GetMember(arena, value, field, source_loc)); + CARBON_ASSIGN_OR_RETURN( + value, Carbon::GetMember(arena, value, field, source_loc, me_value)); } return value; } @@ -216,6 +217,11 @@ void Value::Print(llvm::raw_ostream& out) const { out << ">"; break; } + case Value::Kind::AddrValue: { + const auto& addr = cast(*this); + out << "Addr<" << addr.pattern() << ">"; + break; + } case Value::Kind::AlternativeValue: { const auto& alt = cast(*this); out << "alt " << alt.choice_name() << "." << alt.alt_name() << " " @@ -569,6 +575,7 @@ auto TypeEqual(Nonnull t1, Nonnull t2) -> bool { case Value::Kind::PointerValue: case Value::Kind::LValue: case Value::Kind::BindingPlaceholderValue: + case Value::Kind::AddrValue: case Value::Kind::ContinuationValue: case Value::Kind::ParameterizedEntityName: case Value::Kind::MemberName: @@ -679,6 +686,7 @@ auto ValueEqual(Nonnull v1, Nonnull v2) -> bool { case Value::Kind::NominalClassValue: case Value::Kind::AlternativeValue: case Value::Kind::BindingPlaceholderValue: + case Value::Kind::AddrValue: case Value::Kind::AlternativeConstructorValue: case Value::Kind::ContinuationValue: case Value::Kind::PointerValue: diff --git a/explorer/interpreter/value.h b/explorer/interpreter/value.h index 97ca4a3df34b..e36116c1854c 100644 --- a/explorer/interpreter/value.h +++ b/explorer/interpreter/value.h @@ -61,6 +61,7 @@ class Value { ParameterizedEntityName, MemberName, BindingPlaceholderValue, + AddrValue, AlternativeConstructorValue, ContinuationValue, // A first-class continuation value. StringType, @@ -80,9 +81,12 @@ class Value { LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); } // Returns the sub-Value specified by `path`, which must be a valid field - // path for *this. + // path for *this. If the sub-Value is a method and its me_pattern is an + // AddrPattern, then pass the LValue representing the receiver as `me_value`, + // otherwise pass `*this`. auto GetMember(Nonnull arena, const FieldPath& path, - SourceLocation source_loc) const + SourceLocation source_loc, + Nonnull me_value) const -> ErrorOr>; // Returns a copy of *this, but with the sub-Value specified by `path` @@ -395,6 +399,22 @@ class BindingPlaceholderValue : public Value { std::optional value_node_; }; +// Value for addr pattern +class AddrValue : public Value { + public: + explicit AddrValue(Nonnull pattern) + : Value(Kind::AddrValue), pattern_(pattern) {} + + static auto classof(const Value* value) -> bool { + return value->kind() == Kind::AddrValue; + } + + auto pattern() const -> const Value& { return *pattern_; } + + private: + Nonnull pattern_; +}; + // The int type. class IntType : public Value { public: diff --git a/explorer/syntax/lexer.lpp b/explorer/syntax/lexer.lpp index a699273fd3e6..06ab8e883f24 100644 --- a/explorer/syntax/lexer.lpp +++ b/explorer/syntax/lexer.lpp @@ -33,6 +33,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception %s AFTER_OPERAND /* table-begin */ +ADDR "addr" ALIAS "alias" AMPERSAND "&" AND "and" @@ -138,6 +139,7 @@ string_literal \"([^\\\"\n\v\f\r]|\\.)*\" %} /* table-begin */ +{ADDR} { return SIMPLE_TOKEN(ADDR); } {ALIAS} { return SIMPLE_TOKEN(ALIAS); } {AMPERSAND} { return SIMPLE_TOKEN(AMPERSAND); } {AND} { return SIMPLE_TOKEN(AND); } diff --git a/explorer/syntax/parser.ypp b/explorer/syntax/parser.ypp index db9fd4f0757b..9aae183544ff 100644 --- a/explorer/syntax/parser.ypp +++ b/explorer/syntax/parser.ypp @@ -142,6 +142,7 @@ %type > if_expression %type > expression %type > generic_binding +%type > deduced_param %type >> deduced_params %type >> impl_deduced_params %type >> deduced_param_list @@ -155,7 +156,7 @@ %type > struct_type_literal_contents %type > tuple %type binding_lhs -%type >> receiver +%type >> receiver %type > variable_declaration %type > paren_expression_base %type > paren_expression_contents @@ -174,6 +175,7 @@ %token // Most tokens have their spelling defined in lexer.lpp. // table-begin + ADDR ALIAS AMPERSAND AND @@ -797,27 +799,22 @@ generic_binding: $$ = arena->New(context.source_loc(), std::move($1), $3); } ; +deduced_param: + generic_binding + { $$ = $1; } +| variable_declaration + { $$ = $1; } +| ADDR variable_declaration + { $$ = arena->New(context.source_loc(), $2); } +; deduced_param_list: // Empty - { $$ = std::vector>(); } -| generic_binding + { $$ = {}; } +| deduced_param + { $$ = {$1}; } +| deduced_param_list COMMA deduced_param { - $$ = std::vector>(); - $$.push_back($1); - } -| deduced_param_list COMMA generic_binding - { - $$ = $1; - $$.push_back($3); - } -| variable_declaration - { - $$ = std::vector>(); - $$.push_back($1); - } -| deduced_param_list COMMA variable_declaration - { - $$ = $1; + $$ = $1; // TODO: can we std::move here? $$.push_back($3); } ; @@ -838,6 +835,8 @@ receiver: { $$ = std::nullopt; } | LEFT_CURLY_BRACE variable_declaration RIGHT_CURLY_BRACE { $$ = $2; } +| LEFT_CURLY_BRACE ADDR variable_declaration RIGHT_CURLY_BRACE + { $$ = arena->New(context.source_loc(), $3); } ; function_declaration: FN identifier deduced_params receiver maybe_empty_tuple_pattern return_term block diff --git a/explorer/testdata/addr/fail-method-let.carbon b/explorer/testdata/addr/fail-method-let.carbon new file mode 100644 index 000000000000..446850436725 --- /dev/null +++ b/explorer/testdata/addr/fail-method-let.carbon @@ -0,0 +1,37 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// RUN: %{not} %{explorer} %s 2>&1 | \ +// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s +// RUN: %{not} %{explorer} --parser_debug --trace_file=- %s 2>&1 | \ +// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s +// AUTOUPDATE: %{explorer} %s +// CHECK: COMPILATION ERROR: {{.*}}/explorer/testdata/addr/fail-method-let.carbon:32: method GetSetX requires its receiver to be an lvalue + +package ExplorerTest api; + +class Point { + + fn Origin() -> Point { + return {.x = 0, .y = 0}; + } + + fn GetSetX[addr me: Point*](x: i32) -> i32 { + var old: auto = (*me).x; + (*me).x = x; + return old; + } + + var x: i32; + var y: i32; +} + +fn Main() -> i32 { + let p: Point = Point.Origin(); + var x: auto = p.GetSetX(42); + if (p.x == 42) { + return x; + } + return 1; +} diff --git a/explorer/testdata/addr/fail-method-me-type.carbon b/explorer/testdata/addr/fail-method-me-type.carbon new file mode 100644 index 000000000000..db906d2c2d54 --- /dev/null +++ b/explorer/testdata/addr/fail-method-me-type.carbon @@ -0,0 +1,41 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// RUN: %{not} %{explorer} %s 2>&1 | \ +// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s +// RUN: %{not} %{explorer} --parser_debug --trace_file=- %s 2>&1 | \ +// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s +// AUTOUPDATE: %{explorer} %s +// CHECK: COMPILATION ERROR: {{.*}}/explorer/testdata/addr/fail-method-me-type.carbon:36: type error in method access: 'class Point' is not implicitly convertible to 'class Shape' + +package ExplorerTest api; + +class Shape { + var x: i32; +} + +class Point { + + fn Origin() -> Point { + return {.x = 0, .y = 0}; + } + + fn GetSetX[addr me: Shape*](x: i32) -> i32 { + var old: auto = (*me).x; + (*me).x = x; + return old; + } + + var x: i32; + var y: i32; +} + +fn Main() -> i32 { + var p: Point = Point.Origin(); + var x: auto = p.GetSetX(42); + if (p.x == 42) { + return x; + } + return 1; +} diff --git a/explorer/testdata/addr/method.carbon b/explorer/testdata/addr/method.carbon new file mode 100644 index 000000000000..c1e70582e070 --- /dev/null +++ b/explorer/testdata/addr/method.carbon @@ -0,0 +1,37 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// RUN: %{explorer} %s 2>&1 | \ +// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s +// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \ +// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s +// AUTOUPDATE: %{explorer} %s +// CHECK: result: 0 + +package ExplorerTest api; + +class Point { + + fn Origin() -> Point { + return {.x = 0, .y = 0}; + } + + fn GetSetX[addr me: Point*](x: i32) -> i32 { + var old: auto = (*me).x; + (*me).x = x; + return old; + } + + var x: i32; + var y: i32; +} + +fn Main() -> i32 { + var p: Point = Point.Origin(); + var x: auto = p.GetSetX(42); + if (p.x == 42) { + return x; + } + return 1; +} diff --git a/explorer/testdata/addr/nested-method.carbon b/explorer/testdata/addr/nested-method.carbon new file mode 100644 index 000000000000..cf35a423246e --- /dev/null +++ b/explorer/testdata/addr/nested-method.carbon @@ -0,0 +1,37 @@ + +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// RUN: %{explorer} %s 2>&1 | \ +// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s +// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \ +// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s +// AUTOUPDATE: %{explorer} %s +// CHECK: result: 0 + +package ExplorerTest api; + +class B { + var x: i32; + + fn GetSetX[addr me: Self*](x: i32) -> i32 { + var oldX: auto = (*me).x; + (*me).x = x; + return oldX; + } +} + +class A { + var b: B; +} + +fn Main() -> i32 { + var b: B = {.x = 0}; + var a: A = {.b = b}; + var x: auto = a.b.GetSetX(42); + if (a.b.x == 42) { + return x; + } + return 1; +} diff --git a/explorer/update_checks.py b/explorer/update_checks.py old mode 100755 new mode 100644