mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Expect parentheses after an alternative only if they were present in its declaration (#2605)
The design of choice types expects the declaration of an alternative to match the usage: if an alternative is declared as `None`, then it should be used as `None` not `None()`, and if it is declared as `None()` then it should be used as `None()` not `None`. Update explorer to match. Also clean up the handling of choice types and alternative values a little in general, by moving away from identifying choice types and alternatives as strings and towards identifying them symbolically. Closes #2422
This commit is contained in:
@@ -195,11 +195,15 @@ static auto GetNamedElement(Nonnull<Arena*> arena, Nonnull<const Value*> v,
|
||||
}
|
||||
case Value::Kind::ChoiceType: {
|
||||
const auto& choice = cast<ChoiceType>(*v);
|
||||
if (!choice.FindAlternative(f)) {
|
||||
auto alt = choice.declaration().FindAlternative(f);
|
||||
if (!alt) {
|
||||
return ProgramError(source_loc)
|
||||
<< "alternative " << f << " not in " << *v;
|
||||
}
|
||||
return arena->New<AlternativeConstructorValue>(f, choice.name());
|
||||
if ((*alt)->signature()) {
|
||||
return arena->New<AlternativeConstructorValue>(&choice, *alt);
|
||||
}
|
||||
return arena->New<AlternativeValue>(&choice, *alt, std::nullopt);
|
||||
}
|
||||
case Value::Kind::NominalClassType: {
|
||||
// Access a class function.
|
||||
@@ -360,7 +364,8 @@ void Value::Print(llvm::raw_ostream& out) const {
|
||||
switch (kind()) {
|
||||
case Value::Kind::AlternativeConstructorValue: {
|
||||
const auto& alt = cast<AlternativeConstructorValue>(*this);
|
||||
out << alt.choice_name() << "." << alt.alt_name();
|
||||
out << alt.choice().declaration().name() << "."
|
||||
<< alt.alternative().name();
|
||||
break;
|
||||
}
|
||||
case Value::Kind::BindingPlaceholderValue: {
|
||||
@@ -381,8 +386,11 @@ void Value::Print(llvm::raw_ostream& out) const {
|
||||
}
|
||||
case Value::Kind::AlternativeValue: {
|
||||
const auto& alt = cast<AlternativeValue>(*this);
|
||||
out << "alt " << alt.choice_name() << "." << alt.alt_name() << " "
|
||||
<< alt.argument();
|
||||
out << alt.choice().declaration().name() << "."
|
||||
<< alt.alternative().name();
|
||||
if (auto arg = alt.argument()) {
|
||||
out << **arg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Value::Kind::StructValue: {
|
||||
@@ -536,6 +544,13 @@ void Value::Print(llvm::raw_ostream& out) const {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Value::Kind::ChoiceType: {
|
||||
const auto& choice_type = cast<ChoiceType>(*this);
|
||||
out << "choice ";
|
||||
PrintNameWithBindings(out, &choice_type.declaration(),
|
||||
choice_type.type_args());
|
||||
break;
|
||||
}
|
||||
case Value::Kind::MixinPseudoType: {
|
||||
const auto& mixin_type = cast<MixinPseudoType>(*this);
|
||||
out << "mixin ";
|
||||
@@ -647,9 +662,6 @@ void Value::Print(llvm::raw_ostream& out) const {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Value::Kind::ChoiceType:
|
||||
out << "choice " << cast<ChoiceType>(*this).name();
|
||||
break;
|
||||
case Value::Kind::VariableType:
|
||||
out << cast<VariableType>(*this).binding().name();
|
||||
break;
|
||||
@@ -1013,6 +1025,17 @@ auto ValueStructurallyEqual(
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Value::Kind::AlternativeValue: {
|
||||
const auto& alt1 = cast<AlternativeValue>(*v1);
|
||||
const auto& alt2 = cast<AlternativeValue>(*v2);
|
||||
if (!TypeEqual(&alt1.choice(), &alt2.choice(), equality_ctx) ||
|
||||
&alt1.alternative() != &alt2.alternative()) {
|
||||
return false;
|
||||
}
|
||||
CARBON_CHECK(alt1.argument().has_value() == alt2.argument().has_value());
|
||||
return !alt1.argument().has_value() ||
|
||||
ValueEqual(*alt1.argument(), *alt2.argument(), equality_ctx);
|
||||
}
|
||||
case Value::Kind::StringValue:
|
||||
return cast<StringValue>(*v1).value() == cast<StringValue>(*v2).value();
|
||||
case Value::Kind::ParameterizedEntityName: {
|
||||
@@ -1059,7 +1082,6 @@ auto ValueStructurallyEqual(
|
||||
case Value::Kind::StaticArrayType:
|
||||
return TypeEqual(v1, v2, equality_ctx);
|
||||
case Value::Kind::NominalClassValue:
|
||||
case Value::Kind::AlternativeValue:
|
||||
case Value::Kind::BindingPlaceholderValue:
|
||||
case Value::Kind::AddrValue:
|
||||
case Value::Kind::AlternativeConstructorValue:
|
||||
@@ -1151,17 +1173,6 @@ auto ConstraintType::VisitEqualValues(
|
||||
return true;
|
||||
}
|
||||
|
||||
auto ChoiceType::FindAlternative(std::string_view name) const
|
||||
-> std::optional<Nonnull<const Value*>> {
|
||||
std::vector<NamedValue> alternatives = declaration_->members();
|
||||
for (const NamedValue& alternative : alternatives) {
|
||||
if (alternative.name == name) {
|
||||
return alternative.value;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto FindFunction(std::string_view name,
|
||||
llvm::ArrayRef<Nonnull<Declaration*>> members)
|
||||
-> std::optional<Nonnull<const FunctionValue*>> {
|
||||
|
||||
Reference in New Issue
Block a user