Files
carbon-lang/toolchain/sem_ir/constant.cpp
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

40 lines
1.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
#include "toolchain/sem_ir/constant.h"
#include "toolchain/sem_ir/file.h"
namespace Carbon::SemIR {
auto ConstantStore::GetOrAdd(Inst inst, PhaseKind phase) -> ConstantId {
auto result = map_.Insert(inst, [&] {
auto inst_id = sem_ir_->insts().AddInNoBlock(LocIdAndInst::NoLoc(inst));
ConstantId const_id = ConstantId::Invalid;
if (phase == IsTemplate) {
const_id = SemIR::ConstantId::ForTemplateConstant(inst_id);
} else {
// The instruction in the constants store is an abstract symbolic
// constant, not associated with any particular generic.
SymbolicConstant symbolic_constant = {
.inst_id = inst_id,
.generic_id = GenericId::Invalid,
.index = GenericInstIndex::Invalid,
.period_self_only = (phase == IsPeriodSelfSymbolic)};
const_id =
sem_ir_->constant_values().AddSymbolicConstant(symbolic_constant);
}
sem_ir_->constant_values().Set(inst_id, const_id);
constants_.push_back(inst_id);
return const_id;
});
CARBON_CHECK(result.value() != ConstantId::Invalid);
CARBON_CHECK(
result.value().is_symbolic() == (phase != IsTemplate),
"Constant {0} registered as both symbolic and template constant.", inst);
return result.value();
}
} // namespace Carbon::SemIR