@@ -42,7 +42,9 @@ use rustpython_compiler_core::{
4242use rustpython_compiler_source:: SourceCode ;
4343// use rustpython_parser_core::source_code::{LineNumber, SourceLocation};
4444use std:: borrow:: Cow ;
45+ use crate :: error:: InternalError ;
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,43 @@ macro_rules! emit {
210212 } ;
211213}
212214
215+ fn print_location ( zelf : & mut Compiler ) {
216+ let start = zelf. source_code . source_location ( zelf. current_source_range . start ( ) ) ;
217+ let end = zelf. source_code . source_location ( zelf. current_source_range . end ( ) ) ;
218+ eprintln ! ( "LOCATION: {} from {}:{} to {}:{}" , zelf. source_code. path. to_owned( ) , start. row, start. column, end. row, end. column) ;
219+ }
220+
221+ /// Better traceback for internal error
222+ fn unwrap_internal < T > ( zelf : & mut Compiler , r : InternalResult < T > ) -> T {
223+ if let Err ( r_err) = r {
224+ eprintln ! ( "=== CODEGEN PANIC INFO ===" ) ;
225+ eprintln ! ( "This IS an internal error: {}" , r_err) ;
226+ print_location ( zelf) ;
227+ eprintln ! ( "=== END PANIC INFO ===" ) ;
228+ }
229+ r. unwrap ( )
230+ }
231+
232+ fn compiler_unwrap_option < T > ( zelf : & mut Compiler , o : Option < T > ) -> T {
233+ if let None = o {
234+ eprintln ! ( "=== CODEGEN PANIC INFO ===" ) ;
235+ eprintln ! ( "This IS an internal error, an option was unwrapped during codegen" ) ;
236+ print_location ( zelf) ;
237+ eprintln ! ( "=== END PANIC INFO ===" ) ;
238+ }
239+ o. unwrap ( )
240+ }
241+
242+ fn compiler_result_unwrap < T , E > ( zelf : & mut Compiler , result : Result < T , E > ) -> T {
243+ if let Err ( r_err) = r {
244+ eprintln ! ( "=== CODEGEN PANIC INFO ===" ) ;
245+ eprintln ! ( "This IS an internal error, an result was unwrapped during codegen" ) ;
246+ print_location ( zelf) ;
247+ eprintln ! ( "=== END PANIC INFO ===" ) ;
248+ }
249+ r. unwrap ( )
250+ }
251+
213252/// The pattern context holds information about captured names and jump targets.
214253#[ derive( Clone ) ]
215254pub struct PatternContext {
@@ -372,9 +411,8 @@ impl Compiler<'_> {
372411 fn pop_code_object ( & mut self ) -> CodeObject {
373412 let table = self . pop_symbol_table ( ) ;
374413 assert ! ( table. sub_tables. is_empty( ) ) ;
375- self . code_stack
376- . pop ( )
377- . unwrap ( )
414+ unwrap_internal ( self , self . code_stack
415+ . pop ( ) )
378416 . finalize_code ( self . opts . optimize )
379417 }
380418
@@ -482,7 +520,7 @@ impl Compiler<'_> {
482520 self . current_block ( ) . instructions . pop ( ) ; // pop Instruction::Pop
483521 }
484522 Stmt :: FunctionDef ( _) | Stmt :: ClassDef ( _) => {
485- let store_inst = self . current_block ( ) . instructions . pop ( ) . unwrap ( ) ; // pop Instruction::Store
523+ let store_inst = compiler_unwrap_option ( zelf , self . current_block ( ) . instructions . pop ( ) ) ; // pop Instruction::Store
486524 emit ! ( self , Instruction :: Duplicate ) ;
487525 self . current_block ( ) . instructions . push ( store_inst) ;
488526 }
@@ -540,9 +578,9 @@ impl Compiler<'_> {
540578 self . check_forbidden_name ( & name, usage) ?;
541579
542580 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." ) ,
545- ) ;
581+ let symbol = unwrap_internal ( symbol_table. lookup ( name. as_ref ( ) ) . ok_or_else ( ||
582+ InternalError :: MissingSymbol ( name. to_owned ( ) )
583+ ) ) ;
546584 let info = self . code_stack . last_mut ( ) . unwrap ( ) ;
547585 let mut cache = & mut info. name_cache ;
548586 enum NameOpType {
@@ -1476,12 +1514,9 @@ impl Compiler<'_> {
14761514 }
14771515 for var in & * code. freevars {
14781516 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- } ) ;
1517+ let symbol = unwrap_internal ( table. lookup ( var) . ok_or_else ( || {
1518+ InternalError :: MissingSymbol ( var)
1519+ } ) ) ;
14851520 let parent_code = self . code_stack . last ( ) . unwrap ( ) ;
14861521 let vars = match symbol. scope {
14871522 SymbolScope :: Free => & parent_code. freevar_cache ,
@@ -1564,9 +1599,7 @@ impl Compiler<'_> {
15641599
15651600 // Check if the class is declared global
15661601 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." ,
1569- ) ;
1602+ let symbol = unwrap_internal ( symbol_table. lookup ( name. as_ref ( ) ) . ok_or_else ( || Err ( InternalError :: MissingSymbol ( name. to_owned ( ) ) ) ) ) ;
15701603 let mut global_path_prefix = Vec :: new ( ) ;
15711604 if symbol. scope == SymbolScope :: GlobalExplicit {
15721605 global_path_prefix. append ( & mut self . qualified_path ) ;
0 commit comments