Skip to content

Commit

Permalink
Revert "crtp"
Browse files Browse the repository at this point in the history
This reverts commit bbe22db.
  • Loading branch information
9999years committed Jan 24, 2024
1 parent bbe22db commit 95d7834
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 211 deletions.
2 changes: 1 addition & 1 deletion src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
getDefaultFlakeAttrPaths(),
prefix);
}
} catch (BaseEvalError&) {
} catch (EvalError&) {
// Don't want eval errors to mess-up with the completion engine, so let's just swallow them
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/libcmd/repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ void NixRepl::mainLoop()
} else {
printMsg(lvlError, e.msg());
}
} catch (BaseEvalError & e) {
} catch (EvalError & e) {
// in debugger mode, an EvalError should trigger another repl session.
// when that session returns the exception will land here. No need to show it again;
// show the error for this repl session instead.
Expand Down Expand Up @@ -420,7 +420,7 @@ StringSet NixRepl::completePrefix(const std::string & prefix)

} catch (ParseError & e) {
// Quietly ignore parse errors.
} catch (BaseEvalError & e) {
} catch (EvalError & e) {
// Quietly ignore evaluation errors.
} catch (BadURL & e) {
// Quietly ignore BadURL flake-related errors.
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/eval-cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ Value & AttrCursor::forceValue()

try {
root->state.forceValue(v, noPos);
} catch (BaseEvalError &) {
} catch (EvalError &) {
debug("setting '%s' to failed", getAttrPathStr());
if (root->db)
cachedValue = {root->db->setFailed(getKey()), failed_t()};
Expand Down
2 changes: 2 additions & 0 deletions src/libexpr/eval-cache.hh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

namespace nix::eval_cache {

MakeError(CachedEvalError, EvalError);

struct AttrDb;
class AttrCursor;

Expand Down
50 changes: 16 additions & 34 deletions src/libexpr/eval-error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,31 @@

namespace nix {

template<typename Derived>
typename EvalError<Derived>::Return & EvalError<Derived>::atPos(PosIdx pos)
EvalError & EvalError::atPos(PosIdx pos)
{
err.errPos = state.positions[pos];
return static_cast<Return &>(*this);
return *this;
}

template<typename Derived>
typename EvalError<Derived>::Return & EvalError<Derived>::withTrace(PosIdx pos, const std::string_view text)
EvalError & EvalError::withTrace(PosIdx pos, const std::string_view text)
{
err.traces.push_front(Trace{.pos = state.positions[pos], .hint = hintformat(std::string(text)), .frame = false});
return static_cast<Return &>(*this);
return *this;
}

template<typename Derived>
typename EvalError<Derived>::Return & EvalError<Derived>::withFrameTrace(PosIdx pos, const std::string_view text)
EvalError & EvalError::withFrameTrace(PosIdx pos, const std::string_view text)
{
err.traces.push_front(Trace{.pos = state.positions[pos], .hint = hintformat(std::string(text)), .frame = true});
return static_cast<Return &>(*this);
return *this;
}

template<typename Derived>
typename EvalError<Derived>::Return & EvalError<Derived>::withSuggestions(Suggestions & s)
EvalError & EvalError::withSuggestions(Suggestions & s)
{
err.suggestions = s;
return static_cast<Return &>(*this);
return *this;
}

template<typename Derived>
typename EvalError<Derived>::Return & EvalError<Derived>::withFrame(const Env & env, const Expr & expr)
EvalError & EvalError::withFrame(const Env & env, const Expr & expr)
{
// NOTE: This is abusing side-effects.
// TODO: check compatibility with nested debugger calls.
Expand All @@ -43,27 +38,24 @@ typename EvalError<Derived>::Return & EvalError<Derived>::withFrame(const Env &
.env = env,
.hint = hintformat("Fake frame for debugging purposes"),
.isError = true});
return static_cast<Return &>(*this);
return *this;
}

template<typename Derived>
typename EvalError<Derived>::Return & EvalError<Derived>::addTrace(PosIdx pos, hintformat hint, bool frame)
EvalError & EvalError::addTrace(PosIdx pos, hintformat hint, bool frame)
{
BaseError::addTrace(state.positions[pos], hint, frame);
return static_cast<Return &>(*this);
return *this;
}

template<typename Derived>
template<typename... Args>
typename EvalError<Derived>::Return & EvalError<Derived>::addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs)
EvalError & EvalError::addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs)
{

addTrace(state.positions[pos], hintfmt(std::string(formatString), formatArgs...));
return static_cast<Return &>(*this);
return *this;
}

template<typename Derived>
void EvalError<Derived>::debugThrow()
void EvalError::debugThrow()
{
if (state.debugRepl && !state.debugTraces.empty()) {
const DebugTrace & last = state.debugTraces.front();
Expand All @@ -72,17 +64,7 @@ void EvalError<Derived>::debugThrow()
state.runDebugRepl(this, *env, *expr);
}

throw std::move(static_cast<Return &>(*this));
throw std::move(*this);
}

template class EvalError<>;
template class EvalError<AssertionError>;
template class EvalError<Abort>;
template class EvalError<TypeError>;
template class EvalError<UndefinedVarError>;
template class EvalError<MissingArgumentError>;
template class EvalError<InfiniteRecursionError>;
template class EvalError<CachedEvalError>;
template class EvalError<InvalidPathError>;

}
107 changes: 20 additions & 87 deletions src/libexpr/eval-error.hh
Original file line number Diff line number Diff line change
Expand Up @@ -10,122 +10,55 @@ struct Expr;

class EvalState;

MakeError(ParseError, Error);

/**
* Base class for `EvalError`.
*
* `EvalError` is a template class, so it's impossible to catch all
* `EvalError`s. Instead, catch `BaseEvalError`.
*/
class BaseEvalError : public Error
{
public:
using Error::Error;
};

// We're using the CRTP here to make builder methods that return subclass
// types.
// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
template<typename Derived = void>
class EvalError : public BaseEvalError
class EvalError : public Error
{
public:
using Return = typename std::conditional<
std::is_same<Derived, void>::value,
EvalError<void>,
Derived
>::type;
EvalState & state;

EvalError(EvalState & state, ErrorInfo && errorInfo)
: BaseEvalError(errorInfo)
: Error(errorInfo)
, state(state)
{
}

template<typename... Args>
explicit EvalError(EvalState & state, const std::string & formatString, const Args &... formatArgs)
: BaseEvalError(formatString, formatArgs...)
: Error(formatString, formatArgs...)
, state(state)
{
}

[[nodiscard, gnu::noinline]] Return & atPos(PosIdx pos);
[[nodiscard, gnu::noinline]] EvalError & atPos(PosIdx pos);

[[nodiscard, gnu::noinline]] Return & withTrace(PosIdx pos, const std::string_view text);
[[nodiscard, gnu::noinline]] EvalError & withTrace(PosIdx pos, const std::string_view text);

[[nodiscard, gnu::noinline]] Return & withFrameTrace(PosIdx pos, const std::string_view text);
[[nodiscard, gnu::noinline]] EvalError & withFrameTrace(PosIdx pos, const std::string_view text);

[[nodiscard, gnu::noinline]] Return & withSuggestions(Suggestions & s);
[[nodiscard, gnu::noinline]] EvalError & withSuggestions(Suggestions & s);

[[nodiscard, gnu::noinline]] Return & withFrame(const Env & e, const Expr & ex);
[[nodiscard, gnu::noinline]] EvalError & withFrame(const Env & e, const Expr & ex);

[[nodiscard, gnu::noinline]] Return & addTrace(PosIdx pos, hintformat hint, bool frame = false);
[[nodiscard, gnu::noinline]] EvalError & addTrace(PosIdx pos, hintformat hint, bool frame = false);

template<typename... Args>
Return & addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs);

[[gnu::noinline, gnu::noreturn]] virtual void debugThrow();
};

class AssertionError : public EvalError<AssertionError>
{
public:
using EvalError::EvalError;
};

class ThrownError : public AssertionError
{
public:
using AssertionError::AssertionError;
};

class Abort : public EvalError<Abort>
{
public:
using EvalError::EvalError;
};

class TypeError : public EvalError<TypeError>
{
public:
using EvalError::EvalError;
};

class UndefinedVarError : public EvalError<UndefinedVarError>
{
public:
using EvalError::EvalError;
};
EvalError & addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs);

class MissingArgumentError : public EvalError<MissingArgumentError>
{
public:
using EvalError::EvalError;
[[gnu::noinline, gnu::noreturn]] void debugThrow();
};

class InfiniteRecursionError : public EvalError<InfiniteRecursionError>
{
friend class EvalState;
public:
using EvalError::EvalError;
};

class CachedEvalError : public EvalError<CachedEvalError>
MakeError(ParseError, Error);
MakeError(AssertionError, EvalError);
MakeError(ThrownError, AssertionError);
MakeError(Abort, EvalError);
MakeError(TypeError, EvalError);
MakeError(UndefinedVarError, EvalError);
MakeError(MissingArgumentError, EvalError);

class InfiniteRecursionError : public EvalError
{
friend class EvalState;
public:
using EvalError::EvalError;
};

struct InvalidPathError : public EvalError<InvalidPathError>
{
public:
Path path;
InvalidPathError(EvalState & state, const Path & path)
: EvalError(state, "path '%s' is not valid", path)
{ }
};

}
2 changes: 1 addition & 1 deletion src/libexpr/eval-settings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ struct EvalSettings : Config
Setting<bool> traceVerbose{this, false, "trace-verbose",
"Whether `builtins.traceVerbose` should trace its first argument when evaluated."};

Setting<unsigned int> maxCallDepth{this, 9000, "max-call-depth",
Setting<unsigned int> maxCallDepth{this, 10000, "max-call-depth",
"The maximum function call depth to allow before erroring."};
};

Expand Down
12 changes: 12 additions & 0 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,18 @@ SourcePath resolveExprPath(SourcePath path);
*/
bool isAllowedURI(std::string_view uri, const Strings & allowedPaths);

struct InvalidPathError : public EvalError
{
public:
Path path;
InvalidPathError(EvalState & state, const Path & path)
: EvalError(state, "path '%s' is not valid", path)
{ }
#ifdef EXCEPTION_NEEDS_THROW_SPEC
~InvalidPathError() throw () { };
#endif
};

}

#include "eval-inline.hh"
2 changes: 1 addition & 1 deletion src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ static RegisterPrimOp primop_throw({
NixStringContext context;
auto s = state.coerceToString(pos, *args[0], context,
"while evaluating the error message passed to builtin.throw").toOwned();
ThrownError(state, "%s", s).atPos(pos).debugThrow();
ThrownError(state, "%s", s).debugThrow();
}
});

Expand Down
6 changes: 3 additions & 3 deletions src/nix/flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON

// If we don't recognize it, it's probably content
return true;
} catch (BaseEvalError & e) {
} catch (EvalError & e) {
// Some attrs may contain errors, eg. legacyPackages of
// nixpkgs. We still want to recurse into it, instead of
// skipping it at all.
Expand Down Expand Up @@ -1305,7 +1305,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
{
auto aType = visitor.maybeGetAttr("type");
if (!aType || aType->getString() != "app")
EvalError(*state, "not an app definition").debugThrow();
throw EvalError(*state, "not an app definition");
if (json) {
j.emplace("type", "app");
} else {
Expand Down Expand Up @@ -1340,7 +1340,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
logger->cout("%s: " ANSI_WARNING "%s" ANSI_NORMAL, headerPrefix, description);
}
}
} catch (BaseEvalError & e) {
} catch (EvalError & e) {
if (!(attrPath.size() > 0 && attrPathS[0] == "legacyPackages"))
throw;
}
Expand Down
2 changes: 1 addition & 1 deletion src/nix/search.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ struct CmdSearch : InstallableValueCommand, MixJSON
recurse();
}

} catch (BaseEvalError & e) {
} catch (EvalError & e) {
if (!(attrPath.size() > 0 && attrPathS[0] == "legacyPackages"))
throw;
}
Expand Down
30 changes: 0 additions & 30 deletions tests/functional/ca/config.nix.in

This file was deleted.

1 change: 1 addition & 0 deletions tests/functional/ca/config.nix.in
Loading

0 comments on commit 95d7834

Please sign in to comment.