We were passing a SpecificInterfaceId which just makes code have to do a
lookup to get the actual SpecificInterface. The caller already has the
SpecificInterface, so plumb that around.
SpecificInterfaceId really only exists when we need to stick a
SpecificInterface into an instruction as an operand.
The existing `GetCoreInterface` has linear-time complexity and adds more
than the search criteria to the `CoreInterfaceCache`. Adding a new field
to `Interface` changes this operation when building packages other than
`Core`, as this should only be set for the core library.
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.
This delays the conversion of `query_self_const_id` until the actual
witness creation, mainly so that users of `BuildCustomWitness` don't
need to do extra work to ensure `GetFacetAsType` logic is
shared/applied. This is coming up for destroy logic.
We're going to want to track `Destroy` and some other interfaces in ways
similar to what the C++ logic wants. Rather than having both do their
own comparisons with similar values, this tries to centralize logic.
Note the prior
`context.identifiers().Get(interface.name_id.AsIdentifierId())` is also
obsolete due to #6486, this is just replacing it in a single swoop and
avoiding string comparisons as a consequence.
When performing impl lookup for `Core.Copy` for a C++ class type, look
for a copy constructor. If we find one, synthesize an impl witness that
calls the constructor.
This adds initial support for impl lookup to delegate to the C++ interop
logic for queries involving C++ types. For now, we don't implement the
rules from #6166 that compare a synthesized type structure for the C++
impl against the best Carbon type structure, but the framework for
building that support is established here.
Currently there is no caching of the lookup here, and we build unique
`ImplWitnessTable`s for each lookup, which leads to each impl lookup
producing a distinct facet value. This results in some errors in generic
contexts; this will be addressed in follow-up changes. This PR aims only
to support the non-generic case.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>