diff --git a/crates/cairo-lang-executable/Cargo.toml b/crates/cairo-lang-executable/Cargo.toml index f4cca0b8e0e..db524026cdb 100644 --- a/crates/cairo-lang-executable/Cargo.toml +++ b/crates/cairo-lang-executable/Cargo.toml @@ -10,6 +10,7 @@ description = "Cairo executable artifact." anyhow.workspace = true cairo-lang-casm = { path = "../cairo-lang-casm", version = "~2.9.2", default-features = true, features = ["serde"] } cairo-lang-compiler = { path = "../cairo-lang-compiler", version = "~2.9.2" } +cairo-lang-debug = { path = "../cairo-lang-debug", version = "~2.9.2" } cairo-lang-defs = { path = "../cairo-lang-defs", version = "~2.9.2" } cairo-lang-filesystem = { path = "../cairo-lang-filesystem", version = "~2.9.2" } cairo-lang-lowering = { path = "../cairo-lang-lowering", version = "~2.9.2" } diff --git a/crates/cairo-lang-executable/src/compile.rs b/crates/cairo-lang-executable/src/compile.rs index 8bc47c6a685..fe928e12ccc 100644 --- a/crates/cairo-lang-executable/src/compile.rs +++ b/crates/cairo-lang-executable/src/compile.rs @@ -5,6 +5,7 @@ use anyhow::{Context, Result}; use cairo_lang_compiler::db::RootDatabase; use cairo_lang_compiler::diagnostics::DiagnosticsReporter; use cairo_lang_compiler::project::setup_project; +use cairo_lang_debug::debug::DebugWithDb; use cairo_lang_filesystem::cfg::{Cfg, CfgSet}; use cairo_lang_filesystem::ids::CrateId; use cairo_lang_lowering::ids::ConcreteFunctionWithBodyId; @@ -141,13 +142,29 @@ pub fn compile_executable_function_in_prepared_db( mut diagnostics_reporter: DiagnosticsReporter<'_>, ) -> Result { diagnostics_reporter.ensure(db)?; - let SierraProgramWithDebug { program: sierra_program, debug_info: _ } = Arc::unwrap_or_clone( + let SierraProgramWithDebug { program: sierra_program, debug_info } = Arc::unwrap_or_clone( db.get_sierra_program_for_functions(vec![executable]) .ok() .with_context(|| "Compilation failed without any diagnostics.")?, ); + let executable_func = sierra_program.funcs[0].clone(); - let builder = RunnableBuilder::new(sierra_program, None)?; + let builder = RunnableBuilder::new(sierra_program, None).map_err(|err| { + let mut locs = vec![]; + for stmt_idx in err.stmt_indices() { + if let Some(loc) = debug_info + .statements_locations + .locations + .get(&stmt_idx) + .and_then(|stmt_locs| stmt_locs.first()) + { + locs.push(format!("#{stmt_idx} {:?}", loc.diagnostic_location(db).debug(db))) + } + } + + anyhow::anyhow!("Failed to create runnable builder: {}\n{}", err, locs.join("\n")) + })?; + let wrapper = builder.create_wrapper_info(&executable_func, EntryCodeConfig::executable())?; Ok(CompiledFunction { program: builder.casm_program().clone(), wrapper }) } diff --git a/crates/cairo-lang-runnable-utils/src/builder.rs b/crates/cairo-lang-runnable-utils/src/builder.rs index 087e000fedf..8983f774d82 100644 --- a/crates/cairo-lang-runnable-utils/src/builder.rs +++ b/crates/cairo-lang-runnable-utils/src/builder.rs @@ -16,7 +16,9 @@ use cairo_lang_sierra::extensions::segment_arena::SegmentArenaType; use cairo_lang_sierra::extensions::starknet::syscalls::SystemType; use cairo_lang_sierra::extensions::{ConcreteType, NamedType}; use cairo_lang_sierra::ids::{ConcreteTypeId, GenericTypeId}; -use cairo_lang_sierra::program::{ConcreteTypeLongId, Function, Program as SierraProgram}; +use cairo_lang_sierra::program::{ + ConcreteTypeLongId, Function, Program as SierraProgram, StatementIdx, +}; use cairo_lang_sierra::program_registry::{ProgramRegistry, ProgramRegistryError}; use cairo_lang_sierra_ap_change::ApChangeError; use cairo_lang_sierra_gas::CostError; @@ -50,6 +52,15 @@ pub enum BuildError { ApChangeError(#[from] ApChangeError), } +impl BuildError { + pub fn stmt_indices(&self) -> Vec { + match self { + BuildError::SierraCompilationError(err) => err.stmt_indices(), + _ => vec![], + } + } +} + /// Builder for creating a runnable CASM program from Sierra code. pub struct RunnableBuilder { /// The sierra program. diff --git a/crates/cairo-lang-sierra-to-casm/src/annotations.rs b/crates/cairo-lang-sierra-to-casm/src/annotations.rs index 271f7753835..c01b62154d7 100644 --- a/crates/cairo-lang-sierra-to-casm/src/annotations.rs +++ b/crates/cairo-lang-sierra-to-casm/src/annotations.rs @@ -6,7 +6,7 @@ use cairo_lang_sierra::ids::{ConcreteTypeId, FunctionId, VarId}; use cairo_lang_sierra::program::{BranchInfo, Function, StatementIdx}; use cairo_lang_sierra_type_size::TypeSizeMap; use cairo_lang_utils::unordered_hash_set::UnorderedHashSet; -use itertools::zip_eq; +use itertools::{chain, zip_eq}; use thiserror::Error; use crate::environment::ap_tracking::update_ap_tracking; @@ -93,6 +93,26 @@ pub enum AnnotationError { }, } +impl AnnotationError { + pub fn stmt_indices(&self) -> Vec { + match self { + AnnotationError::ApChangeError { + source_statement_idx, + destination_statement_idx, + introduction_point, + .. + } => chain!( + [source_statement_idx, destination_statement_idx], + &introduction_point.source_statement_idx, + [&introduction_point.destination_statement_idx] + ) + .cloned() + .collect(), + _ => vec![], + } + } +} + /// Error representing an inconsistency in the references annotations. #[derive(Error, Debug, Eq, PartialEq)] pub enum InconsistentReferenceError { diff --git a/crates/cairo-lang-sierra-to-casm/src/compiler.rs b/crates/cairo-lang-sierra-to-casm/src/compiler.rs index 0e9857dc031..080ba76b08e 100644 --- a/crates/cairo-lang-sierra-to-casm/src/compiler.rs +++ b/crates/cairo-lang-sierra-to-casm/src/compiler.rs @@ -85,6 +85,15 @@ pub enum CompilationError { MetadataNegativeGasVariable, } +impl CompilationError { + pub fn stmt_indices(&self) -> Vec { + match self { + CompilationError::AnnotationError(err) => err.stmt_indices(), + _ => vec![], + } + } +} + /// Configuration for the Sierra to CASM compilation. #[derive(Debug, Eq, PartialEq, Clone, Copy)] pub struct SierraToCasmConfig {