Files
carbon-lang/toolchain/sem_ir/entity_name.h
T
33110d096c Facet types support rewrite (where .A =...) constraints (#4613)
* Rewrite constraints are stored in a facet type, substituted, imported,
and formatted.
* We now distinguish `.Self` from other symbolic bindings in two ways:
* `.Self` itself now has an invalid compile time binding index (since it
doesn't bind to any of the generic parameters). As a result, we no
longer need to create a generic region in `handle_where.cpp`.
* There is a new phase tracking values that are only symbolic because
they transitively depend on `.Self`. This allows us to give the result
of a `where` expression template phase as long as it doesn't use any
symbolic constants other than `.Self` or other designators.
* `AddConstant` has been removed from `check/context` since it was only
used from `eval`. This meant less plumbing of the phase change.
* Evaluation of `BindSymbolicName` now also performs substitution into
its type.
* Include a bit more information in some diagnostics.
* `StringifyTypeExpr` outputs rewrites, which required adding support
for associated entities as well.
  * Associated entities now have an entity name set when importing.
* Adds tests for some interesting cases with rewrites and uses of
`.Self` mixed with other symbolic constants.

Still to do:
* There is no validation that any particular type satisfies rewrite
constraints.
  * Access to members of a facet type do not see the rewritten values.
* Impls don't recognize whether associated constants have rewrites
setting their values.
  * No support for resolving facet types.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-12-03 22:44:39 +00:00

79 lines
2.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_SEM_IR_ENTITY_NAME_H_
#define CARBON_TOOLCHAIN_SEM_IR_ENTITY_NAME_H_
#include "common/hashing.h"
#include "common/set.h"
#include "toolchain/base/value_store.h"
#include "toolchain/sem_ir/ids.h"
namespace Carbon::SemIR {
struct EntityName : public Printable<EntityName> {
auto Print(llvm::raw_ostream& out) const -> void {
out << "{name: " << name_id << ", parent_scope: " << parent_scope_id
<< ", index: " << bind_index << "}";
}
friend auto CarbonHashtableEq(const EntityName& lhs, const EntityName& rhs)
-> bool {
return std::memcmp(&lhs, &rhs, sizeof(EntityName)) == 0;
}
// The name.
NameId name_id;
// The parent scope.
NameScopeId parent_scope_id;
// The index for a compile-time binding. Invalid for a runtime binding, or
// for a symbolic binding, like `.Self`, that does not correspond to a generic
// parameter (and therefore has no index).
CompileTimeBindIndex bind_index;
};
// Hashing for EntityName. See common/hashing.h.
inline auto CarbonHashValue(const EntityName& value, uint64_t seed)
-> HashCode {
Hasher hasher(seed);
hasher.HashRaw(value);
return static_cast<HashCode>(hasher);
}
// Value store for EntityName. In addition to the regular ValueStore
// functionality, this can provide optional canonical IDs for EntityNames.
struct EntityNameStore : public ValueStore<EntityNameId> {
public:
// Convert an ID to a canonical ID. All calls to this with equivalent
// `EntityName`s will return the same `EntityNameId`.
auto MakeCanonical(EntityNameId id) -> EntityNameId;
private:
class KeyContext;
Set<EntityNameId, /*SmallSize=*/0, KeyContext> canonical_ids_;
};
class EntityNameStore::KeyContext : public TranslatingKeyContext<KeyContext> {
public:
explicit KeyContext(const EntityNameStore* store) : store_(store) {}
// Note that it is safe to return a `const` reference here as the underlying
// object's lifetime is provided by the `store_`.
auto TranslateKey(EntityNameId id) const -> const EntityName& {
return store_->Get(id);
}
private:
const EntityNameStore* store_;
};
inline auto EntityNameStore::MakeCanonical(EntityNameId id) -> EntityNameId {
return canonical_ids_.Insert(id, KeyContext(this)).key();
}
} // namespace Carbon::SemIR
#endif // CARBON_TOOLCHAIN_SEM_IR_ENTITY_NAME_H_