popChoiceContext() {
		const poppedChoiceContext = this.choiceContext;
		const forkContext = this.forkContext;
		const head = forkContext.head;

		this.choiceContext = poppedChoiceContext.upper;

		switch (poppedChoiceContext.kind) {
			case "&&":
			case "||":
			case "??":
				/*
				 * The `head` are the path of the right-hand operand.
				 * If we haven't previously added segments from child contexts,
				 * then we add these segments to all possible forks.
				 */
				if (!poppedChoiceContext.processed) {
					poppedChoiceContext.trueForkContext.add(head);
					poppedChoiceContext.falseForkContext.add(head);
					poppedChoiceContext.nullishForkContext.add(head);
				}

				/*
				 * If this context is the left (test) expression for another choice
				 * context, such as `a || b` in the expression `a || b || c`,
				 * then we take the segments for this context and move them up
				 * to the parent context.
				 */
				if (poppedChoiceContext.isForkingAsResult) {
					const parentContext = this.choiceContext;

					parentContext.trueForkContext.addAll(
						poppedChoiceContext.trueForkContext,
					);
					parentContext.falseForkContext.addAll(
						poppedChoiceContext.falseForkContext,
					);
					parentContext.nullishForkContext.addAll(
						poppedChoiceContext.nullishForkContext,
					);
					parentContext.processed = true;

					// Exit early so we don't collapse all paths into one.
					return poppedChoiceContext;
				}

				break;

			case "test":
				if (!poppedChoiceContext.processed) {
					/*
					 * The head segments are the path of the `if` block here.
					 * Updates the `true` path with the end of the `if` block.
					 */
					poppedChoiceContext.trueForkContext.clear();
					poppedChoiceContext.trueForkContext.add(head);
				} else {
					/*
					 * The head segments are the path of the `else` block here.
					 * Updates the `false` path with the end of the `else`
					 * block.
					 */
					poppedChoiceContext.falseForkContext.clear();
					poppedChoiceContext.falseForkContext.add(head);
				}

				break;

			case "loop":
				/*
				 * Loops are addressed in `popLoopContext()` so just return
				 * the context without modification.
				 */
				return poppedChoiceContext;

			/* c8 ignore next */
			default:
				throw new Error("unreachable");
		}

		/*
		 * Merge the true path with the false path to create a single path.
		 */
		const combinedForkContext = poppedChoiceContext.trueForkContext;

		combinedForkContext.addAll(poppedChoiceContext.falseForkContext);
		forkContext.replaceHead(combinedForkContext.makeNext(0, -1));

		return poppedChoiceContext;
	}
Pops the last choice context and finalizes it.
This is called upon leaving a node that represents a choice.
@throws {Error} (Unreachable.)
@returns {ChoiceContext} The popped context.