Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
33ee349
feat: add CLI argument for debugging comptime blocks for a particular…
michaeljklein Jun 6, 2024
695194c
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jun 6, 2024
53b0a8b
basic debugging working w/o filtering, added handling for each of the…
michaeljklein Jun 7, 2024
289afaa
add method to find FileId by path suffix, cleanup and make methods fo…
michaeljklein Jun 7, 2024
1d8ba31
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jun 7, 2024
ebed5f8
cargo clippy/fmt
michaeljklein Jun 7, 2024
1bc05ea
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jun 7, 2024
8e518c3
cleanup TODO's
michaeljklein Jun 7, 2024
f1bdb57
patch change from merging master
michaeljklein Jun 7, 2024
f7f01b3
add missing arg
michaeljklein Jun 7, 2024
52bcd04
add missing args in tests
michaeljklein Jun 7, 2024
375229e
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jun 10, 2024
6351085
Update compiler/noirc_frontend/src/hir/comptime/errors.rs
michaeljklein Jun 12, 2024
60d9ef6
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jun 12, 2024
427b1ca
Update compiler/noirc_errors/src/reporter.rs
michaeljklein Jun 14, 2024
2ae971f
Update compiler/noirc_frontend/src/elaborator/mod.rs
michaeljklein Jun 14, 2024
d225099
fix span todo
michaeljklein Jun 17, 2024
f030f38
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jul 8, 2024
32fe0ab
add debug_comptime_scope parameter where missing, use newer NamedGene…
michaeljklein Jul 8, 2024
0c76abe
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jul 8, 2024
b9f6745
make find_by_path_suffix less generic, use as_deref instead of clone,…
michaeljklein Jul 9, 2024
7658908
make functions for checking debug scope and debugging current expression
michaeljklein Jul 9, 2024
0bc2931
refactor setting up interpreter, fix triple-backtick automatic test e…
michaeljklein Jul 9, 2024
2e1cc5e
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jul 9, 2024
71ea123
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jul 9, 2024
90cab04
rename debug_comptime_scope -> debug_comptime_in_file, pass interpret…
michaeljklein Jul 9, 2024
92dc357
Merge branch 'master' into michaeljklein/debug-comptime-cli
michaeljklein Jul 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/fm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ license.workspace = true

[dependencies]
codespan-reporting.workspace = true
iter-extended.workspace = true
serde.workspace = true

[dev-dependencies]
Expand Down
21 changes: 21 additions & 0 deletions compiler/fm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod file_map;

pub use file_map::{File, FileId, FileMap, PathString};

use iter_extended::vecmap;
// Re-export for the lsp
pub use codespan_reporting::files as codespan_files;

Expand Down Expand Up @@ -103,6 +104,26 @@ impl FileManager {
pub fn name_to_id(&self, file_name: PathBuf) -> Option<FileId> {
self.file_map.get_file_id(&PathString::from_path(file_name))
}

/// Find a file by its path suffix, e.g. "src/main.nr" is a suffix of
/// "some_dir/package_name/src/main.nr"`
pub fn find_by_path_suffix(&self, suffix: &str) -> Result<Option<FileId>, Vec<PathBuf>> {
let suffix_path: Vec<_> = Path::new(suffix).components().rev().collect();
let results: Vec<_> = self
.path_to_id
.iter()
.filter(|(path, _id)| {
path.components().rev().zip(suffix_path.iter()).all(|(x, y)| &x == y)
})
.collect();
if results.is_empty() {
Ok(None)
} else if results.len() == 1 {
Ok(Some(*results[0].1))
} else {
Err(vecmap(results, |(path, _id)| path.clone()))
}
}
}

pub trait NormalizePath {
Expand Down
11 changes: 10 additions & 1 deletion compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ pub struct CompileOptions {
#[arg(long, hide = true)]
pub use_legacy: bool,

/// Enable printing results of comptime evaluation: provide a path suffix
/// for the module to debug, e.g. "package_name/src/main.nr"
#[arg(long)]
pub debug_comptime_scope: Option<String>,
Comment thread
michaeljklein marked this conversation as resolved.
Outdated

/// Outputs the paths to any modified artifacts
#[arg(long, hide = true)]
pub show_artifact_paths: bool,
Expand Down Expand Up @@ -258,12 +263,14 @@ pub fn check_crate(
deny_warnings: bool,
disable_macros: bool,
use_legacy: bool,
debug_comptime_scope: Option<&str>,
) -> CompilationResult<()> {
let macros: &[&dyn MacroProcessor] =
if disable_macros { &[] } else { &[&aztec_macros::AztecMacro as &dyn MacroProcessor] };

let mut errors = vec![];
let diagnostics = CrateDefMap::collect_defs(crate_id, context, use_legacy, macros);
let diagnostics =
CrateDefMap::collect_defs(crate_id, context, use_legacy, debug_comptime_scope, macros);
errors.extend(diagnostics.into_iter().map(|(error, file_id)| {
let diagnostic = CustomDiagnostic::from(&error);
diagnostic.in_file(file_id)
Expand Down Expand Up @@ -301,6 +308,7 @@ pub fn compile_main(
options.deny_warnings,
options.disable_macros,
options.use_legacy,
options.debug_comptime_scope.as_deref(),
)?;

let main = context.get_main_function(&crate_id).ok_or_else(|| {
Expand Down Expand Up @@ -342,6 +350,7 @@ pub fn compile_contract(
options.deny_warnings,
options.disable_macros,
options.use_legacy,
options.debug_comptime_scope.as_deref(),
)?;

// TODO: We probably want to error if contracts is empty
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_driver/tests/stdlib_warnings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn stdlib_does_not_produce_constant_warnings() -> Result<(), ErrorsAndWarnings>
let root_crate_id = prepare_crate(&mut context, file_name);

let ((), warnings) =
noirc_driver::check_crate(&mut context, root_crate_id, false, false, false)?;
noirc_driver::check_crate(&mut context, root_crate_id, false, false, false, None)?;

assert_eq!(warnings, Vec::new(), "stdlib is producing {} warnings", warnings.len());

Expand Down
49 changes: 41 additions & 8 deletions compiler/noirc_errors/src/reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub enum DiagnosticKind {
Error,
Bug,
Warning,
Info,
}

/// A count of errors that have been already reported to stderr
Expand All @@ -37,30 +38,57 @@ impl CustomDiagnostic {
}
}

pub fn simple_error(
fn simple_with_kind(
primary_message: String,
secondary_message: String,
secondary_span: Span,
kind: DiagnosticKind,
) -> CustomDiagnostic {
CustomDiagnostic {
message: primary_message,
secondaries: vec![CustomLabel::new(secondary_message, secondary_span)],
notes: Vec::new(),
kind: DiagnosticKind::Error,
kind,
}
}

pub fn simple_error(
primary_message: String,
secondary_message: String,
secondary_span: Span,
) -> CustomDiagnostic {
Self::simple_with_kind(
primary_message,
secondary_message,
secondary_span,
DiagnosticKind::Error,
)
}

pub fn simple_warning(
primary_message: String,
secondary_message: String,
secondary_span: Span,
) -> CustomDiagnostic {
CustomDiagnostic {
message: primary_message,
secondaries: vec![CustomLabel::new(secondary_message, secondary_span)],
notes: Vec::new(),
kind: DiagnosticKind::Warning,
}
Self::simple_with_kind(
primary_message,
secondary_message,
secondary_span,
DiagnosticKind::Warning,
)
}

pub fn simple_info(
primary_message: String,
secondary_message: String,
secondary_span: Span,
) -> CustomDiagnostic {
Self::simple_with_kind(
primary_message,
secondary_message,
secondary_span,
DiagnosticKind::Info,
)
}

pub fn simple_bug(
Expand Down Expand Up @@ -96,6 +124,10 @@ impl CustomDiagnostic {
matches!(self.kind, DiagnosticKind::Warning)
}

pub fn is_info(&self) -> bool {
matches!(self.kind, DiagnosticKind::Info)
}

pub fn is_bug(&self) -> bool {
matches!(self.kind, DiagnosticKind::Bug)
}
Expand Down Expand Up @@ -191,6 +223,7 @@ fn convert_diagnostic(
) -> Diagnostic<fm::FileId> {
let diagnostic = match (cd.kind, deny_warnings) {
(DiagnosticKind::Warning, false) => Diagnostic::warning(),
(DiagnosticKind::Info, _) => Diagnostic::note(),
(DiagnosticKind::Bug, ..) => Diagnostic::bug(),
_ => Diagnostic::error(),
};
Expand Down
42 changes: 26 additions & 16 deletions compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ use crate::{
UnresolvedTypeExpression,
},
hir::{
comptime::{self, Interpreter, InterpreterError},
comptime::{self, InterpreterError},
resolution::{errors::ResolverError, resolver::LambdaContext},
type_check::TypeCheckError,
},
hir_def::{
expr::{
HirArrayLiteral, HirBinaryOp, HirBlockExpression, HirCallExpression, HirCastExpression,
HirConstructorExpression, HirIfExpression, HirIndexExpression, HirInfixExpression,
HirLambda, HirMemberAccess, HirMethodCallExpression, HirMethodReference,
HirPrefixExpression,
HirConstructorExpression, HirExpression, HirIfExpression, HirIndexExpression,
HirInfixExpression, HirLambda, HirMemberAccess, HirMethodCallExpression,
HirMethodReference, HirPrefixExpression,
},
traits::TraitConstraint,
},
macros_api::{
BlockExpression, CallExpression, CastExpression, Expression, ExpressionKind, HirExpression,
HirLiteral, HirStatement, Ident, IndexExpression, Literal, MemberAccessExpression,
BlockExpression, CallExpression, CastExpression, Expression, ExpressionKind, HirLiteral,
HirStatement, Ident, IndexExpression, Literal, MemberAccessExpression,
MethodCallExpression, PrefixExpression,
},
node_interner::{DefinitionKind, ExprId, FuncId, ReferenceId},
Expand Down Expand Up @@ -675,12 +675,20 @@ impl<'context> Elaborator<'context> {
// call is not yet solved for.
self.function_context.push(Default::default());
let (block, _typ) = self.elaborate_block_expression(block);
self.check_and_pop_function_context();

let mut interpreter =
Interpreter::new(self.interner, &mut self.comptime_scopes, self.crate_id);
self.check_and_pop_function_context();
let mut interpreter_errors = vec![];
let mut interpreter = self.setup_interpreter(&mut interpreter_errors);
let value = interpreter.evaluate_block(block);
self.inline_comptime_value(value, span)
self.include_interpreter_errors(&mut interpreter_errors);
let (id, typ) = self.inline_comptime_value(value, span);

let location = self.interner.id_location(id);
self.debug_comptime(location, |interner| {
interner.expression(&id).to_display_ast(interner, location.span).kind
});

(id, typ)
}

pub(super) fn inline_comptime_value(
Expand Down Expand Up @@ -751,9 +759,9 @@ impl<'context> Elaborator<'context> {
}
};

let mut interpreter =
Interpreter::new(self.interner, &mut self.comptime_scopes, self.crate_id);

let file = self.file;
let mut interpreter_errors = vec![];
let mut interpreter = self.setup_interpreter(&mut interpreter_errors);
let mut comptime_args = Vec::new();
let mut errors = Vec::new();

Expand All @@ -763,17 +771,19 @@ impl<'context> Elaborator<'context> {
let location = interpreter.interner.expr_location(&argument);
comptime_args.push((arg, location));
}
Err(error) => errors.push((error.into(), self.file)),
Err(error) => errors.push((error.into(), file)),
}
}

let bindings = interpreter.interner.get_instantiation_bindings(func).clone();
let result = interpreter.call_function(function, comptime_args, bindings, location);
self.include_interpreter_errors(&mut interpreter_errors);

if !errors.is_empty() {
self.errors.append(&mut errors);
return None;
}

let bindings = interpreter.interner.get_instantiation_bindings(func).clone();
let result = interpreter.call_function(function, comptime_args, bindings, location);
let (expr_id, typ) = self.inline_comptime_value(result, location.span);
Some((self.interner.expression(&expr_id), typ))
}
Expand Down
Loading