Skip to content

Commit

Permalink
Fix circular imports not being able to use short names
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Dec 6, 2023
1 parent 9a69d56 commit f6deccc
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/scope.pr
Original file line number Diff line number Diff line change
Expand Up @@ -1355,7 +1355,7 @@ export def get(
let s = get(scope, id_head, force_compile, false, dry_run, context = context)
if s {
if not s.get_scope() {
errors::errorn(id, "Use of :: on non namespace")
if not dry_run { errors::errorn(id, "Use of :: on non namespace") }
return null
}
let value = get(s.get_scope(), id_tail, force_compile, s.imported, dry_run, context = context)
Expand Down
28 changes: 25 additions & 3 deletions src/typechecking.pr
Original file line number Diff line number Diff line change
Expand Up @@ -2048,14 +2048,14 @@ def check_is_identifier_assignable(node: &parser::Node, state: &State) -> bool {
return true
}

export def make_stub_type(ident: &parser::Node, state: &State) -> &typechecking::Type {
export def make_stub_type(ident: &parser::Node, state: &State, prefix: bool = true) -> &typechecking::Type {
assert ident.kind == parser::NodeKind::IDENTIFIER

let name = parser::identifier_to_str(ident)
let tpe = make_type_raw(TypeKind::STUB)
tpe.name = ident.value.identifier.path[vector::length(ident.value.identifier.path) - 1]
tpe.type_name = name
if vector::length(ident.value.identifier.path) == 1 {
if prefix and vector::length(ident.value.identifier.path) == 1 {
tpe.type_name = append_module(tpe.type_name, state.module.module)
}
return tpe
Expand Down Expand Up @@ -2390,7 +2390,7 @@ export def do_type_lookup(node: &parser::Node, state: &State, current_type: &Typ
scope::create_dependency(state.current_value(), value)
tpe = value.value.value_tpe
} else {
tpe = make_stub_type(node, state)
tpe = make_stub_type(node, state, prefix = false)
tpe.is_type_argument = true // TODO Maybe don't reuse this
if prefix {
tpe.type_name = prefix + tpe.type_name
Expand Down Expand Up @@ -5647,6 +5647,27 @@ export def walk_Def_with_type_argument(node: &parser::Node, parameter_t: &Vector
return node
}

// Stub types get replaced with actual types.
// When you are using a function with an unknown type in consteval it creates a stub type
// inside the current module. In typechecking we know the actual type which is inside the imports.
def lookup_stub_types(state: &State) {
let scpe = state.scope
for var key in @state.scope.fields.keys() {
let value = state.scope.fields[key]
if value.tpe.kind == TypeKind::TYPE {
let tpe = value.value.value_tpe
if tpe.kind == TypeKind::STUB and util::find_substr(tpe.type_name, "::", 0) == -1 {
state.scope.fields.remove(key)
var new_value = scope::get(scpe, parser::make_identifier(key), dry_run = true)
if new_value and new_value.tpe.kind == TypeKind::TYPE {
@value.value.value_tpe = @new_value.value.value_tpe
}
state.scope.fields[key] = value
}
}
}
}

export def typecheck(module: &toolchain::Module) {
let state = make_state(module)
module.state = state
Expand Down Expand Up @@ -5715,6 +5736,7 @@ export def typecheck(state: &State) {

node.value.program.function.value = value

lookup_stub_types(state)
typecheck(node, state)

let keys = map::keys(node.scope.fields)
Expand Down

0 comments on commit f6deccc

Please sign in to comment.