diff --git a/explorer/ast/declaration.cpp b/explorer/ast/declaration.cpp index 6c2d0448e27d..c2437d6ba917 100644 --- a/explorer/ast/declaration.cpp +++ b/explorer/ast/declaration.cpp @@ -430,8 +430,8 @@ auto ImplDeclaration::Create(Nonnull arena, SourceLocation source_loc, void AlternativeSignature::Print(llvm::raw_ostream& out) const { out << "alt " << name(); - if (auto sig = signature()) { - out << **signature(); + if (auto params = parameters()) { + out << **params; } } diff --git a/explorer/ast/declaration.h b/explorer/ast/declaration.h index 88cceb31e667..56aad28d1e3a 100644 --- a/explorer/ast/declaration.h +++ b/explorer/ast/declaration.h @@ -468,10 +468,10 @@ class MixDeclaration : public Declaration { class AlternativeSignature : public AstNode { public: AlternativeSignature(SourceLocation source_loc, std::string name, - std::optional> signature) + std::optional> parameters) : AstNode(AstNodeKind::AlternativeSignature, source_loc), name_(std::move(name)), - signature_(signature) {} + parameters_(parameters) {} void Print(llvm::raw_ostream& out) const override; void PrintID(llvm::raw_ostream& out) const override; @@ -481,29 +481,31 @@ class AlternativeSignature : public AstNode { } auto name() const -> const std::string& { return name_; } - auto signature() const -> std::optional> { - return signature_; + auto parameters() const -> std::optional> { + return parameters_; } - auto signature() -> std::optional> { - return signature_; + auto parameters() -> std::optional> { + return parameters_; } - // The static type signature, if any. Cannot be called before type checking. - auto static_type() const -> std::optional> { - return static_type_; + // The static type described by the parameters expression, if any. Cannot be + // called before type checking. This will be nullopt after type checking if + // this alternative does not have a parameter list. + auto parameters_static_type() const -> std::optional> { + return parameters_static_type_; } // Sets the static type of the declared entity. Can only be called once, // during typechecking. - void set_static_type(Nonnull type) { - CARBON_CHECK(!static_type_.has_value()); - static_type_ = type; + void set_parameters_static_type(Nonnull type) { + CARBON_CHECK(!parameters_static_type_.has_value()); + parameters_static_type_ = type; } private: std::string name_; - std::optional> signature_; - std::optional> static_type_; + std::optional> parameters_; + std::optional> parameters_static_type_; }; class ChoiceDeclaration : public Declaration { diff --git a/explorer/fuzzing/ast_to_proto.cpp b/explorer/fuzzing/ast_to_proto.cpp index 2f84f2447563..173b30ade370 100644 --- a/explorer/fuzzing/ast_to_proto.cpp +++ b/explorer/fuzzing/ast_to_proto.cpp @@ -750,9 +750,9 @@ static auto DeclarationToProto(const Declaration& declaration) choice.alternatives()) { auto* alternative_proto = choice_proto->add_alternatives(); alternative_proto->set_name(alternative->name()); - if (auto sig = alternative->signature()) { + if (auto params = alternative->parameters()) { *alternative_proto->mutable_signature() = - TupleLiteralExpressionToProto(**sig); + TupleLiteralExpressionToProto(**params); } } break; diff --git a/explorer/interpreter/pattern_analysis.cpp b/explorer/interpreter/pattern_analysis.cpp index 464df1325dfe..e5501748d7e4 100644 --- a/explorer/interpreter/pattern_analysis.cpp +++ b/explorer/interpreter/pattern_analysis.cpp @@ -82,7 +82,8 @@ void AbstractPattern::AppendElementsTo( } } else if (const auto* alt = dyn_cast(value)) { if (auto arg = alt->argument()) { - out.push_back(AbstractPattern(*arg, *alt->alternative().static_type())); + out.push_back(AbstractPattern( + *arg, *alt->alternative().parameters_static_type())); } } } diff --git a/explorer/interpreter/resolve_names.cpp b/explorer/interpreter/resolve_names.cpp index 095f5f3a133b..657f0ad56292 100644 --- a/explorer/interpreter/resolve_names.cpp +++ b/explorer/interpreter/resolve_names.cpp @@ -792,8 +792,8 @@ auto NameResolver::ResolveNames(Declaration& declaration, // need to check for duplicates. std::set alternative_names; for (Nonnull alternative : choice.alternatives()) { - if (auto sig = alternative->signature()) { - CARBON_RETURN_IF_ERROR(ResolveNames(**sig, choice_scope)); + if (auto params = alternative->parameters()) { + CARBON_RETURN_IF_ERROR(ResolveNames(**params, choice_scope)); } if (!alternative_names.insert(alternative->name()).second) { return ProgramError(alternative->source_loc()) diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index e08b32b908a3..3fb394df4ca0 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -2838,7 +2838,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, // If we find an alternative with no declared signature, we are // constructing an unparameterized alternative value. - if (!(*signature)->static_type()) { + if (!(*signature)->parameters_static_type()) { access.set_member( arena_->New(arena_->New( NamedValue{access.member_name(), &choice}))); @@ -2847,8 +2847,8 @@ auto TypeChecker::TypeCheckExp(Nonnull e, return Success(); } - Nonnull parameter_type = - Substitute(choice.bindings(), *(*signature)->static_type()); + Nonnull parameter_type = Substitute( + choice.bindings(), *(*signature)->parameters_static_type()); Nonnull type = arena_->New(parameter_type, &choice); // TODO: Should there be a Declaration corresponding to each @@ -4073,15 +4073,15 @@ auto TypeChecker::TypeCheckPattern( << "`" << alternative.alternative_name() << "` is not an alternative of " << choice_type; } - if (!(*signature)->static_type()) { + if (!(*signature)->parameters_static_type()) { return ProgramError(alternative.source_loc()) << "alternative `" << choice_type << "." << alternative.alternative_name() << "` does not expect an argument list"; } - Nonnull parameter_type = - Substitute(choice_type.bindings(), *(*signature)->static_type()); + Nonnull parameter_type = Substitute( + choice_type.bindings(), *(*signature)->parameters_static_type()); CARBON_RETURN_IF_ERROR(TypeCheckPattern(&alternative.arguments(), parameter_type, impl_scope, enclosing_value_category)); @@ -5543,10 +5543,10 @@ auto TypeChecker::DeclareChoiceDeclaration(Nonnull choice, } for (Nonnull alternative : choice->alternatives()) { - if (auto signature = alternative->signature()) { + if (auto params = alternative->parameters()) { CARBON_ASSIGN_OR_RETURN( - auto type, TypeCheckTypeExp(*signature, *scope_info.innermost_scope)); - alternative->set_static_type(type); + auto type, TypeCheckTypeExp(*params, *scope_info.innermost_scope)); + alternative->set_parameters_static_type(type); } } diff --git a/explorer/interpreter/value.cpp b/explorer/interpreter/value.cpp index d8555ca2bcd5..95bf51abac4c 100644 --- a/explorer/interpreter/value.cpp +++ b/explorer/interpreter/value.cpp @@ -200,7 +200,7 @@ static auto GetNamedElement(Nonnull arena, Nonnull v, return ProgramError(source_loc) << "alternative " << f << " not in " << *v; } - if ((*alt)->signature()) { + if ((*alt)->parameters()) { return arena->New(&choice, *alt); } return arena->New(&choice, *alt, std::nullopt); diff --git a/explorer/interpreter/value.h b/explorer/interpreter/value.h index a4f0113b94a4..c72c02950bb5 100644 --- a/explorer/interpreter/value.h +++ b/explorer/interpreter/value.h @@ -381,12 +381,23 @@ class NominalClassValue : public Value { Nonnull class_value_ptr_; }; -// Common implementation of alternative values and alternative constructors. -class AlternativeValueBase : public Value { +// An alternative constructor value. +class AlternativeConstructorValue : public Value { public: - AlternativeValueBase(Kind kind, Nonnull choice, - Nonnull alternative) - : Value(kind), choice_(choice), alternative_(alternative) {} + AlternativeConstructorValue(Nonnull choice, + Nonnull alternative) + : Value(Kind::AlternativeConstructorValue), + choice_(choice), + alternative_(alternative) {} + + static auto classof(const Value* value) -> bool { + return value->kind() == Kind::AlternativeConstructorValue; + } + + template + auto Decompose(F f) const { + return f(&choice(), &alternative()); + } auto choice() const -> const ChoiceType& { return *choice_; } auto alternative() const -> const AlternativeSignature& { @@ -398,31 +409,15 @@ class AlternativeValueBase : public Value { Nonnull alternative_; }; -// An alternative constructor value. -class AlternativeConstructorValue : public AlternativeValueBase { - public: - AlternativeConstructorValue(Nonnull choice, - Nonnull alternative) - : AlternativeValueBase(Kind::AlternativeConstructorValue, choice, - alternative) {} - - static auto classof(const Value* value) -> bool { - return value->kind() == Kind::AlternativeConstructorValue; - } - - template - auto Decompose(F f) const { - return f(&choice(), &alternative()); - } -}; - // An alternative value. -class AlternativeValue : public AlternativeValueBase { +class AlternativeValue : public Value { public: AlternativeValue(Nonnull choice, Nonnull alternative, std::optional> argument) - : AlternativeValueBase(Kind::AlternativeValue, choice, alternative), + : Value(Kind::AlternativeValue), + choice_(choice), + alternative_(alternative), argument_(argument) {} static auto classof(const Value* value) -> bool { @@ -434,11 +429,17 @@ class AlternativeValue : public AlternativeValueBase { return f(&choice(), &alternative(), argument_); } + auto choice() const -> const ChoiceType& { return *choice_; } + auto alternative() const -> const AlternativeSignature& { + return *alternative_; + } auto argument() const -> std::optional> { return argument_; } private: + Nonnull choice_; + Nonnull alternative_; std::optional> argument_; };