Files
carbon-lang/toolchain/check/pattern_match.h
T
Dana Jansens 7beb29f8b2 Use a fallback loc for diagnostics generated on canonical insts (#7967)
We allow using `InstId` as a `LocId` for diagnostics, which works great
in `handle_*` functions, where we are working with non-canonical insts.
And convert and pattern matching often are given non-canonical insts,
which they can use, or pull apart to find some other inst, and use those
as a location for diagnostics. However these operations can also be
called with canonical insts, which have no location. In that case if we
need to diagnose an error, it ends up not being attached to any code at
all. Since we always have a `LocId` somewhere up the call stack, pass it
along and in these places that handle canonical instructions too, use
`GetInstLocationOrFallback()` to get a valid location for diagnostics.

This is also similar to what eval does with its fallback `LocId`.

The result is that many diagnostics now have a location where they had
none before. It also means some insts don't get `<elided>` in formatted
semir for not having a location at all and thus not being in range.
2026-10-15 19:03:10 +00:00

103 lines
4.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_MATCH_H_
#define CARBON_TOOLCHAIN_CHECK_PATTERN_MATCH_H_
#include "toolchain/check/context.h"
#include "toolchain/sem_ir/function.h"
#include "toolchain/sem_ir/ids.h"
namespace Carbon::Check {
// TODO: Find a better place for this overview, once it has stabilized.
//
// The signature pattern of a function call is matched partially by the caller
// and partially by the callee. `ParamPattern` insts mark the boundary
// between the two: pattern insts that are descendants of a `ParamPattern`
// are matched by the callee, and pattern insts that have a `ParamPattern`
// as a descendant are matched by the caller.
// Return type for CalleePatternMatch.
struct CalleePatternMatchResults {
SemIR::InstBlockId call_param_patterns_id;
SemIR::InstBlockId call_params_id;
SemIR::Function::CallParamIndexRanges param_ranges;
};
// Emits the pattern-match IR for the declaration of a parameterized entity with
// the given implicit and explicit parameter patterns, and the given return
// pattern (any of which may be `None` if not applicable). This IR performs the
// callee side of pattern matching, starting at the `ParamPattern` insts, and
// matching them against the corresponding `Call` parameters (see
// entity_with_params_base.h for the definition of that term).
// Returns the IDs of inst blocks consisting of references to the `Call`
// parameter patterns and `Call` parameters of the function, as well as
// the implicit, explicit, and return index ranges of those blocks.
//
// In some circumstances this can add new pattern insts, so the pattern
// block containing the parameter patterns should still be on top of
// `context.pattern_block_stack()`.
auto CalleePatternMatch(Context& context, SemIR::LocId loc_id,
SemIR::InstBlockId implicit_param_patterns_id,
SemIR::InstBlockId param_patterns_id,
SemIR::InstId return_pattern_id)
-> CalleePatternMatchResults;
// Emits the callee pattern-match IR for `return_pattern_id`, for an entity
// whose parameters were already matched by `CalleePatternMatch` without a
// return pattern, producing `param_results`. This is used when the return
// pattern is only formed after the parameters, as for a deduced return type.
// Returns `param_results` extended with the return's `Call` parameters.
//
// As with `CalleePatternMatch`, the pattern block containing the return pattern
// should be on top of `context.pattern_block_stack()`.
auto CalleeReturnPatternMatch(Context& context, SemIR::LocId loc_id,
const CalleePatternMatchResults& param_results,
SemIR::InstId return_pattern_id)
-> CalleePatternMatchResults;
// Return type for ThunkPatternMatch.
struct ThunkPatternMatchResults {
// The syntactic argument list. If there is a self parameter, the first
// element will be the corresponding argument.
llvm::SmallVector<SemIR::InstId> syntactic_args;
// The trailing elements of `outer_call_args` that were not used in
// `syntactic_args`. These presumably represent the output arguments for the
// return.
llvm::ArrayRef<SemIR::InstId> ignored_call_args;
};
// Given the syntactic parameters and `Call` arguments for the outer part of a
// thunked function call, computes the corresponding syntactic argument list,
// suitable for passing to the inner part of the thunked function call.
auto ThunkPatternMatch(Context& context, SemIR::LocId loc_id,
llvm::ArrayRef<SemIR::InstId> param_pattern_ids,
llvm::ArrayRef<SemIR::InstId> outer_call_args)
-> ThunkPatternMatchResults;
// Emits the pattern-match IR for matching the given arguments with the given
// parameter patterns, and returns an inst block of the arguments that should
// be passed to the `Call` inst. `is_desugared` indicates that this call
// was produced by desugaring, not written as a function call in user code, so
// arguments to `ref` parameters aren't required to have `ref` tags.
auto CallerPatternMatch(
Context& context, SemIR::LocId loc_id, SemIR::SpecificId specific_id,
SemIR::InstId self_pattern_id, SemIR::InstBlockId param_patterns_id,
SemIR::InstId return_pattern_id, SemIR::InstId self_arg_id,
llvm::ArrayRef<SemIR::InstId> arg_refs, SemIR::InstId return_arg_id,
bool is_desugared) -> SemIR::InstBlockId;
// Emits the pattern-match IR for a local pattern matching operation with the
// given pattern and scrutinee.
auto LocalPatternMatch(Context& context, SemIR::LocId loc_id,
SemIR::InstId pattern_id, SemIR::InstId scrutinee_id)
-> void;
} // namespace Carbon::Check
#endif // CARBON_TOOLCHAIN_CHECK_PATTERN_MATCH_H_