@@ -41,8 +41,10 @@ use rustpython_compiler_core::{
4141} ;
4242use rustpython_compiler_source:: SourceCode ;
4343// use rustpython_parser_core::source_code::{LineNumber, SourceLocation};
44+ use crate :: error:: InternalError ;
4445use std:: borrow:: Cow ;
4546
47+ pub ( crate ) type InternalResult < T > = Result < T , InternalError > ;
4648type CompileResult < T > = Result < T , CodegenError > ;
4749
4850#[ derive( PartialEq , Eq , Clone , Copy ) ]
@@ -210,6 +212,54 @@ macro_rules! emit {
210212 } ;
211213}
212214
215+ fn eprint_location ( zelf : & Compiler < ' _ > ) {
216+ let start = zelf
217+ . source_code
218+ . source_location ( zelf. current_source_range . start ( ) ) ;
219+ let end = zelf
220+ . source_code
221+ . source_location ( zelf. current_source_range . end ( ) ) ;
222+ eprintln ! (
223+ "LOCATION: {} from {}:{} to {}:{}" ,
224+ zelf. source_code. path. to_owned( ) ,
225+ start. row,
226+ start. column,
227+ end. row,
228+ end. column
229+ ) ;
230+ }
231+
232+ /// Better traceback for internal error
233+ fn unwrap_internal < T > ( zelf : & Compiler < ' _ > , r : InternalResult < T > ) -> T {
234+ if let Err ( ref r_err) = r {
235+ eprintln ! ( "=== CODEGEN PANIC INFO ===" ) ;
236+ eprintln ! ( "This IS an internal error: {}" , r_err) ;
237+ eprint_location ( zelf) ;
238+ eprintln ! ( "=== END PANIC INFO ===" ) ;
239+ }
240+ r. unwrap ( )
241+ }
242+
243+ fn compiler_unwrap_option < T > ( zelf : & Compiler < ' _ > , o : Option < T > ) -> T {
244+ if o. is_none ( ) {
245+ eprintln ! ( "=== CODEGEN PANIC INFO ===" ) ;
246+ eprintln ! ( "This IS an internal error, an option was unwrapped during codegen" ) ;
247+ eprint_location ( zelf) ;
248+ eprintln ! ( "=== END PANIC INFO ===" ) ;
249+ }
250+ o. unwrap ( )
251+ }
252+
253+ // fn compiler_result_unwrap<T, E: std::fmt::Debug>(zelf: &Compiler<'_>, result: Result<T, E>) -> T {
254+ // if result.is_err() {
255+ // eprintln!("=== CODEGEN PANIC INFO ===");
256+ // eprintln!("This IS an internal error, an result was unwrapped during codegen");
257+ // eprint_location(zelf);
258+ // eprintln!("=== END PANIC INFO ===");
259+ // }
260+ // result.unwrap()
261+ // }
262+
213263/// The pattern context holds information about captured names and jump targets.
214264#[ derive( Clone ) ]
215265pub struct PatternContext {
@@ -372,10 +422,9 @@ impl Compiler<'_> {
372422 fn pop_code_object ( & mut self ) -> CodeObject {
373423 let table = self . pop_symbol_table ( ) ;
374424 assert ! ( table. sub_tables. is_empty( ) ) ;
375- self . code_stack
376- . pop ( )
377- . unwrap ( )
378- . finalize_code ( self . opts . optimize )
425+ let pop = self . code_stack . pop ( ) ;
426+ let stack_top = compiler_unwrap_option ( self , pop) ;
427+ unwrap_internal ( self , stack_top. finalize_code ( self . opts . optimize ) )
379428 }
380429
381430 // could take impl Into<Cow<str>>, but everything is borrowed from ast structs; we never
@@ -482,7 +531,8 @@ impl Compiler<'_> {
482531 self . current_block ( ) . instructions . pop ( ) ; // pop Instruction::Pop
483532 }
484533 Stmt :: FunctionDef ( _) | Stmt :: ClassDef ( _) => {
485- let store_inst = self . current_block ( ) . instructions . pop ( ) . unwrap ( ) ; // pop Instruction::Store
534+ let pop_instructions = self . current_block ( ) . instructions . pop ( ) ;
535+ let store_inst = compiler_unwrap_option ( self , pop_instructions) ; // pop Instruction::Store
486536 emit ! ( self , Instruction :: Duplicate ) ;
487537 self . current_block ( ) . instructions . push ( store_inst) ;
488538 }
@@ -540,8 +590,11 @@ impl Compiler<'_> {
540590 self . check_forbidden_name ( & name, usage) ?;
541591
542592 let symbol_table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
543- let symbol = symbol_table. lookup ( name. as_ref ( ) ) . unwrap_or_else ( ||
544- unreachable ! ( "the symbol '{name}' should be present in the symbol table, even when it is undefined in python." ) ,
593+ let symbol = unwrap_internal (
594+ self ,
595+ symbol_table
596+ . lookup ( name. as_ref ( ) )
597+ . ok_or_else ( || InternalError :: MissingSymbol ( name. to_string ( ) ) ) ,
545598 ) ;
546599 let info = self . code_stack . last_mut ( ) . unwrap ( ) ;
547600 let mut cache = & mut info. name_cache ;
@@ -1476,12 +1529,12 @@ impl Compiler<'_> {
14761529 }
14771530 for var in & * code. freevars {
14781531 let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
1479- let symbol = table . lookup ( var ) . unwrap_or_else ( || {
1480- panic ! (
1481- "couldn't look up var {} in {} in {}" ,
1482- var , code . obj_name , self . source_code . path
1483- )
1484- } ) ;
1532+ let symbol = unwrap_internal (
1533+ self ,
1534+ table
1535+ . lookup ( var )
1536+ . ok_or_else ( || InternalError :: MissingSymbol ( var . to_owned ( ) ) ) ,
1537+ ) ;
14851538 let parent_code = self . code_stack . last ( ) . unwrap ( ) ;
14861539 let vars = match symbol. scope {
14871540 SymbolScope :: Free => & parent_code. freevar_cache ,
@@ -1564,8 +1617,11 @@ impl Compiler<'_> {
15641617
15651618 // Check if the class is declared global
15661619 let symbol_table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
1567- let symbol = symbol_table. lookup ( name. as_ref ( ) ) . expect (
1568- "The symbol must be present in the symbol table, even when it is undefined in python." ,
1620+ let symbol = unwrap_internal (
1621+ self ,
1622+ symbol_table
1623+ . lookup ( name. as_ref ( ) )
1624+ . ok_or_else ( || InternalError :: MissingSymbol ( name. to_owned ( ) ) ) ,
15691625 ) ;
15701626 let mut global_path_prefix = Vec :: new ( ) ;
15711627 if symbol. scope == SymbolScope :: GlobalExplicit {
0 commit comments