Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Implement array merging, take II #1229

Merged
merged 4 commits into from
Apr 6, 2023
Merged

Implement array merging, take II #1229

merged 4 commits into from
Apr 6, 2023

Conversation

yannham
Copy link
Member

@yannham yannham commented Apr 5, 2023

Closes #1187 #1226.

Implement array merging by generating an contract.Equal application, ie two arrays are properly merged only if they are equal.

This required to slightly rework the way contract reporting work, see #1226 (comment). This PR doesn't panic if a type doesn't have a position anymore when reporting an error, but pretty-print this type, parse it again with positions, and use this type for error reporting.

Doing so, this PR also fixes an unreported bug, which was that reporting contract failure on deeply (more than one level) type constructor was off. On master:

$ nickel <<< '[[5]] | Array (Array String)'
error: contract broken by a value
  ┌─ <stdin>:1:3

1 │ [[5]] | Array (Array String)
  │   ^            ^^^^^^^^^^^^ expected array element type
  │   │             
  │   applied to this expression

This underlines Array String instead of String. This manifested through dubious code in the ty_path::span method. This issue is fixed by this PR and a snapshot test was added.

Error reporting when merging fails

The current error reporting for a failure of merging two arrays isn't optimal. We have to choose between reporting the generated contract (contract.Equal some_array), which is indeed the contract that failed, but is not related (position-wise) to the original merge.

We can instead report the original merge location as being the position of the type (which is a bit hacky, but whatever), but then the error reporting is underlining the merge with the message "expected type". For now we went with the latter. All the information required for good error reporting is propagated, but doing so requires to rethink a bit the structure of contract error reporting. For now, we use this imperfect reporting, and plan on improving on it later. It's arguably at least viable.

yannham added 2 commits April 5, 2023 14:13
Implement array merging to fix merging not being idempotent on array,
while it's a desirable fundamental property. As we don't want to pick an
arbitrary merge strategy on arrays (there are several ones, and each one
might be natural in one specific situation), we do the minimal thing: we
only succeed in merging arrays when they're equal (using a lazy `Equal`
contract).

Additional behavior will be possible once custom merge functions land.
@yannham yannham requested review from vkleen and ebresafegaga April 5, 2023 12:13
@yannham yannham changed the title Implement array merginge, take II Implement array merging, take II Apr 5, 2023
@github-actions github-actions bot temporarily deployed to pull request April 5, 2023 12:16 Inactive
Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io>
@github-actions github-actions bot temporarily deployed to pull request April 5, 2023 12:54 Inactive
@yannham yannham merged commit 8436ffe into master Apr 6, 2023
@yannham yannham deleted the task/merge-array-3 branch April 6, 2023 10:37
vkleen added a commit that referenced this pull request Aug 9, 2023
We previously used a bespoke formatting algorithm for `Type`. I replaced
the analogous code for `Term`s by the pretty printer in #1262 but we
were worried about some questionable code for contract error reporting
before doing the same for types. Namely, at some point it relied on hard
coded string offsets for pointing at parts of types that were inferred
by Nickel and consequently had no `TermPos`. In #1229 we ripped out
that code and replaced it by reparsing the pretty printer output when
necessary.

Incidentally, this change also fixes some terms being truncated when
formatted. For example, previously

```
SomeUserDefinedContract "that" "takes" "many" "arguments"
```

would be printed as `SomeUserDefinedContract "that" …`. This is somewhat
useful to prevent huge screenfuls of error messages sometimes, but it
makes the `Display` implementation useless for other natural purposes.
github-merge-queue bot pushed a commit that referenced this pull request Aug 10, 2023
)

* Use the pretty printer in the  `Display` implementation for `Type`

We previously used a bespoke formatting algorithm for `Type`. I replaced
the analogous code for `Term`s by the pretty printer in #1262 but we
were worried about some questionable code for contract error reporting
before doing the same for types. Namely, at some point it relied on hard
coded string offsets for pointing at parts of types that were inferred
by Nickel and consequently had no `TermPos`. In #1229 we ripped out
that code and replaced it by reparsing the pretty printer output when
necessary.

Incidentally, this change also fixes some terms being truncated when
formatted. For example, previously

```
SomeUserDefinedContract "that" "takes" "many" "arguments"
```

would be printed as `SomeUserDefinedContract "that" …`. This is somewhat
useful to prevent huge screenfuls of error messages sometimes, but it
makes the `Display` implementation useless for other natural purposes.

* Revert a useless change to snapshot test inputs

* Factor out calling the pretty printer for `Display`
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Merge is not idempotent
2 participants