mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Improved error message when accessing @private from other modules. Added convenience functions to Maybe.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user