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:
Richard Smith
2023-02-14 13:28:52 -08:00
committed by GitHub
parent f7924aa93f
commit 59ff7743c0
18 changed files with 315 additions and 168 deletions
+8 -5
View File
@@ -34,7 +34,7 @@ auto AbstractPattern::discriminator() const -> std::string_view {
}
} else if (const auto* value = value_.dyn_cast<const Value*>()) {
if (const auto* alt = dyn_cast<AlternativeValue>(value)) {
return alt->alt_name();
return alt->alternative().name();
} else if (const auto* bool_val = dyn_cast<BoolValue>(value)) {
return bool_val->value() ? "true" : "false";
}
@@ -47,13 +47,16 @@ auto AbstractPattern::elements_size() const -> int {
if (const auto* tuple_pattern = dyn_cast<TuplePattern>(pattern)) {
return tuple_pattern->fields().size();
} else if (isa<AlternativePattern>(pattern)) {
// Note, AlternativePattern is only used for a pattern with arguments. An
// alternative pattern without arguments is represented as an
// AlternativeValue.
return 1;
}
} else if (const auto* value = value_.dyn_cast<const Value*>()) {
if (const auto* tuple = dyn_cast<TupleValue>(value)) {
return tuple->elements().size();
} else if (const auto* alt = dyn_cast<AlternativeValue>(value)) {
return 1;
return alt->argument() ? 1 : 0;
}
}
return 0;
@@ -78,9 +81,9 @@ void AbstractPattern::AppendElementsTo(
AbstractPattern(tuple->elements()[i], tuple_type->elements()[i]));
}
} else if (const auto* alt = dyn_cast<AlternativeValue>(value)) {
out.push_back(AbstractPattern(
&alt->argument(),
*cast<ChoiceType>(type_)->FindAlternative(alt->alt_name())));
if (auto arg = alt->argument()) {
out.push_back(AbstractPattern(*arg, *alt->alternative().static_type()));
}
}
}
}