Improve CanDestroyType to handle remaining cases (#6943)

This is only fixing the decision about *whether* to produce a witness.
Implementation of the witness is still a TODO, though where a body is
generated, it should also precisely reflect where one _needs_ to be
generated.

Note the tests:

- toolchain/lower/testdata/function/generic/import_core_witness.carbon
- toolchain/lower/testdata/function/generic/import_unused_def.carbon

These tests can probably be produced _without_ Core.Destroy, but I found
the essence of them while trying to build //examples with Core.Destroy
and a simpler minimization wasn't striking me.

Assisted-by: Google Antigravity with Gemini

---------

Co-authored-by: jonmeow <jperkins@google.com>
This commit is contained in:
Jon Ross-Perkins
2026-04-02 22:54:58 +00:00
committed by GitHub
co-authored by jonmeow
parent 1fa7a64cd4
commit 9266ced4e3
212 changed files with 11376 additions and 4978 deletions
+13 -2
View File
@@ -760,12 +760,16 @@ auto FileContext::GetOrCreateLLVMFunction(
// TODO: For an imported inline function, consider generating an
// `available_externally` definition.
auto linkage = specific_id.has_value() ? llvm::Function::LinkOnceODRLinkage
: llvm::Function::ExternalLinkage;
auto linkage = llvm::Function::ExternalLinkage;
if (function_id == sem_ir().global_ctor_id()) {
// The global constructor name would collide with global constructors for
// other files in the same package, so use an internal linkage symbol.
linkage = llvm::Function::InternalLinkage;
} else if (specific_id.has_value()) {
// Specific functions are allowed to be duplicated across files.
// TODO: CoreWitness should have the same behavior; see its use of
// WeakODRLinkage in BuildFunctionDefinition.
linkage = llvm::Function::LinkOnceODRLinkage;
}
auto* llvm_function = llvm::Function::Create(function_type_info.type, linkage,
@@ -912,6 +916,13 @@ auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id,
"Attempting to emit definition of inexact function: {0}",
*function_info->llvm_function);
// TODO: Build CoreWitness functions when they're called instead of when
// they're defined. That should allow LinkOnceODRLinkage.
if (declaration_function.special_function_kind ==
SemIR::Function::SpecialFunctionKind::CoreWitness) {
function_info->llvm_function->setLinkage(llvm::Function::WeakODRLinkage);
}
const auto& body_block_ids = definition_function.body_block_ids;
CARBON_DCHECK(!body_block_ids.empty(),
"No function body blocks found during lowering.");