11 if (!sigma->is_set())
return Sieve(sigma->num_ops());
12 return Sieve(sigma->ops(), [
this](
const Def* op) { return !old_world().inhabitant(op); });
15const Def* SingleErasure::erase(
const Single* single) {
20const Def* SingleErasure::inhabitant(
const Def* type) {
21 if (
auto single =
type->isa<Single>(); single && !is_unit(single))
return rewrite(single->op());
25size_t SingleErasure::remap(
const Sieve& keep,
const Def* index) {
28 index->blame(
"index is not a literal")
29 .n(
"dropping an information-free component shifts the indices of its successors")
33 assert(j !=
Sieve::Gone &&
"an Extract/Insert of a dropped component is erased before it is remapped");
38 auto type = erase(single);
39 log().d(
"single-erasure `{}` → `{}`", single, type);
46 return inhabitant(wrap->type());
66 auto keep = sieve(sigma);
72 auto keep = sieve(old_sigma);
76 return rewrite_stub(old_sigma, new_sigma, keep.new2old());
88 auto keep = sieve(sigma);
97 if (
old_world().inhabitant(insert->value()->type()))
return rewrite(insert->tuple());
99 if (
auto sigma = insert->tuple()->type()->isa<
Sigma>()) {
100 auto keep = sieve(sigma);
bool is_intro() const noexcept
constexpr auto ops() const noexcept
const Def * unfold_type() const
Yields the type of this Def and builds a new Type (LSucc n) if necessary.
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Constructs a Join or Variant value.
const Def * value() const
Creates a new Tuple / Pack by inserting Insert::value at position Insert::index into Insert::tuple.
static std::optional< T > isa(const Def *def)
Scrutinize Match::scrutinee() and dispatch to Match::arms.
const Def * scrutinee() const
const Def * arm(size_t i) const
const fe::Log & log() const
void profile_count(std::string_view key, uint64_t n=1)
Adds n to the custom fe::Profiler counter key of the current run; no-op unless profiling is enabled.
World & new_world()
Create new Defs into this.
const Def * rewrite_imm_Tuple(const Tuple *) override
const Def * rewrite_stub(Def *, Def *) override
World & old_world()
Get old Defs from here.
virtual const Def * rewrite_imm_Match(const Match *)
virtual const Def * rewrite_imm_Seq(const Seq *seq)
virtual const Def * rewrite_imm_Extract(const Extract *)
virtual const Def * rewrite_mut_Sigma(Sigma *)
virtual const Def * rewrite_imm_Insert(const Insert *)
virtual const Def * rewrite_mut_Seq(Seq *seq)
virtual const Def * rewrite_imm_Sigma(const Sigma *)
virtual const Def * rewrite_imm_Inj(const Inj *)
virtual const Def * rewrite(const Def *)
virtual const Def * rewrite_imm_Variant(const Variant *)
Base class for Arr and Pack.
Filters the components of an aggregate and keeps track of where the survivors end up.
static constexpr size_t Gone
const Def * rewrite_imm_Tuple(const Tuple *) final
const Def * rewrite_imm_Variant(const Variant *) final
const Def * rewrite_mut_Seq(Seq *) final
const Def * rewrite_mut_Sigma(Sigma *) final
const Def * rewrite_imm_Wrap(const Wrap *) final
const Def * rewrite_imm_Match(const Match *) final
const Def * rewrite_imm_Insert(const Insert *) final
const Def * rewrite_imm_Sigma(const Sigma *) final
const Def * rewrite_imm_Extract(const Extract *) final
const Def * rewrite_imm_Inj(const Inj *) final
const Def * rewrite_imm_Single(const Single *) final
const Def * rewrite_imm_Seq(const Seq *) final
Singleton type formation.
Data constructor for a Sigma.
A sum type whose cases are positional: unlike a Join, they are neither sorted nor deduplicated.
static const Def * isa_lone(const Def *d)
The payload A of a single-case Variant | A, which is isomorphic to A.
const Def * insert(const Def *d, const Def *i, const Def *val)
const Def * inhabitant(const Def *type)
The sole inhabitant of type, if it has exactly one, nullptr otherwise.
const Def * sigma(Defs ops)
const Def * app(const Def *callee, const Def *arg)
const Def * extract(const Def *d, const Def *i)
const Def * prod(bool term, Defs ops)
Sigma * mut_sigma(const Def *type, size_t size)
Singleton term introduction.