diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index fd2c8796ea6..d365e5807c2 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -372,6 +372,8 @@ impl DefCollector { let current_def_map = context.def_maps.get_mut(&crate_id).unwrap(); let file_id = current_def_map.file_id(module_id); + let has_path_resolution_error = resolved_import.error.is_some(); + if let Some(error) = resolved_import.error { errors.push(( DefCollectorErrorKind::PathResolutionError(error).into(), @@ -401,24 +403,29 @@ impl DefCollector { let result = current_def_map.modules[resolved_import.module_scope.0] .import(name.clone(), visibility, module_def_id, is_prelude); - let module_id = - ModuleId { krate: crate_id, local_id: resolved_import.module_scope }; - context.def_interner.usage_tracker.add_unused_item( - module_id, - name.clone(), - UnusedItem::Import, - visibility, - ); - - if visibility != ItemVisibility::Private { - let local_id = resolved_import.module_scope; - let defining_module = ModuleId { krate: crate_id, local_id }; - context.def_interner.register_name_for_auto_import( - name.to_string(), - module_def_id, + // If we error on path resolution don't also say it's unused (in case it ends up being unused) + if !has_path_resolution_error { + let module_id = ModuleId { + krate: crate_id, + local_id: resolved_import.module_scope, + }; + context.def_interner.usage_tracker.add_unused_item( + module_id, + name.clone(), + UnusedItem::Import, visibility, - Some(defining_module), ); + + if visibility != ItemVisibility::Private { + let local_id = resolved_import.module_scope; + let defining_module = ModuleId { krate: crate_id, local_id }; + context.def_interner.register_name_for_auto_import( + name.to_string(), + module_def_id, + visibility, + Some(defining_module), + ); + } } let last_segment = collected_import.path.last_ident(); diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index ceb781266df..33ab82bca2a 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -3038,3 +3038,26 @@ fn use_numeric_generic_in_trait_method() { println!("{errors:?}"); assert_eq!(errors.len(), 0); } + +#[test] +fn errors_once_on_unused_import_that_is_not_accessible() { + // Tests that we don't get an "unused import" here given that the import is not accessible + let src = r#" + mod moo { + struct Foo {} + } + + use moo::Foo; + + fn main() {} + "#; + + let errors = get_program_errors(src); + assert_eq!(errors.len(), 1); + assert!(matches!( + errors[0].0, + CompilationError::DefinitionError(DefCollectorErrorKind::PathResolutionError( + PathResolutionError::Private { .. } + )) + )); +} diff --git a/tooling/lsp/src/requests/code_action/remove_unused_import.rs b/tooling/lsp/src/requests/code_action/remove_unused_import.rs index c660dd57e47..f1e12d64ef5 100644 --- a/tooling/lsp/src/requests/code_action/remove_unused_import.rs +++ b/tooling/lsp/src/requests/code_action/remove_unused_import.rs @@ -163,7 +163,7 @@ mod tests { let src = r#" mod moo { - fn foo() {} + pub fn foo() {} } use moo::fo>|||||