Start adding ImportRefUsed, removing older copy behavior. (#3657)

Builds on #3656.

Under the prior "lazy" model, we had been planning to copy instructions.
Under the current "unused+used" model, we're restricting that to
constants. I'm trimming back some of the ResolveIfImportRefUnused logic
because it was more appropriate for the former model.

Right now, I'm adding ImportRefUsed direct creation in import.cpp for
namespaces. I think I'll need to do something similar in
RseolveIfImportRefUnused... I'm still trying to think about how to
manage type information there (which needs to come in as an import
reference itself, and probably have some amount of deduplication before
forming a TypeId). So ImportRefUnused lacks a type because I'm hesitant
to aggressively load it, whereas ImportRefUsed should *always* have a
type but it's just an error while I think things through.

For reference, ImportRefUnused and ImportRefUsed are mainly split in
order to track the boolean "used" without making fundamental
modifications to Inst for bit packing (this effectively instead packs a
bit into InstKind). AnyImportRef currently excludes the type because
it's mainly for diagnostic printing at the moment. It could end up with
a TypeId that would end up Invalid for ImportRefUnused, though it could
also be that the TypeId is only accessed when using ImportRefUsed
explicitly.
This commit is contained in:
Jon Ross-Perkins
2024-01-26 17:26:15 +00:00
committed by GitHub
parent adad286b74
commit c1a894fca7
20 changed files with 129 additions and 126 deletions
+11 -30
View File
@@ -221,46 +221,26 @@ auto Context::AddNameToLookup(SemIR::NameId name_id, SemIR::InstId target_id)
auto Context::ResolveIfImportRefUnused(SemIR::InstId inst_id) -> void {
auto inst = insts().Get(inst_id);
auto lazy_inst = inst.TryAs<SemIR::ImportRefUnused>();
if (!lazy_inst) {
auto unused_inst = inst.TryAs<SemIR::ImportRefUnused>();
if (!unused_inst) {
return;
}
const SemIR::File& import_ir = *cross_ref_irs().Get(lazy_inst->ir_id);
auto import_inst = import_ir.insts().Get(lazy_inst->inst_id);
const SemIR::File& import_ir = *cross_ref_irs().Get(unused_inst->ir_id);
auto import_inst = import_ir.insts().Get(unused_inst->inst_id);
switch (import_inst.kind()) {
case SemIR::InstKind::FunctionDecl: {
// TODO: Fill this in better.
auto function_id =
functions().Add({.name_id = SemIR::NameId::Invalid,
.enclosing_scope_id = SemIR::NameScopeId::Invalid,
.decl_id = inst_id,
.implicit_param_refs_id = SemIR::InstBlockId::Empty,
.param_refs_id = SemIR::InstBlockId::Empty,
.return_type_id = SemIR::TypeId::Invalid,
.return_slot_id = SemIR::InstId::Invalid});
ReplaceInstBeforeConstantUse(
inst_id,
// TODO: For diagnostic purposes, we should provide some form of
// location for the function.
{Parse::NodeId::Invalid,
SemIR::FunctionDecl{GetBuiltinType(SemIR::BuiltinKind::FunctionType),
function_id}});
constant_values().Set(inst_id,
SemIR::ConstantId::ForTemplateConstant(inst_id));
break;
}
default:
// TODO: We need more type support. For now we inject an arbitrary
// invalid node that's unrelated to the underlying value. The TODO
// diagnostic is used since this section shouldn't typically be able to
// error.
TODO(Parse::NodeId::Invalid,
(llvm::Twine("TODO: support ") + import_inst.kind().name()).str());
(llvm::Twine("TODO: ResolveIfImportRefUnused for ") +
import_inst.kind().name())
.str());
ReplaceInstBeforeConstantUse(
inst_id, {Parse::NodeId::Invalid,
SemIR::VarStorage{SemIR::TypeId::Error,
SemIR::NameId::PackageNamespace}});
inst_id,
{SemIR::ImportRefUsed{SemIR::TypeId::Error, unused_inst->ir_id,
unused_inst->inst_id}});
break;
}
}
@@ -970,6 +950,7 @@ class TypeCompleter {
case SemIR::InterfaceDecl::Kind:
case SemIR::IntLiteral::Kind:
case SemIR::ImportRefUnused::Kind:
case SemIR::ImportRefUsed::Kind:
case SemIR::NameRef::Kind:
case SemIR::Namespace::Kind:
case SemIR::Param::Kind: