Improved error message when accessing @private from other modules. Added convenience functions to Maybe.

This commit is contained in:
Christoffer Lerno
2025-01-04 14:58:06 +01:00
parent 469188044d
commit e31e57c7e7
6 changed files with 51 additions and 11 deletions

View File

@@ -1,16 +1,43 @@
module std::collections::maybe(<Type>);
import std::io;
struct Maybe
struct Maybe (Printable)
{
Type value;
bool has_value;
}
fn usz! Maybe.to_format(&self, Formatter* f) @dynamic
{
if (self.has_value) return f.printf("[%s]", self.value);
return f.printf("[EMPTY]");
}
fn void Maybe.set(&self, Type val)
{
*self = { .value = val, .has_value = true };
}
fn void Maybe.reset(&self)
{
*self = {};
}
fn Maybe value(Type val)
{
return { .value = val, .has_value = true };
}
fn Maybe Maybe.with_value(Type val) @operator(construct)
{
return { .value = val, .has_value = true };
}
fn Maybe Maybe.empty() @operator(construct)
{
return { };
}
const Maybe EMPTY = { };
macro Type! Maybe.get(self)

View File

@@ -17,6 +17,7 @@
- Allow using 'var' to declare lambdas in functions.
- Add 'validation' setting and make dead code a warning.
- Allow compile time `$foreach` iteration over constant Strings and bytes.
- Improved error message when accessing `@private` from other modules #1769.
### Fixes
- Fix case trying to initialize a `char[*]*` from a String.
@@ -62,6 +63,7 @@
- Add `@enum_from_value`.
- Updated hash function.
- Added URL parser.
- Added convenience functions to `Maybe`.
## 0.6.5 Change list

View File

@@ -136,7 +136,7 @@ static inline Decl *sema_find_decl_in_module(Module *module, Path *path, const c
return module_find_symbol(module, symbol);
}
static bool sema_find_decl_in_private_imports(SemaContext *context, NameResolve *name_resolve, bool want_generic)
static bool sema_find_decl_in_imports(SemaContext *context, NameResolve *name_resolve, bool want_generic)
{
Decl *decl = NULL;
// 1. Loop over imports.
@@ -145,7 +145,8 @@ static bool sema_find_decl_in_private_imports(SemaContext *context, NameResolve
FOREACH(Decl *, import, context->unit->imports)
{
if (import->import.module->is_generic != want_generic) continue;
if (!import->import.import_private_as_public) continue;
bool is_private_import = import->import.import_private_as_public;
if (!path && (decl || !is_private_import)) continue;
// Is the decl in the import.
Decl *found = sema_find_decl_in_module(import->import.module, path, symbol, &name_resolve->path_found);
@@ -154,6 +155,16 @@ static bool sema_find_decl_in_private_imports(SemaContext *context, NameResolve
ASSERT0(found->visibility != VISIBLE_LOCAL);
if (found->visibility != VISIBLE_PUBLIC)
{
if (decl) continue;
if (!is_private_import)
{
name_resolve->private_decl = found;
continue;
}
}
// Did we already have a match?
if (decl)
{
@@ -418,7 +429,7 @@ static bool sema_resolve_path_symbol(SemaContext *context, NameResolve *name_res
}
// 3. Loop over imports.
if (!sema_find_decl_in_private_imports(context, name_resolve, false)) return false;
if (!sema_find_decl_in_imports(context, name_resolve, false)) return false;
// 4. Go to global search
if (name_resolve->found) return true;
@@ -493,7 +504,7 @@ static bool sema_resolve_no_path_symbol(SemaContext *context, NameResolve *name_
return true;
}
if (!sema_find_decl_in_private_imports(context, name_resolve, false)) return false;
if (!sema_find_decl_in_imports(context, name_resolve, false)) return false;
if (name_resolve->found) return true;
return sema_find_decl_in_global(context, &compiler.context.symbols, NULL, name_resolve, false);
@@ -582,12 +593,12 @@ static void sema_report_error_on_decl(SemaContext *context, NameResolve *name_re
const char *private_name = decl_to_name(name_resolve->private_decl);
if (path_name)
{
sema_error_at(context, span, "The %s '%s::%s' is not visible from this module.",
sema_error_at(context, span, "The %s '%s::%s' is '@private' and not visible from other modules.",
private_name, path_name,
symbol);
} else
{
sema_error_at(context, span, "The %s '%s' is not visible from this module.",
sema_error_at(context, span, "The %s '%s' is '@private' and not visible from other modules.",
private_name, symbol);
}
return;
@@ -982,7 +993,7 @@ bool unit_resolve_parameterized_symbol(SemaContext *context, NameResolve *name_r
name_resolve->private_decl = NULL;
name_resolve->path_found = NULL;
if (!sema_find_decl_in_private_imports(context, name_resolve, true)) return false;
if (!sema_find_decl_in_imports(context, name_resolve, true)) return false;
if (!name_resolve->found)
{
if (!sema_find_decl_in_global(context, &compiler.context.generic_symbols,

View File

@@ -4,7 +4,7 @@ import bar;
fn void runBar()
{
bar::notVisible(); // #error: 'bar::notVisible' could not be found
bar::notVisible(); // #error: 'bar::notVisible' is '@private'
}
// #file: file2.c3

View File

@@ -9,7 +9,7 @@ import foo;
fn void test()
{
foo::hidden(); // #error: 'foo::hidden' could not be found,
foo::hidden(); // #error: 'foo::hidden' is '@private'
}
module baz;

View File

@@ -22,6 +22,6 @@ import test;
fn void abc()
{
test::bar(); // #error: could not be found
test::bar(); // #error: is '@private'
test::bar2(); // #error: could not be found
}