Files
carbon-lang/toolchain/check/pattern.h
Lucile Rose Nihlen 503f09037d Add support for default values for non-generic parameters of generic functions. (#8011)
A first step in expanding support for default values for parameters in
generic functions.

Adds code to parameter type deduction to include default values for
absent call arguments. In support of that, this PR also generalizes a
function from `export.cpp` that is useful to extract a default
`ConstantId` value from an arbitrary function paramater pattern.
2026-10-21 21:03:39 +00:00

127 lines
5.8 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_CHECK_PATTERN_H_
#define CARBON_TOOLCHAIN_CHECK_PATTERN_H_
#include "toolchain/check/context.h"
#include "toolchain/sem_ir/ids.h"
namespace Carbon::Check {
// The following functions are used to mark the start and end of a time interval
// during pattern handling, in which we may build an `ExprRegion` to represent
// an expression. During one of these intervals, we say that an `ExprRegion` is
// _pending_. Any insts added to `inst_block_stack` while an `ExprRegion` is
// pending are treated as part of the expression. These intervals do not nest:
// we can't start an interval if an `ExprRegion` is already pending.
//
// To ensure that each start has a matching end, without nesting, callers should
// maintain the invariant that an `ExprRegion` is pending before handling the
// start of a pattern, and after handling the end of a pattern.
// Marks the start of a pending `ExprRegion` (see above).
auto BeginExprRegionForPattern(Context& context) -> void;
// Finishes building the pending `ExprRegion`, and returns its ID. It will not
// yet have any control-flow edges into or out of it. An empty `ExprRegion` will
// still be pending after the call, so `End[Empty]ExprRegionForPattern` must be
// called separately after this.
auto ConsumeExprRegionForPattern(Context& context, SemIR::InstId result_id)
-> SemIR::ExprRegionId;
// Ends the pending `ExprRegion`, and asserts that it is empty.
auto EndEmptyExprRegionForPattern(Context& context) -> void;
// Ends the pending `ExprRegion`. If the top of the node stack is an expression,
// the `ExprRegion` is consumed and converted to an expression pattern, which
// replaces the expression on the node stack. Otherwise, the top of the node
// stack should be a pattern, in which case this asserts that the pending region
// is empty, and discards it.
//
// The node stack is passed explicitly as a reminder that this function affects
// the node stack, unlike the other `*ExprRegionForPattern` functions.
auto EndExprRegionForPattern(Context& context, NodeStack& node_stack) -> void;
// Builds and returns an empty `ExprRegion`.
auto MakeEmptyRegion(Context& context, SemIR::InstId result_id)
-> SemIR::ExprRegionId;
// Information about a created binding pattern.
struct BindingPatternInfo {
SemIR::InstId pattern_id;
SemIR::InstId bind_id;
};
// The phase of a binding pattern.
enum class BindingPhase { Template, Symbolic, Runtime };
// Creates an entity name for a binding pattern with the given properties.
// `type_inst_id` is the declared type of the binding as written, if known; see
// `SemIR::EntityName::type_inst_id`.
auto AddBindingEntityName(Context& context, SemIR::NameId name_id,
SemIR::TypeInstId type_inst_id, SemIR::InstId form_id,
bool is_unused, BindingPhase phase)
-> SemIR::EntityNameId;
// Creates a binding pattern and the associated binding inst, and returns their
// IDs. `scrutinee_type_id` is the type of the binding, and `type_region_id` is
// the region representing that type expression. The binding is added to
// `context.bind_name_map()`, with a placeholder value.
auto AddBindingPattern(Context& context, SemIR::LocId name_loc,
SemIR::ExprRegionId type_region_id,
SemIR::TypeId scrutinee_type_id,
SemIR::AnyBindingPattern pattern) -> BindingPatternInfo;
// Creates a binding inst with the given type and value, to represent the result
// of matching the given binding pattern. The binding is not added to any block,
// or to `context.bind_name_map()`.
auto AddBindingForPattern(Context& context, SemIR::LocId name_loc,
SemIR::AnyBindingPattern pattern,
SemIR::TypeId binding_type_id, SemIR::InstId value_id)
-> SemIR::InstId;
// Returns a VarStorage inst for the given `var` pattern. `is_returned_var`
// indicates whether the pattern is the `var` part of a `returned var`; if so,
// this reuses the return parameter, and otherwise it adds a new inst.
auto GetOrAddVarStorage(Context& context, SemIR::InstId var_pattern_id,
bool is_returned_var) -> SemIR::InstId;
// Kinds of parameters that can be added by `AddParamPattern`.
enum class ParamPatternKind {
// A value parameter, `x: T`.
Value,
// A reference parameter, `ref x: T`.
Ref,
// A variable parameter, `var x: T`.
Var,
};
// Returns the `ParamPatternKind` of the parameter instruction `param_inst_id`.
auto GetParamPatternKind(Context& context, SemIR::InstId param_inst_id)
-> ParamPatternKind;
// Adds a parameter pattern with the specified name and type information. The
// pattern emulates `x: T`, `ref x: T`, or `var x: T` depending on the value of
// `kind`. This only sets up the parameter pattern, binding pattern and type;
// callers are expected to add the returned parameter pattern instruction to
// appropriate blocks. This is used when generating functions, rather than
// processing a user-authored declaration.
auto AddParamPattern(Context& context, SemIR::LocId loc_id,
SemIR::NameId name_id,
SemIR::ExprRegionId type_expr_region_id,
SemIR::TypeId type_id, ParamPatternKind kind)
-> SemIR::InstId;
// Given any parameter pattern `InstId`, returns the constant value of the
// associated default value for that parameter, or `None` if no default value
// was supplied.
auto ExtractParameterDefault(Context& context,
SemIR::InstId param_pattern_inst_id)
-> SemIR::ConstantId;
} // namespace Carbon::Check
#endif // CARBON_TOOLCHAIN_CHECK_PATTERN_H_