1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#pragma once
///@file
#include "lix/libutil/box_ptr.hh"
#include "lix/libutil/error.hh"
#include "lix/libutil/types.hh"
#include "lix/libexpr/pos-idx.hh"
#include "lix/libexpr/pos-table.hh"
#include <concepts>
namespace nix {
struct DebugState;
struct DebugTrace;
struct Env;
struct Expr;
struct Value;
class EvalError;
class EvalState;
template<std::derived_from<EvalError> T>
class EvalErrorBuilder;
class EvalError : public Error
{
template<std::derived_from<EvalError> T>
friend class EvalErrorBuilder;
std::shared_ptr<const DebugTrace> frame;
public:
using Error::Error;
};
MakeError(ParseError, Error);
MakeError(AssertionError, EvalError);
MakeError(ThrownError, AssertionError);
MakeError(Abort, EvalError);
MakeError(TypeError, EvalError);
MakeError(UndefinedVarError, EvalError);
MakeError(MissingArgumentError, EvalError);
MakeError(RestrictedPathError, Error);
MakeError(InfiniteRecursionError, EvalError);
/**
* Represents an exception due to an invalid path; that is, it does not exist.
* It corresponds to `!Store::validPath()`.
*/
struct InvalidPathError : public EvalError
{
public:
Path path;
InvalidPathError(const Path & path)
: EvalError("path '%s' did not exist in the store during evaluation", path)
{
}
};
template<std::derived_from<EvalError> T>
class [[nodiscard]] EvalErrorBuilder final
{
const PosTable & positions;
DebugState * debug;
box_ptr<T> error;
public:
template<typename... Args>
explicit EvalErrorBuilder(const PosTable & positions, DebugState * debug, const Args &... args)
: positions(positions)
, debug{debug}
, error(make_box_ptr<T>(args...))
{
}
[[gnu::noinline]] EvalErrorBuilder<T> withExitStatus(unsigned int exitStatus) &&;
[[gnu::noinline]] EvalErrorBuilder<T> atPos(PosIdx pos) &&;
[[gnu::noinline]] EvalErrorBuilder<T> withTrace(PosIdx pos, const std::string_view text) &&;
[[gnu::noinline]] EvalErrorBuilder<T> withSuggestions(Suggestions & s) &&;
[[gnu::noinline]] EvalErrorBuilder<T> withFrame(const Env & e, const Expr & ex) &&;
[[gnu::noinline]] EvalErrorBuilder<T> addTrace(PosIdx pos, HintFmt hint) &&;
template<typename... Args>
[[gnu::noinline]] EvalErrorBuilder<T>
addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs) &&;
/**
* Throw the underlying exception, invoking the debug state callback.
*/
[[gnu::noinline, gnu::noreturn]] void debugThrow(NeverAsync = {}) &&;
/**
* Throw the underlying exception, bypassing the debug state callback.
*/
[[gnu::noinline, gnu::noreturn]] void throw_() &&;
};
}
|