forked from lix-project/lix
jade
0cc285f87b
Fixes:
- Identifiers starting with _ are prohibited
- Some driveby header dependency cleaning which wound up with doing some
extra fixups.
- Fucking C style casts, man. C++ made these 1000% worse by letting you
also do memory corruption with them with references.
- Remove casts to Expr * where ExprBlackHole is an incomplete type by
introducing an explicitly-cast eBlackHoleAddr as Expr *.
- An incredibly illegal cast of the text bytes of the StorePath hash
into a size_t directly. You can't DO THAT.
Replaced with actually parsing the hash so we get 100% of the bits
being entropy, then memcpying the start of the hash. If this shows
up in a profile we should just make the hash parser faster with a
lookup table or something sensible like that.
- This horrendous bit of UB which I thankfully slapped a deprecation
warning on, built, and it didn't trigger anywhere so it was dead
code and I just deleted it. But holy crap you *cannot* do that.
inline void mkString(const Symbol & s)
{
mkString(((const std::string &) s).c_str());
}
- Some wrong lints. Lots of wrong macro lints, one wrong
suspicious-sizeof lint triggered by the template being instantiated
with only pointers, but the calculation being correct for both
pointers and not-pointers.
- Exceptions in destructors strike again. I tried to catch the
exceptions that might actually happen rather than all the exceptions
imaginable. We can let the runtime hard-kill it on other exceptions
imo.
Change-Id: I71761620846cba64d66ee7ca231b20c061e69710
109 lines
2.9 KiB
C++
109 lines
2.9 KiB
C++
#pragma once
|
|
///@file
|
|
|
|
#include "error.hh"
|
|
#include "types.hh"
|
|
#include "pos-idx.hh"
|
|
|
|
namespace nix {
|
|
|
|
struct Env;
|
|
struct Expr;
|
|
struct Value;
|
|
|
|
class EvalState;
|
|
template<class T>
|
|
class EvalErrorBuilder;
|
|
|
|
class EvalError : public Error
|
|
{
|
|
template<class T>
|
|
friend class EvalErrorBuilder;
|
|
public:
|
|
EvalState & state;
|
|
|
|
EvalError(EvalState & state, ErrorInfo && errorInfo)
|
|
: Error(errorInfo)
|
|
, state(state)
|
|
{
|
|
}
|
|
|
|
template<typename... Args>
|
|
explicit EvalError(EvalState & state, const std::string & formatString, const Args &... formatArgs)
|
|
: Error(formatString, formatArgs...)
|
|
, state(state)
|
|
{
|
|
}
|
|
};
|
|
|
|
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(EvalState & state, const Path & path)
|
|
: EvalError(state, "path '%s' did not exist in the store during evaluation", path)
|
|
{
|
|
}
|
|
};
|
|
|
|
/**
|
|
* `EvalErrorBuilder`s may only be constructed by `EvalState`. The `debugThrow`
|
|
* method must be the final method in any such `EvalErrorBuilder` usage, and it
|
|
* handles deleting the object.
|
|
*/
|
|
template<class T>
|
|
class EvalErrorBuilder final
|
|
{
|
|
friend class EvalState;
|
|
|
|
template<typename... Args>
|
|
explicit EvalErrorBuilder(EvalState & state, const Args &... args)
|
|
: error(T(state, args...))
|
|
{
|
|
}
|
|
|
|
public:
|
|
T error;
|
|
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withExitStatus(unsigned int exitStatus);
|
|
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & atPos(PosIdx pos);
|
|
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & atPos(Value & value, PosIdx fallback = noPos);
|
|
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withTrace(PosIdx pos, const std::string_view text);
|
|
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withFrameTrace(PosIdx pos, const std::string_view text);
|
|
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withSuggestions(Suggestions & s);
|
|
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withFrame(const Env & e, const Expr & ex);
|
|
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & addTrace(PosIdx pos, HintFmt hint);
|
|
|
|
template<typename... Args>
|
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> &
|
|
addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs);
|
|
|
|
/**
|
|
* Delete the `EvalErrorBuilder` and throw the underlying exception.
|
|
*/
|
|
[[gnu::noinline, gnu::noreturn]] void debugThrow();
|
|
};
|
|
|
|
}
|