Add semantics for struct type and value literals. (#2709)

This handles the basics of type and value for structs. Structurally, these look like parameters and arguments (respectively) because expressions/generics may result in multiple IR nodes being generated.

Because `{}` needs to be cast to a type for storage, I'm also adding some validation that's not specific to `{}`, e.g. that `1` shouldn't be valid as a type for storage (previously, nothing errored for that).

This adds more stringification of types, particularly literals, because they come up in value errors now.

ImplicitAs is the result of me mulling whether I'm taking the right approach on type conversions. I think it needs to return a value so that if the implicit cast rewrites the value, the result is accessible to the caller. I may reorient the current TryTypeConversion logic to be more based on the ImplicitAs logic.
This commit is contained in:
Jon Ross-Perkins
2023-03-30 10:15:11 -07:00
committed by GitHub
parent 33f26bd37b
commit 2eef8c751b
32 changed files with 1200 additions and 206 deletions
+19
View File
@@ -128,6 +128,23 @@ auto SemanticsIR::StringifyNodeImpl(llvm::raw_ostream& out,
auto node = GetNode(node_id);
switch (node.kind()) {
case SemanticsNodeKind::StructType: {
out << "{";
auto refs = GetNodeBlock(node.GetAsStructType().second);
llvm::ListSeparator sep;
for (const auto& ref_id : refs) {
out << sep;
// TODO: Bound recursion depth or remove recursive step.
StringifyNodeImpl(out, ref_id);
}
out << "}";
break;
}
case SemanticsNodeKind::StructTypeField: {
out << "." << GetString(node.GetAsStructTypeField()) << ": ";
StringifyNodeImpl(out, node.type_id());
break;
}
case SemanticsNodeKind::Assign:
case SemanticsNodeKind::BinaryOperatorAdd:
case SemanticsNodeKind::BindName:
@@ -142,6 +159,8 @@ auto SemanticsIR::StringifyNodeImpl(llvm::raw_ostream& out,
case SemanticsNodeKind::Return:
case SemanticsNodeKind::ReturnExpression:
case SemanticsNodeKind::StringLiteral:
case SemanticsNodeKind::StructValue:
case SemanticsNodeKind::StubReference:
case SemanticsNodeKind::VarStorage:
// We don't need to handle stringification for nodes that don't show up in
// errors, but make it clear what's going on so that it's clearer when