Preserve wildcard import symbol ownership

177c923409796b6215b34c2b4f8272183829b6a2b3ee3f417e68b46046fdd1df
Wildcard imports reused a defining module's `Symbol` but scope
insertion overwrote its `moduleId` with the importing module. Lowering
then qualified imported functions as definitions of the importer and
code generation failed to locate the actual symbol.

Assign module ownership only when inserting a newly created symbol
whose owner is unset.
Alexis Sellier committed ago 1 parent 8c31c850
Makefile +1 -1
93 93
$(patsubst %.start.ras,%.rv64,$(BIN_TEST_RAD_START_SRC)): %.rv64: %.start.ras
94 94
95 95
# Compile each executable test to a binary.
96 96
$(BIN_TEST_DIR)/%.rv64: $(BIN_TEST_DIR)/%.rad $(RAD_BIN)
97 97
	@echo "radiance $< => $@"
98 -
	@$(RADIANCE) -pkg test $(patsubst %,-start %,$(wildcard $(@:.rv64=.start.ras))) -mod $< $(patsubst %,-mod %,$(wildcard $(@:.rv64=.ras))) -o $@
98 +
	@$(RADIANCE) -pkg test -mod $< $(patsubst %,-mod %,$(wildcard $(@:.rv64=)/*.rad)) $(patsubst %,-start %,$(wildcard $(@:.rv64=.start.ras))) $(patsubst %,-mod %,$(wildcard $(@:.rv64=.ras))) -o $@
99 99
100 100
$(BIN_TEST_DIR)/%.rv64: $(BIN_TEST_DIR)/%.ras $(BIN_RUNNER)
101 101
	@echo "asm $< => $@"
102 102
	@$(EMU) $(EMU_FLAGS) -run $(BIN_RUNNER) -- assemble $< $@
103 103
lib/std/lang/resolver.rad +6 -3
2009 2009
        }
2010 2010
    }
2011 2011
    if scope.symbolsLen >= scope.symbols.len {
2012 2012
        throw emitError(self, site, ErrorKind::SymbolOverflow);
2013 2013
    }
2014 -
    // Propagate module ID to the symbol for fast lookup.
2015 -
    if let modId = scope.moduleId {
2016 -
        set sym.moduleId = modId;
2014 +
    // Preserve the defining module when importing an existing symbol into
2015 +
    // another module's scope.
2016 +
    if sym.moduleId == nil {
2017 +
        if let modId = scope.moduleId {
2018 +
            set sym.moduleId = modId;
2019 +
        }
2017 2020
    }
2018 2021
    set scope.symbols[scope.symbolsLen] = sym;
2019 2022
    set scope.symbolsLen += 1;
2020 2023
}
2021 2024
test/tests/wildcard.import.owner.rad added +9 -0
1 +
//! A wildcard import keeps the defining module for imported functions.
2 +
//! returns: 42
3 +
4 +
mod wildcard_import_owner;
5 +
use wildcard_import_owner::*;
6 +
7 +
@default fn main() -> i32 {
8 +
    return answer();
9 +
}
test/tests/wildcard.import.owner/wildcard_import_owner.rad added +3 -0
1 +
export fn answer() -> i32 {
2 +
    return 42;
3 +
}