compiler: Check symbol visibility from resolved module identities

87ca5d9f4f5fdd3179323943f9ad6e4e8fcaedae1353c3a1c008ad34a673c013
Alexis Sellier committed ago 1 parent 05c6985b
lib/std/lang/resolver.rad +6 -9
3385 3385
        }
3386 3386
    }
3387 3387
    return nil;
3388 3388
}
3389 3389
3390 -
/// Check if a symbol is accessible from the given scope.
3390 +
/// Check symbol visibility from declaration attributes and module identities.
3391 3391
/// A symbol is accessible if:
3392 3392
/// * It has the `export` attribute, OR
3393 3393
/// * It's being accessed from within the module where it was defined.
3394 -
unsafe fn isSymbolVisible(sym: *unsafe Symbol, symScope: *unsafe Scope, fromScope: *unsafe Scope) -> bool {
3394 +
fn isSymbolVisible(attrs: u32, symModuleId: ?u16, currentModuleId: ?u16) -> bool {
3395 3395
    // Public symbols are visible from anywhere.
3396 -
    if ast::hasAttribute(sym.attrs, ast::Attribute::Export) {
3396 +
    if ast::hasAttribute(attrs, ast::Attribute::Export) {
3397 3397
        return true;
3398 3398
    }
3399 3399
    // In test mode, @test symbols are visible from anywhere
3400 3400
    // so the test runner can reference them.
3401 -
    if ast::hasAttribute(sym.attrs, ast::Attribute::Test) {
3401 +
    if ast::hasAttribute(attrs, ast::Attribute::Test) {
3402 3402
        return true;
3403 3403
    }
3404 3404
    // Private symbols are only visible from the same module.
3405 -
    let symModuleId = findModuleForScope(symScope);
3406 -
    let currentModuleId = findModuleForScope(fromScope);
3407 -
3408 3405
    return symModuleId == currentModuleId;
3409 3406
}
3410 3407
3411 3408
/// Resolve an access node (eg. `lang::resolver::MAX_ERRORS`) to a symbol,
3412 3409
/// starting from the given scope.
3455 3452
    let root = path[0];
3456 3453
    let sym = findInScopeRecursive(scope, root, isAnySymbol)
3457 3454
        else throw emitError(self, node, ErrorKind::UnresolvedSymbol(root));
3458 3455
3459 3456
    // Check visibility for symbol.
3460 -
    if not isSymbolVisible(sym, scope, self.scope) {
3457 +
    if not isSymbolVisible(sym.attrs, findModuleForScope(scope), findModuleForScope(self.scope)) {
3461 3458
        throw emitError(self, node, ErrorKind::UnresolvedSymbol(root));
3462 3459
    }
3463 3460
    // End condition.
3464 3461
    if path.len == 1 {
3465 3462
        return sym;
3539 3536
    }
3540 3537
    let childName = path[0];
3541 3538
    let childSym = findSymbolInScope(scope, childName)
3542 3539
        else throw emitError(self, node, ErrorKind::UnresolvedSymbol(childName));
3543 3540
3544 -
    if not isSymbolVisible(childSym, scope, self.scope) {
3541 +
    if not isSymbolVisible(childSym.attrs, findModuleForScope(scope), findModuleForScope(self.scope)) {
3545 3542
        throw emitError(self, node, ErrorKind::UnresolvedSymbol(childName));
3546 3543
    }
3547 3544
    return try resolveModulePathRecursive(
3548 3545
        self,
3549 3546
        node,