Files
carbon-lang/toolchain/sem_ir/require_impls.h
T
Dana Jansens c64117d0e0 Make IdTag typesafe (#6574)
The IdTag knows the type of the Id its tagging and the type of the Id
being used as the tag. This prevents mixing up tagged and untagged ids,
and avoids having to work with untyped integers.

Adds an Untagged marker struct that's used as the tag type in IdTag when
no tag is desired.

The complexity of ConstantIds and TypeIds became a bit visible: TypeIds
are concrete ConstantIds. And ConstantIds have two different tagging
schemes, one for concrete and one for symbolic ids. And ConstantIds are
actually re-cast InstIds with the same index. The LoweredTypeStore needs
to work with tagged TypeIds, but the tags actually come from an InstId
store in ConstantValueStore. Now this is expressed in the type system by
getting the tags for TypeIds from the ConstantValueStore.

ValueStores without an TagId type parameter are now visibly untagged.

IdTag is now only default constructible when it does not have a tag,
which means ValueStore is only default constructible when the TagId is
untagged. This forces tagged value stores to be constructed correctly
with a tag at compile time, and untagged ones to be constructed without.

FixedSizeValueStore has overloads for dealing with tagged and untagged
Ids, since it can't default-construct ValueStore for tagged ids, and no
longer requires passing in default-constructed tags when there is no tag
in the ids.
2026-01-13 22:44:38 +00:00

55 lines
1.9 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_REQUIRE_IMPLS_H_
#define CARBON_TOOLCHAIN_SEM_IR_REQUIRE_IMPLS_H_
#include "toolchain/base/block_value_store.h"
#include "toolchain/base/canonical_value_store.h"
#include "toolchain/sem_ir/ids.h"
namespace Carbon::SemIR {
// An interface requirement from an interface or named constraint, written
// `require T impls Z`.
//
// While this comes from a `require` declaration, it is not an Entity like most
// other declarations, with a name and parameters, so it does not inherit
// EntityWithParamsBase.
struct RequireImpls : Printable<RequireImpls> {
// The self-type which must implement a given facet type.
TypeInstId self_id;
// Evaluates to the `FacetType` that the self-type must implement.
TypeInstId facet_type_inst_id;
// If the facet type extends `Self`. When true, the `self_id` will be `Self`.
bool extend_self;
// The location of the `require` declaration.
InstId decl_id;
// The interface or named constraint which contains the `require` declaration.
NameScopeId parent_scope_id;
// A `require` declaration is always generic over `Self` since it's inside an
// interface or named constraint definition.
GenericId generic_id;
auto Print(llvm::raw_ostream& out) const -> void {
out << '{';
out << "self_id: " << self_id
<< ", facet_type_inst_id: " << facet_type_inst_id
<< ", extend_self: " << (extend_self ? "true" : "false")
<< ", parent_scope: " << parent_scope_id;
out << '}';
}
};
using RequireImplsStore =
ValueStore<RequireImplsId, RequireImpls, Tag<CheckIRId>>;
using RequireImplsBlockStore =
BlockValueStore<RequireImplsBlockId, RequireImplsId, Tag<CheckIRId>>;
} // namespace Carbon::SemIR
#endif // CARBON_TOOLCHAIN_SEM_IR_REQUIRE_IMPLS_H_