Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Provide proper error location for antiquotations, turning big. #959

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

layus
Copy link
Collaborator

@layus layus commented Jun 17, 2021

I have been banging my head around a small annoyance with antiquotations. Because they do not have their own NExprF constructor, they receive no location annotation. This in turns prevents the display of the right antiquote in the error message.

Example of the error before:

In file test.nix:2:1:
    1 |  
==> 2 |  let {
    3 |    a = "foo";
    4 |    b = 5;
    5 |    c = a + b;
    6 |    body = "${a} ${b}";
    7 |  }
    8 |  
    9 |  
While evaluating:
>>>>>>>>
  rec { a = "foo"; b = 5; c = a + b; body = "${a} ${b}"; }.body
<<<<<<<<
In file test.nix:6:10:
    3 |    a = "foo";
    4 |    b = 5;
    5 |    c = a + b;
==> 6 |    body = "${a} ${b}";
    7 |  }
    8 |  
While evaluating:
>>>>>>>>
  "${a} ${b}"
<<<<<<<<
Failed to assemble string

And after this hack (including changes from #957 )

In file test.nix:2:1:
    1 |  
  > 2 |  let {
  > 3 |    a = "foo";
  > 4 |    b = 5;
  > 5 |    c = a + b;
  > 6 |    body = "${a} ${b}";
  > 7 |  }
    8 |  
    9 |  
         While evaluating:
         >>>>>>>>
           rec {
             a = "foo";
             b = 5;
             c = a + b;
             body = "${"${a}"}${"${b}"}";
             }.body
         <<<<<<<<
In file test.nix:6:10:
    3 |    a = "foo";
    4 |    b = 5;
    5 |    c = a + b;
==> 6 |    body = "${a} ${b}";
      |           ^^^^^^^^^^^
    7 |  }
    8 |  
         While evaluating:
         >>>>>>>>
           "${"${a}"}${"${b}"}"
         <<<<<<<<
In file test.nix:6:16:
    3 |    a = "foo";
    4 |    b = 5;
    5 |    c = a + b;
==> 6 |    body = "${a} ${b}";
      |                 ^^^^
    7 |  }
    8 |  
         While evaluating:
         >>>>>>>>
           "${b}"
         <<<<<<<<
Expected a string, but saw 5

Of course, the hack appears in the pretty-print of the ast: While evaluating: "${"${a}"}${"${b}"}". I simply wrapped the antiquotation into another string with a single antiquotation.

This makes me think that having a proper Antiquotation !r constructor the NExprF datatype may help a lot. Because seen from this point of view, antiquotations are a grammatical marker for coercing an expression to a string. It fits quite well to mark the full antiquotation as the source of the problem when the value is not coercible to a string, because the expression itself is not faulty. I will investigate that idea.

Some related questions remain, like why do we insist on keeping the indent level of multiline strings ? These are the only space-related information that we keep, and it is not at all used. It seems like an attempt to render values as closely as possible to the original input. But in many other locations we just drop the info. So it is an incomplete attempt (see how we handle the let ... body = construct.

@layus
Copy link
Collaborator Author

layus commented Jun 18, 2021

Some nice ideas in here, but introducing NAntiquotation is not one of them :-).

Nix has an ExprConcatStrings expression, which is a shortcut for a chain of + operations on strings, paths, floats and ints all at the same time.

Hnix tries to go a bit too fast here by mangling the string concatenation with raw string expressions.

Technically, in nix, double-quoted strings and indented strings do not exist. There exists only concatenations of raw strings and antiquotations.

@Anton-Latukha
Copy link
Collaborator

Anton-Latukha commented Aug 13, 2021

Not a solution but notifications & related thoughts.

I refactored Parser. Now antiquotations are organized there, which may help. There is a specific question of labeling/error reporting particularly in the parsers, the raised question is HNix evaluation messaging, but parser things & labeling of parser parts can be a way of improving error reporting, as parser generally needs to name every part of the language that can fail & so we can draw/deduplicate use of names from it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants