From 3f0f8f3bc50694017062597bbbfdf2078d5e1ade Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 28 Oct 2024 17:32:57 -0300 Subject: [PATCH 1/5] Fix small typo in error message --- compiler/noirc_frontend/src/hir/resolution/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs index 3c4022b58bb..a72e8978c9c 100644 --- a/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -502,7 +502,7 @@ impl<'a> From<&'a ResolverError> for Diagnostic { ResolverError::MacroIsNotComptime { span } => { Diagnostic::simple_error( "This macro call is to a non-comptime function".into(), - "Macro calls must be to comptime functions".into(), + "Macro calls must be comptime functions".into(), *span, ) }, From 6e52e22ff16fa2a09b108610dc564d0d09362f88 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 28 Oct 2024 17:36:12 -0300 Subject: [PATCH 2/5] Suggest to remove `!` at the end of the call --- .../noirc_frontend/src/hir/type_check/errors.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/type_check/errors.rs b/compiler/noirc_frontend/src/hir/type_check/errors.rs index 99de6bca434..75a9e589df5 100644 --- a/compiler/noirc_frontend/src/hir/type_check/errors.rs +++ b/compiler/noirc_frontend/src/hir/type_check/errors.rs @@ -434,11 +434,15 @@ impl<'a> From<&'a TypeCheckError> for Diagnostic { let msg = format!("Expected {expected_count} generic{expected_plural} from this function, but {actual_count} {actual_plural} provided"); Diagnostic::simple_error(msg, "".into(), *span) }, - TypeCheckError::MacroReturningNonExpr { typ, span } => Diagnostic::simple_error( - format!("Expected macro call to return a `Quoted` but found a(n) `{typ}`"), - "Macro calls must return quoted values, otherwise there is no code to insert".into(), - *span, - ), + TypeCheckError::MacroReturningNonExpr { typ, span } => { + let mut error = Diagnostic::simple_error( + format!("Expected macro call to return a `Quoted` but found a(n) `{typ}`"), + "Macro calls must return quoted values, otherwise there is no code to insert.".into(), + *span, + ); + error.add_secondary("Hint: remove the `!` from the end of the call name.".to_string(), *span); + error + }, TypeCheckError::UnsupportedTurbofishUsage { span } => { let msg = "turbofish (`::<_>`) usage at this position isn't supported yet"; Diagnostic::simple_error(msg.to_string(), "".to_string(), *span) From 17ae2d5adaf88c18d2562959bfda669b6f757bc0 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 28 Oct 2024 18:07:29 -0300 Subject: [PATCH 3/5] Code action to remove `!` from call --- tooling/lsp/src/requests/code_action.rs | 34 ++++++- .../code_action/remove_bang_from_call.rs | 97 +++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 tooling/lsp/src/requests/code_action/remove_bang_from_call.rs diff --git a/tooling/lsp/src/requests/code_action.rs b/tooling/lsp/src/requests/code_action.rs index f3e9130e17d..5c2831be7e9 100644 --- a/tooling/lsp/src/requests/code_action.rs +++ b/tooling/lsp/src/requests/code_action.rs @@ -12,7 +12,10 @@ use lsp_types::{ }; use noirc_errors::Span; use noirc_frontend::{ - ast::{ConstructorExpression, ItemVisibility, NoirTraitImpl, Path, UseTree, Visitor}, + ast::{ + CallExpression, ConstructorExpression, ItemVisibility, MethodCallExpression, NoirTraitImpl, + Path, UseTree, Visitor, + }, graph::CrateId, hir::def_map::{CrateDefMap, LocalModuleId, ModuleId}, node_interner::NodeInterner, @@ -29,6 +32,7 @@ use super::{process_request, to_lsp_location}; mod fill_struct_fields; mod implement_missing_members; mod import_or_qualify; +mod remove_bang_from_call; mod remove_unused_import; mod tests; @@ -250,4 +254,32 @@ impl<'a> Visitor for CodeActionFinder<'a> { true } + + fn visit_call_expression(&mut self, call: &CallExpression, span: Span) -> bool { + if !self.includes_span(span) { + return false; + } + + if call.is_macro_call { + self.remove_bang_from_call(call.func.span); + } + + true + } + + fn visit_method_call_expression( + &mut self, + method_call: &MethodCallExpression, + span: Span, + ) -> bool { + if !self.includes_span(span) { + return false; + } + + if method_call.is_macro_call { + self.remove_bang_from_call(method_call.method_name.span()); + } + + true + } } diff --git a/tooling/lsp/src/requests/code_action/remove_bang_from_call.rs b/tooling/lsp/src/requests/code_action/remove_bang_from_call.rs new file mode 100644 index 00000000000..90f4fef0efd --- /dev/null +++ b/tooling/lsp/src/requests/code_action/remove_bang_from_call.rs @@ -0,0 +1,97 @@ +use lsp_types::TextEdit; +use noirc_errors::{Location, Span}; +use noirc_frontend::{node_interner::ReferenceId, QuotedType, Type}; + +use crate::byte_span_to_range; + +use super::CodeActionFinder; + +impl<'a> CodeActionFinder<'a> { + pub(super) fn remove_bang_from_call(&mut self, span: Span) { + // If we can't find the referenced function, there's nothing we can do + let Some(ReferenceId::Function(func_id)) = + self.interner.find_referenced(Location::new(span, self.file)) + else { + return; + }; + + // If the return type is Quoted, all is good + let func_meta = self.interner.function_meta(&func_id); + if let Type::Quoted(QuotedType::Quoted) = func_meta.return_type() { + return; + } + + // The `!` comes right after the name + let byte_span = span.end() as usize..span.end() as usize + 1; + let Some(range) = byte_span_to_range(self.files, self.file, byte_span) else { + return; + }; + + let title = "Remove `!` from call".to_string(); + let text_edit = TextEdit { range, new_text: "".to_string() }; + + let code_action = self.new_quick_fix(title, text_edit); + self.code_actions.push(code_action); + } +} + +#[cfg(test)] +mod tests { + use tokio::test; + + use crate::requests::code_action::tests::assert_code_action; + + #[test] + async fn test_removes_bang_from_call() { + let title = "Remove `!` from call"; + + let src = r#" + fn foo() {} + + fn main() { + fo>|| Date: Tue, 29 Oct 2024 11:02:01 -0300 Subject: [PATCH 4/5] Revert "Fix small typo in error message" This reverts commit 3f0f8f3bc50694017062597bbbfdf2078d5e1ade. --- compiler/noirc_frontend/src/hir/resolution/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs index a72e8978c9c..3c4022b58bb 100644 --- a/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -502,7 +502,7 @@ impl<'a> From<&'a ResolverError> for Diagnostic { ResolverError::MacroIsNotComptime { span } => { Diagnostic::simple_error( "This macro call is to a non-comptime function".into(), - "Macro calls must be comptime functions".into(), + "Macro calls must be to comptime functions".into(), *span, ) }, From b52b28e165857889a9ee866520f633343dd45e9a Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 29 Oct 2024 11:02:25 -0300 Subject: [PATCH 5/5] Better hint --- compiler/noirc_frontend/src/hir/type_check/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/type_check/errors.rs b/compiler/noirc_frontend/src/hir/type_check/errors.rs index 75a9e589df5..3b4ab148ef7 100644 --- a/compiler/noirc_frontend/src/hir/type_check/errors.rs +++ b/compiler/noirc_frontend/src/hir/type_check/errors.rs @@ -440,7 +440,7 @@ impl<'a> From<&'a TypeCheckError> for Diagnostic { "Macro calls must return quoted values, otherwise there is no code to insert.".into(), *span, ); - error.add_secondary("Hint: remove the `!` from the end of the call name.".to_string(), *span); + error.add_secondary("Hint: remove the `!` from the end of the function name.".to_string(), *span); error }, TypeCheckError::UnsupportedTurbofishUsage { span } => {