mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
- Rewrite compile_dict to preserve insertion order with ** unpacking - Fix function call error messages to include function name and keyword-only argument counts - Fix missing keyword-only argument error to list all missing args - Fix starred expression error messages to match CPython - Fix "cannot unpack non-iterable" error message - Remove resolved expected failure markers in test_extcall and test_unpack_ex
177 lines
5.7 KiB
Rust
177 lines
5.7 KiB
Rust
use alloc::fmt;
|
|
use core::fmt::Display;
|
|
use rustpython_compiler_core::SourceLocation;
|
|
use thiserror::Error;
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub enum PatternUnreachableReason {
|
|
NameCapture,
|
|
Wildcard,
|
|
}
|
|
|
|
impl Display for PatternUnreachableReason {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Self::NameCapture => write!(f, "name capture"),
|
|
Self::Wildcard => write!(f, "wildcard"),
|
|
}
|
|
}
|
|
}
|
|
|
|
// pub type CodegenError = rustpython_parser_core::source_code::LocatedError<CodegenErrorType>;
|
|
|
|
#[derive(Error, Debug)]
|
|
pub struct CodegenError {
|
|
pub location: Option<SourceLocation>,
|
|
#[source]
|
|
pub error: CodegenErrorType,
|
|
pub source_path: String,
|
|
}
|
|
|
|
impl fmt::Display for CodegenError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
// TODO:
|
|
self.error.fmt(f)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
#[non_exhaustive]
|
|
pub enum InternalError {
|
|
StackOverflow,
|
|
StackUnderflow,
|
|
MissingSymbol(String),
|
|
}
|
|
|
|
impl Display for InternalError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Self::StackOverflow => write!(f, "stack overflow"),
|
|
Self::StackUnderflow => write!(f, "stack underflow"),
|
|
Self::MissingSymbol(s) => write!(
|
|
f,
|
|
"The symbol '{s}' must be present in the symbol table, even when it is undefined in python."
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
#[non_exhaustive]
|
|
pub enum CodegenErrorType {
|
|
/// Invalid assignment, cannot store value in target.
|
|
Assign(&'static str),
|
|
/// Invalid delete
|
|
Delete(&'static str),
|
|
SyntaxError(String),
|
|
/// Multiple `*` detected
|
|
MultipleStarArgs,
|
|
/// Misplaced `*` expression
|
|
InvalidStarExpr,
|
|
/// Break statement outside of loop.
|
|
InvalidBreak,
|
|
/// Continue statement outside of loop.
|
|
InvalidContinue,
|
|
InvalidReturn,
|
|
InvalidYield,
|
|
InvalidYieldFrom,
|
|
InvalidAwait,
|
|
InvalidAsyncFor,
|
|
InvalidAsyncWith,
|
|
InvalidAsyncComprehension,
|
|
AsyncYieldFrom,
|
|
AsyncReturnValue,
|
|
InvalidFuturePlacement,
|
|
InvalidFutureFeature(String),
|
|
FunctionImportStar,
|
|
TooManyStarUnpack,
|
|
EmptyWithItems,
|
|
EmptyWithBody,
|
|
ForbiddenName,
|
|
DuplicateStore(String),
|
|
UnreachablePattern(PatternUnreachableReason),
|
|
RepeatedAttributePattern,
|
|
ConflictingNameBindPattern,
|
|
/// break/continue/return inside except* block
|
|
BreakContinueReturnInExceptStar,
|
|
NotImplementedYet, // RustPython marker for unimplemented features
|
|
}
|
|
|
|
impl core::error::Error for CodegenErrorType {}
|
|
|
|
impl fmt::Display for CodegenErrorType {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
use CodegenErrorType::*;
|
|
match self {
|
|
Assign(target) => write!(f, "cannot assign to {target}"),
|
|
Delete(target) => write!(f, "cannot delete {target}"),
|
|
SyntaxError(err) => write!(f, "{}", err.as_str()),
|
|
MultipleStarArgs => {
|
|
write!(f, "multiple starred expressions in assignment")
|
|
}
|
|
InvalidStarExpr => write!(f, "can't use starred expression here"),
|
|
InvalidBreak => write!(f, "'break' outside loop"),
|
|
InvalidContinue => write!(f, "'continue' outside loop"),
|
|
InvalidReturn => write!(f, "'return' outside function"),
|
|
InvalidYield => write!(f, "'yield' outside function"),
|
|
InvalidYieldFrom => write!(f, "'yield from' outside function"),
|
|
InvalidAwait => write!(f, "'await' outside async function"),
|
|
InvalidAsyncFor => write!(f, "'async for' outside async function"),
|
|
InvalidAsyncWith => write!(f, "'async with' outside async function"),
|
|
InvalidAsyncComprehension => {
|
|
write!(
|
|
f,
|
|
"asynchronous comprehension outside of an asynchronous function"
|
|
)
|
|
}
|
|
AsyncYieldFrom => write!(f, "'yield from' inside async function"),
|
|
AsyncReturnValue => {
|
|
write!(f, "'return' with value inside async generator")
|
|
}
|
|
InvalidFuturePlacement => write!(
|
|
f,
|
|
"from __future__ imports must occur at the beginning of the file"
|
|
),
|
|
InvalidFutureFeature(feat) => {
|
|
write!(f, "future feature {feat} is not defined")
|
|
}
|
|
FunctionImportStar => {
|
|
write!(f, "import * only allowed at module level")
|
|
}
|
|
TooManyStarUnpack => {
|
|
write!(f, "too many expressions in star-unpacking assignment")
|
|
}
|
|
EmptyWithItems => {
|
|
write!(f, "empty items on With")
|
|
}
|
|
EmptyWithBody => {
|
|
write!(f, "empty body on With")
|
|
}
|
|
ForbiddenName => {
|
|
write!(f, "forbidden attribute name")
|
|
}
|
|
DuplicateStore(s) => {
|
|
write!(f, "duplicate store {s}")
|
|
}
|
|
UnreachablePattern(reason) => {
|
|
write!(f, "{reason} makes remaining patterns unreachable")
|
|
}
|
|
RepeatedAttributePattern => {
|
|
write!(f, "attribute name repeated in class pattern")
|
|
}
|
|
ConflictingNameBindPattern => {
|
|
write!(f, "alternative patterns bind different names")
|
|
}
|
|
BreakContinueReturnInExceptStar => {
|
|
write!(
|
|
f,
|
|
"'break', 'continue' and 'return' cannot appear in an except* block"
|
|
)
|
|
}
|
|
NotImplementedYet => {
|
|
write!(f, "RustPython does not implement this feature yet")
|
|
}
|
|
}
|
|
}
|
|
}
|