mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Track witnesses wherever possible (#2263)
Change explorer's handling of witnesses to track them wherever possible. Associated constant support needs witnesses to be available much more pervasively. The main changes here are: - `Substitute` now takes a set of bindings covering both `Value`s for `GenericBinding`s and `Witness`es for `ImplBinding`s, and substitutes both. - Witnesses are now tracked within `ConstraintType`s. The `.Self` type has an `ImplBinding` that self-references from parts of the constraint to other parts of the constraint can use to access the witness for the constraint. - The constraint type for an `impl` and for a `GenericBinding` are now stored in pre-substituted form, with references to the actual constrained type rather than symbolic references to `.Self`. This results in minor changes in diagnostic text. Argument deduction still performs substitutions without remapping witnesses.
This commit is contained in:
@@ -4,11 +4,46 @@
|
||||
|
||||
#include "explorer/ast/bindings.h"
|
||||
|
||||
#include "common/error.h"
|
||||
#include "explorer/ast/impl_binding.h"
|
||||
#include "explorer/ast/pattern.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
void Bindings::Add(Nonnull<const GenericBinding*> binding,
|
||||
Nonnull<const Value*> value,
|
||||
std::optional<Nonnull<const Value*>> witness) {
|
||||
bool added_value = args_.insert({binding, value}).second;
|
||||
CARBON_CHECK(added_value) << "Add of already-existing binding";
|
||||
|
||||
if (witness) {
|
||||
// TODO: Eventually we should check that we have a witness if and only if
|
||||
// the binding has an impl binding.
|
||||
auto impl_binding = binding->impl_binding();
|
||||
CARBON_CHECK(impl_binding) << "Given witness but have no impl binding";
|
||||
bool added_witness = witnesses_.insert({*impl_binding, *witness}).second;
|
||||
CARBON_CHECK(added_witness) << "Add of already-existing binding";
|
||||
}
|
||||
}
|
||||
|
||||
auto Bindings::None() -> Nonnull<const Bindings*> {
|
||||
static Nonnull<const Bindings*> bindings = new Bindings({}, {});
|
||||
static Nonnull<const Bindings*> bindings = new Bindings;
|
||||
return bindings;
|
||||
}
|
||||
|
||||
auto Bindings::SymbolicIdentity(
|
||||
Nonnull<Arena*> arena,
|
||||
llvm::ArrayRef<Nonnull<const GenericBinding*>> bindings)
|
||||
-> Nonnull<const Bindings*> {
|
||||
auto* result = arena->New<Bindings>();
|
||||
for (auto* binding : bindings) {
|
||||
std::optional<Nonnull<const Value*>> witness;
|
||||
if (binding->impl_binding()) {
|
||||
witness = *binding->impl_binding().value()->symbolic_identity();
|
||||
}
|
||||
result->Add(binding, *binding->symbolic_identity(), witness);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
Reference in New Issue
Block a user