Skip to content

Improve location reporting for type and type coercion errors #6200

@layus

Description

@layus

Describe the bug

Nix sometimes reports imprecise error location when a value has the wrong type for an operation.

In this example, builtins.hasAttr expects a string and receives a boolean as first argument. But the caret points at the builtin itself, making the error message misleading.

error: value is a Boolean while a string was expected

       at /nix/store/1bicq9whypjqyy2j6b7qw58jqm9f1py3-source/lib.nix:75:12:

           74|         let inputName = declaredInputs."${name}"; in
           75|         if builtins.hasAttr inputName nickelInputs then
             |            ^
           76|           let input = nickelInputs."${inputName}"; in

In the code, we see that we coerce the first arg to a string, and pass as trace position the pos of the builtin itsefl (the only we can have at this point in evaluation).

auto attr = state.forceStringNoCtx(*args[0], pos);

Expected behavior

Each time we have a coercion, there is a potential for failure. We should ensure that the message is correct by pointing at the right location. From my analysis, it is next to impossible, as the information is lost by the time we know that we have to coerce.

The next best thing is to amend the error message to mention how the error relates to the error location. In this case, say it is the first argument to the builtin under evaluation. This way, the caret can remain on the builtin itself.

error: in the first argument of builtins.hasAttr: value is a Boolean while a string was expected

Thus, coercion functions such as coerceToString, evalAttrs and the like should take an extra, mandatory error message describing what the coerced value means for the current Expr node under evaluation.

We should also ensure that each Expr node that may fail in such a way gets a proper error context. That is, we should ensure that a caret points to the expression we refer to in the error message. This is the issue encountered by #6191.

Additional context

#6191

9d67332 (thanks @greedy !)

Metadata

Metadata

Labels

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions