Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
While working toward fixing #1187, I need to have access to a span when generating the
contract.Equal
application for arrays (indeed, contract labels don't accept aTermPos
, but require aRawSpan
, ensuring the position is always defined).One solution was to relax the restriction that contract labels need a raw span, but this property is nice, because it forces the Nickel implementation to always make the effort of propagating position information when handling contracts (case in point: this restriction led to this PR).
Another solution was to apply this constraint to merge as well, and propagate a span through merge operations. That is, passing around something akin to
label::Label
when merging values, which would store the original position of the merge operation.Beside #1187, this approach has value in itself: when merging, only the original merge operation hold a defined position, but recursive submerges don't:
Here,
{bar = 1} & {baz = 1}
doesn't have a position, and for a good reason: it actually comes from several locations,{bar = 1}
,{baz = 1}
, and the original top-level merge as well, but we can't pick one as "the" right inherited position, so we pick none. If an error is raised by merge, we currently can't point to the location of the merge:Note how the error is
non mergeable terms
, but there is no merge in sight, because we lose track of it.Content
This PR introduces a separate label, called
MergeLabel
, which carries the span of the original merge operation, as well as aMergeKind
context. This label is a parameter of the binary op merge (not an actual Nickel parameter, so the operation is still binary, but as a parameter of the enum variant).This label is threaded through subsequent merges and is used for error reporting.
Examples
Here is the above example after this PR:
Additionally, we also improve the error reporting of merge conflicts when elaborating a piecewise definition. Before, the error message was like:
After this PR, it becomes: