use crate::{RegId, Span};
use miette::Diagnostic;
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Debug, Clone, Error, Diagnostic, PartialEq, Serialize, Deserialize)]
pub enum CompileError {
#[error("Register overflow.")]
#[diagnostic(code(nu::compile::register_overflow))]
RegisterOverflow {
#[label("the code being compiled is probably too large")]
block_span: Option<Span>,
},
#[error("Register {reg_id} was uninitialized when used, possibly reused.")]
#[diagnostic(
code(nu::compile::register_uninitialized),
help("this is a compiler bug. Please report it at https://github.com/nushell/nushell/issues/new\nfrom: {caller}"),
)]
RegisterUninitialized { reg_id: RegId, caller: String },
#[error("Register {reg_id} was uninitialized when used, possibly reused.")]
#[diagnostic(
code(nu::compile::register_uninitialized),
help("this is a compiler bug. Please report it at https://github.com/nushell/nushell/issues/new\nfrom: {caller}"),
)]
RegisterUninitializedWhilePushingInstruction {
reg_id: RegId,
caller: String,
instruction: String,
#[label("while adding this instruction: {instruction}")]
span: Span,
},
#[error("Block contains too much string data: maximum 4 GiB exceeded.")]
#[diagnostic(
code(nu::compile::data_overflow),
help("try loading the string data from a file instead")
)]
DataOverflow {
#[label("while compiling this block")]
block_span: Option<Span>,
},
#[error("Block contains too many files.")]
#[diagnostic(
code(nu::compile::register_overflow),
help("try using fewer file redirections")
)]
FileOverflow {
#[label("while compiling this block")]
block_span: Option<Span>,
},
#[error("Invalid redirect mode: File should not be specified by commands.")]
#[diagnostic(
code(nu::compile::invalid_redirect_mode),
help("this is a command bug. Please report it at https://github.com/nushell/nushell/issues/new")
)]
InvalidRedirectMode {
#[label("while compiling this expression")]
span: Span,
},
#[error("Encountered garbage, likely due to parse error.")]
#[diagnostic(code(nu::compile::garbage))]
Garbage {
#[label("garbage found here")]
span: Span,
},
#[error("Unsupported operator expression.")]
#[diagnostic(code(nu::compile::unsupported_operator_expression))]
UnsupportedOperatorExpression {
#[label("this expression is in operator position but is not an operator")]
span: Span,
},
#[error("Attempted access of $env by integer path.")]
#[diagnostic(code(nu::compile::access_env_by_int))]
AccessEnvByInt {
#[label("$env keys should be strings")]
span: Span,
},
#[error("Encountered invalid `{keyword}` keyword call.")]
#[diagnostic(code(nu::compile::invalid_keyword_call))]
InvalidKeywordCall {
keyword: String,
#[label("this call is not properly formed")]
span: Span,
},
#[error("Attempted to set branch target of non-branch instruction.")]
#[diagnostic(
code(nu::compile::set_branch_target_of_non_branch_instruction),
help("this is a compiler bug. Please report it at https://github.com/nushell/nushell/issues/new"),
)]
SetBranchTargetOfNonBranchInstruction {
instruction: String,
#[label("tried to modify: {instruction}")]
span: Span,
},
#[error("External calls are not supported.")]
#[diagnostic(
code(nu::compile::run_external_not_found),
help("`run-external` was not found in scope")
)]
RunExternalNotFound {
#[label("can't be run in this context")]
span: Span,
},
#[error("Assignment operations require a variable.")]
#[diagnostic(
code(nu::compile::assignment_requires_variable),
help("try assigning to a variable or a cell path of a variable")
)]
AssignmentRequiresVar {
#[label("needs to be a variable")]
span: Span,
},
#[error("Assignment to an immutable variable.")]
#[diagnostic(
code(nu::compile::assignment_requires_mutable_variable),
help("declare the variable with `mut`, or shadow it again with `let`")
)]
AssignmentRequiresMutableVar {
#[label("needs to be a mutable variable")]
span: Span,
},
#[error("{envvar_name} cannot be set manually.")]
#[diagnostic(
code(nu::compile::automatic_env_var_set_manually),
help(
r#"The environment variable '{envvar_name}' is set automatically by Nushell and cannot be set manually."#
)
)]
AutomaticEnvVarSetManually {
envvar_name: String,
#[label("cannot set '{envvar_name}' manually")]
span: Span,
},
#[error("Cannot replace environment.")]
#[diagnostic(
code(nu::compile::cannot_replace_env),
help("Assigning a value to '$env' is not allowed.")
)]
CannotReplaceEnv {
#[label("setting '$env' not allowed")]
span: Span,
},
#[error("Unexpected expression.")]
#[diagnostic(code(nu::compile::unexpected_expression))]
UnexpectedExpression {
expr_name: String,
#[label("{expr_name} is not allowed in this context")]
span: Span,
},
#[error("Missing required declaration: `{decl_name}`")]
#[diagnostic(code(nu::compile::missing_required_declaration))]
MissingRequiredDeclaration {
decl_name: String,
#[label("`{decl_name}` must be in scope to compile this expression")]
span: Span,
},
#[error("Invalid literal")]
#[diagnostic(code(nu::compile::invalid_literal))]
InvalidLiteral {
msg: String,
#[label("{msg}")]
span: Span,
},
#[error("{msg}")]
#[diagnostic(code(nu::compile::not_in_a_loop))]
NotInALoop {
msg: String,
#[label("can't be used outside of a loop")]
span: Option<Span>,
},
#[error("Incoherent loop state: the loop that ended was not the one we were expecting.")]
#[diagnostic(
code(nu::compile::incoherent_loop_state),
help("this is a compiler bug. Please report it at https://github.com/nushell/nushell/issues/new"),
)]
IncoherentLoopState {
#[label("while compiling this block")]
block_span: Option<Span>,
},
#[error("Undefined label `{label_id}`.")]
#[diagnostic(
code(nu::compile::undefined_label),
help("this is a compiler bug. Please report it at https://github.com/nushell/nushell/issues/new"),
)]
UndefinedLabel {
label_id: usize,
#[label("label was used while compiling this code")]
span: Option<Span>,
},
}