1use alloc::fmt;
2use core::fmt::Display;
3use rustpython_compiler_core::SourceLocation;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
9pub struct CodegenError {
10 pub location: Option<SourceLocation>,
11 pub end_location: Option<SourceLocation>,
12 #[source]
13 pub error: CodegenErrorType,
14 pub source_path: String,
15}
16
17impl fmt::Display for CodegenError {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 self.error.fmt(f)
21 }
22}
23
24#[derive(Debug)]
25#[non_exhaustive]
26pub enum InternalError {
27 StackUnderflow,
28 InconsistentStackDepth,
29 InvalidStackEffect,
30 MalformedControlFlowGraph,
31 MissingSymbol(String),
32 ConstIndexOutOfRange { index: usize, len: usize },
33}
34
35impl Display for InternalError {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match self {
38 Self::StackUnderflow => write!(f, "Invalid CFG, stack underflow"),
39 Self::InconsistentStackDepth => write!(f, "Invalid CFG, inconsistent stackdepth"),
40 Self::InvalidStackEffect => write!(f, "Invalid stack effect"),
41 Self::MalformedControlFlowGraph => write!(f, "malformed control flow graph."),
42 Self::MissingSymbol(s) => write!(
43 f,
44 "The symbol '{s}' must be present in the symbol table, even when it is undefined in python."
45 ),
46 Self::ConstIndexOutOfRange { index, len } => {
47 write!(
48 f,
49 "LOAD_CONST index {index} is out of range for consts (len={len})"
50 )
51 }
52 }
53 }
54}
55
56#[derive(Debug)]
57#[non_exhaustive]
58pub enum CodegenErrorType {
59 Assign(&'static str),
61 Delete(&'static str),
63 SyntaxError(String),
64 MultipleStarArgs,
66 MultipleStarredExpressionsInSequencePattern,
67 MultipleStarredNamesInSequencePattern,
68 InvalidStarExpr,
70 InvalidBreak,
72 InvalidContinue,
74 InvalidReturn,
75 InvalidYield,
76 InvalidYieldFrom,
77 InvalidAwait,
78 InvalidAsyncFor,
79 InvalidAsyncWith,
80 InvalidAsyncComprehension,
81 AsyncYieldFrom,
82 AsyncReturnValue,
83 InvalidFuturePlacement,
84 InvalidFutureFeature(String),
85 InvalidFutureBraces,
86 RecursionError,
87 TooManyStarUnpack,
88 TooManyExpressionsInStarUnpackingSequencePattern,
89 EmptyWithItems,
90 EmptyWithBody,
91 ForbiddenName,
92 DuplicateStore(String),
93 UnreachableWildcardPattern,
94 UnreachableNameCapturePattern(String),
95 RepeatedAttributePattern(String),
96 ConflictingNameBindPattern,
97 BreakContinueReturnInExceptStar,
99}
100
101impl core::error::Error for CodegenErrorType {}
102
103impl fmt::Display for CodegenErrorType {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 match self {
106 Self::Assign(target) => write!(f, "cannot assign to {target}"),
107 Self::Delete(target) => write!(f, "cannot delete {target}"),
108 Self::SyntaxError(err) => write!(f, "{}", err.as_str()),
109 Self::MultipleStarArgs => {
110 write!(f, "multiple starred expressions in assignment")
111 }
112 Self::MultipleStarredExpressionsInSequencePattern => {
113 write!(f, "multiple starred expressions in sequence pattern")
114 }
115 Self::MultipleStarredNamesInSequencePattern => {
116 write!(f, "multiple starred names in sequence pattern")
117 }
118 Self::InvalidStarExpr => write!(f, "can't use starred expression here"),
119 Self::InvalidBreak => write!(f, "'break' outside loop"),
120 Self::InvalidContinue => write!(f, "'continue' not properly in loop"),
121 Self::InvalidReturn => write!(f, "'return' outside function"),
122 Self::InvalidYield => write!(f, "'yield' outside function"),
123 Self::InvalidYieldFrom => write!(f, "'yield from' outside function"),
124 Self::InvalidAwait => write!(f, "'await' outside async function"),
125 Self::InvalidAsyncFor => write!(f, "'async for' outside async function"),
126 Self::InvalidAsyncWith => write!(f, "'async with' outside async function"),
127 Self::InvalidAsyncComprehension => {
128 write!(
129 f,
130 "asynchronous comprehension outside of an asynchronous function"
131 )
132 }
133 Self::AsyncYieldFrom => write!(f, "'yield from' inside async function"),
134 Self::AsyncReturnValue => write!(f, "'return' with value in async generator"),
135 Self::InvalidFuturePlacement => write!(
136 f,
137 "from __future__ imports must occur at the beginning of the file"
138 ),
139 Self::InvalidFutureFeature(feat) => {
140 write!(f, "future feature {feat} is not defined")
141 }
142 Self::InvalidFutureBraces => write!(f, "not a chance"),
143 Self::RecursionError => {
144 write!(f, "maximum recursion depth exceeded during compilation")
145 }
146 Self::TooManyStarUnpack => {
147 write!(f, "too many expressions in star-unpacking assignment")
148 }
149 Self::TooManyExpressionsInStarUnpackingSequencePattern => {
150 write!(f, "too many expressions in star-unpacking sequence pattern")
151 }
152 Self::EmptyWithItems => {
153 write!(f, "empty items on With")
154 }
155 Self::EmptyWithBody => {
156 write!(f, "empty body on With")
157 }
158 Self::ForbiddenName => {
159 write!(f, "forbidden attribute name")
160 }
161 Self::DuplicateStore(s) => write!(f, "multiple assignments to name '{s}' in pattern"),
162 Self::UnreachableWildcardPattern => {
163 write!(f, "wildcard makes remaining patterns unreachable")
164 }
165 Self::UnreachableNameCapturePattern(name) => {
166 write!(
167 f,
168 "name capture '{name}' makes remaining patterns unreachable"
169 )
170 }
171 Self::RepeatedAttributePattern(name) => {
172 write!(f, "attribute name repeated in class pattern: {name}")
173 }
174 Self::ConflictingNameBindPattern => {
175 write!(f, "alternative patterns bind different names")
176 }
177 Self::BreakContinueReturnInExceptStar => {
178 write!(
179 f,
180 "'break', 'continue' and 'return' cannot appear in an except* block"
181 )
182 }
183 }
184 }
185}