From f39dd82adc2ff026d1b69328dc7019593a2498d7 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 15 Aug 2023 10:47:40 +0200 Subject: [PATCH] Fix issue where imports could be made more than once. Addresses #929 --- src/compiler/sema_passes.c | 29 +++++++++++++++++++------- src/version.h | 2 +- test/test_suite/import/import_twice.c3 | 8 +++++++ 3 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 test/test_suite/import/import_twice.c3 diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index e790541bf..b0e37d9e0 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -63,7 +63,7 @@ void sema_analysis_pass_process_imports(Module *module) { DEBUG_LOG("Pass: Importing dependencies for files in module '%s'.", module->name->module); - unsigned import_count = 0; + unsigned total_import_count = 0; VECEACH(module->units, index) { // 1. Loop through each context in the module. @@ -71,17 +71,29 @@ void sema_analysis_pass_process_imports(Module *module) DEBUG_LOG("Checking imports for %s.", unit->file->name); // 2. Loop through imports - unsigned imports = vec_size(unit->imports); + Decl **imports = unit->imports; + unsigned import_count = vec_size(imports); - for (unsigned i = 0; i < imports; i++) + for (unsigned i = 0; i < import_count; i++) { // 3. Begin analysis - Decl *import = unit->imports[i]; + Decl *import = imports[i]; assert(import->resolve_status == RESOLVE_NOT_DONE); import->resolve_status = RESOLVE_RUNNING; - // 4. Find the module. Path *path = import->import.path; + + for (unsigned j = 0; j < i; j++) + { + if (imports[j]->import.path->module == path->module) + { + SEMA_ERROR(import, "Module '%s' imported more than once, please remove one.", path->module); + SEMA_NOTE(imports[j], "The previous one was here."); + decl_poison(import); + goto NEXT; + } + } + Module *import_module = global_context_find_module(path->module); // 5. Do we find it? @@ -103,11 +115,12 @@ void sema_analysis_pass_process_imports(Module *module) // 7. Assign the module. DEBUG_LOG("* Import of %s.", path->module); import->import.module = import_module; +NEXT:; } - import_count += imports; + total_import_count += import_count; } - (void)import_count; // workaround for clang 13.0 - DEBUG_LOG("Pass finished processing %d import(s) with %d error(s).", import_count, global_context.errors_found); + (void)total_import_count; // workaround for clang 13.0 + DEBUG_LOG("Pass finished processing %d import(s) with %d error(s).", total_import_count, global_context.errors_found); } INLINE void register_global_decls(CompilationUnit *unit, Decl **decls) diff --git a/src/version.h b/src/version.h index ddd3b943c..15837ef37 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.608" \ No newline at end of file +#define COMPILER_VERSION "0.4.609" \ No newline at end of file diff --git a/test/test_suite/import/import_twice.c3 b/test/test_suite/import/import_twice.c3 new file mode 100644 index 000000000..da7fed2ec --- /dev/null +++ b/test/test_suite/import/import_twice.c3 @@ -0,0 +1,8 @@ +module foo; +import std::io; +import std::io; // #error: imported more than + +fn void! main() +{ + io::printn("Hello world"); +}