Files
swift-mirror/include/swift/SILOptimizer/Utils/PartitionOpError.def
T
Michael Gottesman 3e4ef57a30 [rbi] Add IncompatibleRegionMerge error with contextual diagnostics
Introduce the IncompatibleRegionMerge partition op error type to detect merges
between regions with incompatible isolation.

Previously, these merge failures produced generic "unknown pattern" errors. Now
we detect them during partition evaluation and emit context-specific diagnostics
like "cannot assign X to Y" or "cannot pass X to function Y", explaining the
specific operation that caused the isolation conflict.

This is part of a larger effort to move isolation-related diagnostics from the
AST level to RegionIsolation at the SIL level. This is important because it
enables flow isolation to support global actor isolated nominal types.

NOTE: We are going to emit errors that we are not going to emit eventually. I am
just updating so I can track that they are all resolved.
2026-03-08 22:16:14 -07:00

178 lines
7.9 KiB
Modula-2

//===--- PartitionOpError.def ----------------------------*- C++ -*--------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// This file contains macros for defining PartitionOpError kinds used by
/// SendNonSendable diagnostics. Using an X-macro pattern reduces boilerplate
/// when adding new error types and ensures consistency across:
/// - Error kind enumeration
/// - Error struct definitions
/// - Error handler dispatch (handleError)
/// - Verbatim error emission (emitVerbatimErrors)
///
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Macro Definitions
//===----------------------------------------------------------------------===//
//
// Errors fall into two categories based on how they are emitted:
//
// 1. Data Dependent Errors: These errors require additional context from
// analysis data structures (like sendingOpToRequireInstMultiMap) to emit
// diagnostics. They are handled immediately during dataflow evaluation in
// handleError(). Example: LocalUseAfterSend needs to record send/use pairs
// for later. These are today just made PARTITION_OP_ERROR. We can categorize
// them separately in the future if needed.
//
// 2. VERBATIM ERRORS (PARTITION_OP_VERBATIM_ERROR):
// These errors are self-contained - all information needed for emission
// is stored within the error struct itself. They are collected during
// dataflow and batch-emitted later in emitVerbatimErrors().
// Example: SentNeverSendable contains the operand and isolation info.
//
// The VERBATIM_SPECIAL_EMISSION_EMITTER variant handles verbatim errors that
// require custom emission logic that doesn't fit the standard pattern.
/// Base macro for all partition operation errors. Data-dependent errors that
/// require immediate handling during dataflow should use this directly.
#ifndef PARTITION_OP_ERROR
#define PARTITION_OP_ERROR(Name)
#endif
/// Macro for verbatim errors that contain all state needed for emission.
/// These are collected during dataflow and emitted later via a diagnostic
/// emitter class named `<Name>DiagnosticEmitter` with an `emit()` method.
/// The emitter constructor takes (RegionAnalysisFunctionInfo*, <Name>Error).
#ifndef PARTITION_OP_VERBATIM_ERROR
#define PARTITION_OP_VERBATIM_ERROR(Name) PARTITION_OP_ERROR(Name)
#endif
/// Macro for verbatim errors with non-standard emission patterns.
///
/// Standard verbatim errors map 1:1 to diagnostic emitters. This macro is for
/// errors that need special handling, such as:
/// - Emitting multiple diagnostics from a single error
/// - Requiring additional filtering logic before emission
/// - Needing access to data not passed through the standard constructor
///
/// Errors using this macro are explicitly handled in emitVerbatimErrors()
/// rather than through the X-macro expansion.
#ifndef PARTITION_OP_VERBATIM_SPECIAL_EMISSION_EMITTER
#define PARTITION_OP_VERBATIM_SPECIAL_EMISSION_EMITTER(Name) PARTITION_OP_VERBATIM_ERROR(Name)
#endif
//===----------------------------------------------------------------------===//
// Error Definitions
//===----------------------------------------------------------------------===//
/// A value was used after its region was already sent to another isolation
/// domain.
///
/// This is a data-dependent error because we need to track the relationship
/// between the sending operation and all subsequent uses in
/// sendingOpToRequireInstMultiMap for deferred diagnostic emission.
///
/// Error struct fields:
/// - op: The PartitionOp representing the use that required the element.
/// - sentElement: The element that was used after being sent.
/// - sendingOp: The operand of the instruction that originally sent the region.
PARTITION_OP_ERROR(LocalUseAfterSend)
/// An 'inout sending' parameter was sent but not reinitialized before the
/// function exits.
///
/// When a function sends an 'inout sending' parameter's region, it must
/// reinitialize the parameter with a disconnected value before returning.
/// This ensures the caller doesn't observe the parameter in an invalid state.
///
/// This is a data-dependent error because it needs to record the send location
/// for use in later diagnostic emission alongside other send-related errors.
PARTITION_OP_ERROR(InOutSendingNotInitializedAtExit)
//===---
// Verbatim Errors
//
// These are self-contained and can be emitted using only their stored state.
//===---
/// An unrecognized code pattern was encountered during dataflow analysis.
///
/// This is a fallback error indicating the analysis found SIL that it doesn't
/// know how to handle. It may indicate a gap in the analysis or new SIL
/// constructs that need support.
PARTITION_OP_VERBATIM_ERROR(UnknownCodePattern)
/// A non-Sendable value that must stay in its isolation domain was passed to a
/// 'sending' parameter or into another isolation domain.
///
/// Example: Passing a value in a @MainActor region to a function expecting a
/// 'sending' parameter.
///
/// Error struct contains the sending operand and isolation info of the
/// non-Sendable value, which is sufficient to emit the diagnostic.
PARTITION_OP_VERBATIM_ERROR(SentNeverSendable)
/// A non-Sendable value was assigned into a 'sending' result parameter.
///
/// When a function has a 'sending' out-parameter, the caller expects to
/// receive a disconnected value that can be freely sent. Assigning an
/// isolated value violates this contract.
///
/// Example: Storing a value from an @MainActor-isolated region into an 'inout
/// sending T' parameter that the caller expects to be sendable.
PARTITION_OP_VERBATIM_ERROR(AssignNeverSendableIntoSendingResult)
/// An 'inout sending' parameter was assigned an isolated (non-disconnected)
/// value at function exit.
///
/// Similar to InOutSendingNotInitializedAtExit, but here the parameter WAS
/// reinitialized - just with a value that isn't disconnected. The caller
/// expects 'inout sending' parameters to contain disconnected values.
PARTITION_OP_VERBATIM_ERROR(InOutSendingNotDisconnectedAtExit)
/// A concrete 'inout sending' parameter's value is being returned from
/// the function.
PARTITION_OP_VERBATIM_ERROR(InOutSendingReturned)
/// A function crossing isolation boundaries is returning a non-Sendable value.
///
/// When a function's result crosses isolation domains (e.g., an async function
/// called from a different actor), returning a non-Sendable type is unsafe.
PARTITION_OP_VERBATIM_ERROR(NonSendableIsolationCrossingResult)
/// Used to signify that when performing the analysis two regions with
/// incompatible isolations were attempted to be merged. Contains information
/// to SendNonSendable knows /why/ the region merge happened so that we can
/// emit a nice diagnostic.
PARTITION_OP_VERBATIM_ERROR(IncompatibleRegionMerge)
//===---
// Verbatim Errors with Special Emission
//
// These need custom handling that doesn't fit the standard emitter pattern.
//===---
/// Two or more 'inout sending' parameters belong to the same region.
///
/// This is problematic because 'inout sending' parameters must be
/// independently transferable. If they share a region, sending one would
/// invalidate the other.
///
/// Uses SPECIAL_EMISSION because a single error may need to emit multiple
/// diagnostics (one for each pair of parameters in the same region) and
/// requires filtering based on diagnostic behavior settings.
PARTITION_OP_VERBATIM_SPECIAL_EMISSION_EMITTER(InOutSendingParametersInSameRegion)
#undef PARTITION_OP_VERBATIM_SPECIAL_EMISSION_EMITTER
#undef PARTITION_OP_VERBATIM_ERROR
#undef PARTITION_OP_ERROR