mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:50:13 +01:00
Pursuant to recent decisions on #6124, switch `Destroy` to use a `CustomWitness` for its implementation. Right now this is manufacturing no-op implementation functions on each lookup, which obviously isn't ideal but is intended as a first pass. I'm mostly trying to find the right balance between updating the approach to reflect new decisions, while still breaking apart work in a way. The `CoreInterface` logic is intended to build on `CoreIdentifier` support. We have a number of additional interfaces that require specialized logic, and that'll extend pretty far with C++ interop, so it seemed easiest to have a generic function for it. That's what's replacing the logic inside C++ interop that was doing string comparisons (which could have already been moved to `CoreIdentifier`, I just missed it in my first pass). This adds `CustomWitness` support because the `Destroy` witnesses can be imported cross-file. `CustomWitness` was previously only used for C++ types, which don't yet support import, which is why that wasn't previously an issue. The addition of `query_specific_interface_id` is similarly needed in order to get correct sorting of witness blocks when imported. This PR also removes builtin constraint logic (note this is in a separate commit to help review; it's not a separate PR because it's difficult to split apart without tests breaking). This had been made generic with the expectation that destroy, copy, move, and conversions would all need related support. Under the new decision, we are not going to do blanket impls and will instead just manufacture a `CustomWitness` for everything. A lot of SemIR fingerprints change, but that's probably because the addition of `Destroy` on core classes is yielding structural changes.
92 lines
4.0 KiB
C++
92 lines
4.0 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_IMPL_H_
|
|
#define CARBON_TOOLCHAIN_CHECK_IMPL_H_
|
|
|
|
#include "toolchain/check/context.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
struct RedeclaredImpl {
|
|
// The previous Impl which the query Impl is redeclaring.
|
|
SemIR::ImplId prev_impl_id;
|
|
};
|
|
struct NewImpl {
|
|
// The lookup bucket for the query Impl where it should be added once an
|
|
// ImplId is known.
|
|
SemIR::ImplStore::LookupBucketRef lookup_bucket;
|
|
// Indicates the query Impl is not a redeclaration but an error was diagnosed.
|
|
// The caller should avoid diagnosing more errors in the query impl.
|
|
bool find_had_error;
|
|
};
|
|
|
|
// Finds an existing impl if the `query_impl` is a redeclaration, and returns
|
|
// its `ImplId`. This ensures all (valid) redeclarations share the same
|
|
// `ImplId`. Otherwise, returns the bucket where a new `ImplId` should be added.
|
|
auto FindImplId(Context& context, const SemIR::Impl& query_impl)
|
|
-> std::variant<RedeclaredImpl, NewImpl>;
|
|
|
|
// Adds an impl to the ImplStore, and returns a new `ImplId`.
|
|
//
|
|
// If the impl is modified with `extend` then the parent's scope is extended
|
|
// with it.
|
|
auto AddImpl(Context& context, const SemIR::Impl& impl,
|
|
SemIR::ImplStore::LookupBucketRef lookup_bucket,
|
|
Parse::NodeId extend_node, SemIR::LocId implicit_params_loc_id)
|
|
-> SemIR::ImplId;
|
|
|
|
// Creates and returns an impl witness instruction for an impl declaration.
|
|
//
|
|
// If there are no rewrites into a name of the interface being implemented, a
|
|
// placeholder witness table is created, to be replaced in the impl definition.
|
|
//
|
|
// Adds and returns an `ImplWitness` instruction (created with location set to
|
|
// `loc_id`) that shows the "`Self` type" (from a facet in `impl.self_id`)
|
|
// implements an identified interface (from a facet type in
|
|
// `impl.constraint_id`). This witness reflects the values assigned to
|
|
// associated constant members of that interface by rewrite constraints in the
|
|
// constraint facet type. `self_specific_id` will be the `specific_id` of the
|
|
// resulting witness.
|
|
auto AddImplWitnessForDeclaration(Context& context, SemIR::LocId loc_id,
|
|
const SemIR::Impl& impl,
|
|
SemIR::SpecificId self_specific_id)
|
|
-> SemIR::InstId;
|
|
|
|
// Update `impl`'s witness at the start of a definition.
|
|
auto ImplWitnessStartDefinition(Context& context, SemIR::Impl& impl) -> void;
|
|
|
|
// Adds the function members to the witness for `impl`.
|
|
auto FinishImplWitness(Context& context, const SemIR::Impl& impl_id) -> void;
|
|
|
|
// Sets all unset members of the witness for `impl` to the error instruction and
|
|
// sets the witness id in the `Impl` to an error.
|
|
auto FillImplWitnessWithErrors(Context& context, SemIR::Impl& impl) -> void;
|
|
|
|
// Returns whether the impl is either `final` explicitly, or implicitly due to
|
|
// being concrete.
|
|
auto IsImplEffectivelyFinal(Context& context, const SemIR::Impl& impl) -> bool;
|
|
|
|
// Checks that `impl_function_id` is a valid implementation of the function
|
|
// described in the interface as `interface_function_id`. Returns the value to
|
|
// put into the corresponding slot in the witness table, which can be
|
|
// `ErrorInst::InstId` if the function is not usable.
|
|
auto CheckAssociatedFunctionImplementation(
|
|
Context& context, SemIR::FunctionType interface_function_type,
|
|
SemIR::InstId impl_decl_id, SemIR::TypeId self_type_id,
|
|
SemIR::InstId witness_inst_id, bool defer_thunk_definition)
|
|
-> SemIR::InstId;
|
|
|
|
// Checks that the constraint specified for the impl is valid and identified.
|
|
// Returns the interface that the impl implements. On error, issues a diagnostic
|
|
// and returns `None`.
|
|
auto CheckConstraintIsInterface(Context& context, SemIR::InstId impl_decl_id,
|
|
SemIR::TypeInstId constraint_id)
|
|
-> SemIR::SpecificInterface;
|
|
|
|
} // namespace Carbon::Check
|
|
|
|
#endif // CARBON_TOOLCHAIN_CHECK_IMPL_H_
|