mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
Determining that a type has trivial destruction requires checking whether all of its subobjects have trivial destruction and whether its type has a custom witness for `Destroy.Op`. This isn't possible when `Destroy` is the custodian for `Destroy.Op` and `SubobjectDestroy.Op`, so we need to make `SubobjectDestroy` its own interface. `Destroy.SelfDestruct` becomes a standalone function because it depends on `SubobjectDestroy` and `Destroy` being implemented, and is also responsible for generating any custom witnesses for both interfaces. Making `SelfDestruct` an interface was experimented with, but this required a blanket impl that caused issues for facet types. `Destroy` depends on `SubobjectDestroy` to be implemented. We'd ideally use `require impls SubobjectDestroy`, but it isn't complete yet, and it also causes problems when `Destroy` is implemented inside the class definition. We work around this by temporarily renaming the `Destroy` interface to `DestroyImpl`, and introducing a constraint called `Destroy` so that user code doesn't need to write `Core.SubobjectDestroy & Core.Destroy`.
73 lines
3.5 KiB
C++
73 lines
3.5 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#ifndef CARBON_TOOLCHAIN_CHECK_CUSTOM_WITNESS_H_
|
|
#define CARBON_TOOLCHAIN_CHECK_CUSTOM_WITNESS_H_
|
|
|
|
#include "toolchain/check/context.h"
|
|
#include "toolchain/sem_ir/builtin_function_kind.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
// Builds a witness that the given type implements the given interface,
|
|
// populating it with the specified set of values. Returns a corresponding
|
|
// lookup result. Produces a diagnostic and returns `None` if the specified
|
|
// values aren't suitable for the interface.
|
|
auto BuildCustomWitness(Context& context, SemIR::LocId loc_id,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterface query_specific_interface,
|
|
llvm::ArrayRef<SemIR::InstId> values) -> SemIR::InstId;
|
|
|
|
// Builds a witness that the given type is copyable via a primitive copy.
|
|
auto BuildPrimitiveCopyWitness(
|
|
Context& context, SemIR::LocId loc_id,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId;
|
|
|
|
// Returns a manufactured operator function.
|
|
// `param_types` contains the parameter types. The first element of
|
|
// `param_types` is treated as the `self` type, and any subsequent elements
|
|
// are treated as the types of the remaining explicit parameters.
|
|
// The `interface_id` is the interface containing the `op_name` function, which
|
|
// should be an interface in Core.
|
|
auto MakeBuiltinOperatorFunction(Context& context, SemIR::LocId loc_id,
|
|
llvm::ArrayRef<SemIR::TypeId> param_types,
|
|
SemIR::TypeId return_type_id,
|
|
CoreIdentifier op_name,
|
|
SemIR::BuiltinFunctionKind builtin_kind,
|
|
SemIR::InterfaceId interface_id)
|
|
-> SemIR::InstId;
|
|
|
|
// Builds a witness that the given type is trivially destroyable.
|
|
auto BuildTrivialSubobjectDestroyWitness(
|
|
Context& context, SemIR::LocId loc_id,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId;
|
|
|
|
// Given an interface, returns the corresponding enum if it's covered by
|
|
// `CoreInterface`, or `Unknown` if it's some other interface.
|
|
auto GetCoreInterface(Context& context, SemIR::InterfaceId interface_id)
|
|
-> SemIR::CoreInterface;
|
|
|
|
// Maps a `CoreInterface` to its `CoreIdentifier` equivalent.
|
|
auto AsCoreIdentifier(SemIR::CoreInterface core_interface) -> CoreIdentifier;
|
|
|
|
// Returns a witness for a `CoreInterface` `CustomWitness`. A return value of
|
|
// `None` indicates a non-final witness should be produced, while `std::nullopt`
|
|
// indicates the query is final and no witness can be produced.
|
|
//
|
|
// If `build_witness` is false, this function always returns `None` as the
|
|
// witness, whether it would be final or not. It is used to indicate the
|
|
// presence of such a witness without adding instructions for it.
|
|
auto LookupCustomWitness(Context& context, SemIR::LocId loc_id,
|
|
SemIR::CoreInterface core_interface,
|
|
SemIR::ConstantId query_self_const_id,
|
|
SemIR::SpecificInterface query_specific_interface,
|
|
bool build_witness) -> std::optional<SemIR::InstId>;
|
|
|
|
} // namespace Carbon::Check
|
|
|
|
#endif // CARBON_TOOLCHAIN_CHECK_CUSTOM_WITNESS_H_
|