fix(tvix/eval): Emit errors for invalid integers

Invalid integers (eg integers that're too long) end up as error returns
on the `.value()` returned from the literal in the AST - previously we'd
unwrap this error, causing it to panic the compiler, but now we've got a
nice error variant for it (which just unwraps the underlying
std::num::ParseIntError).

Change-Id: I50c3c5ba89407d86659e20d8991b9658415f39a0
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6635
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Griffin Smith 2022-09-18 12:06:11 -04:00 committed by grfn
parent b3cc4c8c2c
commit d431aa7743
2 changed files with 19 additions and 2 deletions

View file

@ -192,7 +192,10 @@ impl Compiler<'_, '_> {
fn compile_literal(&mut self, node: ast::Literal) {
let value = match node.kind() {
ast::LiteralKind::Float(f) => Value::Float(f.value().unwrap()),
ast::LiteralKind::Integer(i) => Value::Integer(i.value().unwrap()),
ast::LiteralKind::Integer(i) => match i.value() {
Ok(v) => Value::Integer(v),
Err(err) => return self.emit_error(&node, err.into()),
},
ast::LiteralKind::Uri(u) => {
self.emit_warning(&node, WarningKind::DeprecatedLiteralURL);

View file

@ -1,6 +1,6 @@
use crate::value::CoercionKind;
use std::fmt::Display;
use std::path::PathBuf;
use std::{fmt::Display, num::ParseIntError};
use codemap::{CodeMap, Span};
use codemap_diagnostic::{Diagnostic, Emitter, Level, SpanLabel, SpanStyle};
@ -77,12 +77,21 @@ pub enum ErrorKind {
/// The given string doesn't represent an absolute path
NotAnAbsolutePath(PathBuf),
/// An error occurred when parsing an integer
ParseIntError(ParseIntError),
/// Tvix internal warning for features triggered by users that are
/// not actually implemented yet, and without which eval can not
/// proceed.
NotImplemented(&'static str),
}
impl From<ParseIntError> for ErrorKind {
fn from(e: ParseIntError) -> Self {
Self::ParseIntError(e)
}
}
#[derive(Clone, Debug)]
pub struct Error {
pub kind: ErrorKind,
@ -200,6 +209,10 @@ to a missing value in the attribute set(s) included via `with`."#,
)
}
ErrorKind::ParseIntError(err) => {
format!("invalid integer: {}", err)
}
ErrorKind::NotImplemented(feature) => {
format!("feature not yet implemented in Tvix: {}", feature)
}
@ -230,6 +243,7 @@ to a missing value in the attribute set(s) included via `with`."#,
ErrorKind::NotCoercibleToString { .. } => "E018",
ErrorKind::IndexOutOfBounds { .. } => "E019",
ErrorKind::NotAnAbsolutePath(_) => "E020",
ErrorKind::ParseIntError(_) => "E021",
ErrorKind::NotImplemented(_) => "E999",
}
}