Lower types in the order they were completed. (#3324)

This is a prerequisite for class support, where a class can be
referenced as a type before it becomes complete. For example, given:

```carbon
class A {
  fn F(a: A);

  class B {}
  var b: B;
}

fn A.F(a: A) {}
```

we need to lower `B` before we lower `A`, even though `A` is used as a
type first.

This will also start catching some cases where we don't require a type
to be complete despite using it, as we now only lower types that are
required to be complete.

Remove the poison values for struct and tuple literals. We don't need
those any more, because we never generate references to those literals
as values, and we don't have a type to use for them because we never
require the type of a literal to be complete, only the type of the
entity initialized by the literal, which can be different, for example
when initializing an array from a tuple literal or a class from a struct
literal.

This doesn't affect the output: `llvm::Type` objects that are not
referenced by an LLVM module don't affect the IR for that module, and
the order in which `llvm::Type`s are created doesn't affect anything
either.
This commit is contained in:
Richard Smith
2023-10-23 18:04:01 +00:00
committed by GitHub
parent 5971f80826
commit 85e9642d18
6 changed files with 38 additions and 16 deletions
+8 -6
View File
@@ -31,11 +31,13 @@ FileContext::FileContext(llvm::LLVMContext& llvm_context,
auto FileContext::Run() -> std::unique_ptr<llvm::Module> {
CARBON_CHECK(llvm_module_) << "Run can only be called once.";
// Lower types.
auto types = semantics_ir_->types().array_ref();
types_.resize_for_overwrite(types.size());
for (auto [i, type] : llvm::enumerate(types)) {
types_[i] = BuildType(type.node_id);
// Lower all types that were required to be complete. Note that this may
// leave some entries in `types_` null, if those types were mentioned but not
// used.
types_.resize(semantics_ir_->types().size());
for (auto type_id : semantics_ir_->complete_types()) {
types_[type_id.index] =
BuildType(semantics_ir_->types().Get(type_id).node_id);
}
// Lower function declarations.
@@ -259,7 +261,7 @@ auto FileContext::BuildType(SemIR::NodeId node_id) -> llvm::Type* {
return llvm::StructType::get(*llvm_context_, subtypes);
}
default: {
CARBON_FATAL() << "Cannot use node as type: " << node_id;
CARBON_FATAL() << "Cannot use node as type: " << node_id << " " << node;
}
}
}