diff --git a/core/src/error.rs b/core/src/error.rs new file mode 100644 index 0000000000..4553b60a9a --- /dev/null +++ b/core/src/error.rs @@ -0,0 +1,22 @@ +use crate::Location; + +#[derive(Debug, PartialEq, Eq)] +pub struct Error { + pub error: T, + pub location: Location, + pub source_path: String, +} + +impl std::ops::Deref for Error { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.error + } +} + +impl Error { + pub fn error(self) -> T { + self.error + } +} diff --git a/core/src/lib.rs b/core/src/lib.rs index 0b2e23e8f5..f38c6d0b3b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -2,9 +2,11 @@ #![doc(html_root_url = "https://docs.rs/rustpython-compiler-core/")] mod bytecode; +mod error; mod location; mod mode; pub use bytecode::*; +pub use error::Error; pub use location::Location; pub use mode::Mode; diff --git a/parser/Cargo.toml b/parser/Cargo.toml index 2522e726f6..e6acbbd4b0 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -16,6 +16,7 @@ tiny-keccak = { version = "2", features = ["sha3"] } [dependencies] rustpython-ast = { path = "../ast" } +rustpython-compiler-core = { path = "../core" } ahash = "0.7.6" itertools = "0.10.3" diff --git a/parser/src/error.rs b/parser/src/error.rs index 76f02dc5c9..b64abcb77e 100644 --- a/parser/src/error.rs +++ b/parser/src/error.rs @@ -118,11 +118,7 @@ impl From for LalrpopError { /// Represents an error during parsing #[derive(Debug, PartialEq)] -pub struct ParseError { - pub error: ParseErrorType, - pub location: Location, - pub source_path: String, -} +pub struct ParseError(rustpython_compiler_core::Error); #[derive(Debug, PartialEq)] pub enum ParseErrorType { @@ -138,8 +134,28 @@ pub enum ParseErrorType { Lexical(LexicalErrorType), } +impl From for rustpython_compiler_core::Error { + fn from(err: ParseError) -> Self { + err.0 + } +} + +impl From for ParseErrorType { + fn from(err: ParseError) -> Self { + err.0.error + } +} + /// Convert `lalrpop_util::ParseError` to our internal type impl ParseError { + fn new(error: ParseErrorType, location: Location, source_path: String) -> Self { + Self(rustpython_compiler_core::Error { + error, + location, + source_path, + }) + } + pub(crate) fn from_lalrpop( err: LalrpopError, source_path: &str, @@ -147,36 +163,30 @@ impl ParseError { let source_path = source_path.to_owned(); match err { // TODO: Are there cases where this isn't an EOF? - LalrpopError::InvalidToken { location } => ParseError { - error: ParseErrorType::Eof, - location, + LalrpopError::InvalidToken { location } => { + ParseError::new(ParseErrorType::Eof, location, source_path) + } + LalrpopError::ExtraToken { token } => { + ParseError::new(ParseErrorType::ExtraToken(token.1), token.0, source_path) + } + LalrpopError::User { error } => ParseError::new( + ParseErrorType::Lexical(error.error), + error.location, source_path, - }, - LalrpopError::ExtraToken { token } => ParseError { - error: ParseErrorType::ExtraToken(token.1), - location: token.0, - source_path, - }, - LalrpopError::User { error } => ParseError { - error: ParseErrorType::Lexical(error.error), - location: error.location, - source_path, - }, + ), LalrpopError::UnrecognizedToken { token, expected } => { // Hacky, but it's how CPython does it. See PyParser_AddToken, // in particular "Only one possible expected token" comment. let expected = (expected.len() == 1).then(|| expected[0].clone()); - ParseError { - error: ParseErrorType::UnrecognizedToken(token.1, expected), - location: token.0, + ParseError::new( + ParseErrorType::UnrecognizedToken(token.1, expected), + token.0, source_path, - } + ) + } + LalrpopError::UnrecognizedEOF { location, .. } => { + ParseError::new(ParseErrorType::Eof, location, source_path) } - LalrpopError::UnrecognizedEOF { location, .. } => ParseError { - error: ParseErrorType::Eof, - location, - source_path, - }, } } } @@ -229,9 +239,9 @@ impl ParseErrorType { } impl std::ops::Deref for ParseError { - type Target = ParseErrorType; + type Target = rustpython_compiler_core::Error; fn deref(&self) -> &Self::Target { - &self.error + &self.0 } } diff --git a/parser/src/fstring.rs b/parser/src/fstring.rs index 11d75a09bd..dc170635a5 100644 --- a/parser/src/fstring.rs +++ b/parser/src/fstring.rs @@ -186,7 +186,7 @@ impl<'a> FStringParser<'a> { vec![self.expr(ExprKind::FormattedValue { value: Box::new( parse_fstring_expr(&expression) - .map_err(|e| InvalidExpression(Box::new(e.error)))?, + .map_err(|e| InvalidExpression(Box::new(e.into())))?, ), conversion: conversion as _, format_spec: spec, @@ -204,7 +204,7 @@ impl<'a> FStringParser<'a> { self.expr(ExprKind::FormattedValue { value: Box::new( parse_fstring_expr(&expression) - .map_err(|e| InvalidExpression(Box::new(e.error)))?, + .map_err(|e| InvalidExpression(Box::new(e.into())))?, ), conversion: (if conversion == ConversionFlag::None && spec.is_none() {