diff --git a/Sources/Core/Checker.swift b/Sources/Core/Checker.swift index 57ad2e9..331b608 100644 --- a/Sources/Core/Checker.swift +++ b/Sources/Core/Checker.swift @@ -78,7 +78,7 @@ struct Checker { func declare(_ entity: Entity, scopeOwnsEntity: Bool = true) { let previous = context.scope.insert(entity, scopeOwnsEntity: scopeOwnsEntity) - if let previous = previous, entity.file === previous.file { + if let previous = previous, entity.file !== previous.file { reportError("Invalid redeclaration of '\(previous.name)'", at: entity.ident.start) file.attachNote("Previous declaration here: \(file.position(for: previous.ident.start).description)") } @@ -88,6 +88,22 @@ struct Checker { extension Checker { mutating func checkFile() { + // Before we begin checking this file we import the entities from our imports where applicable + // We can't guarentee collecting happens in any sort of order because that is where we establish an ordering + // because of this importing entities into our scope is only possible now that all of the entities for + // the imported files exist + for i in file.imports { + if i.importSymbolsIntoScope { + for member in i.scope.members.values { + guard !member.isFile && !member.isLibrary else { + continue + } + + declare(member, scopeOwnsEntity: i.exportSymbolsOutOfScope) + } + } + } + for node in file.nodes { check(topLevelStmt: node) } @@ -134,9 +150,9 @@ extension Checker { // below return assert(file.errors.count > 0) } - var entity: Entity? + var fileEntity: Entity? if let alias = i.alias { - entity = newEntity(ident: alias, flags: .file) + fileEntity = newEntity(ident: alias, flags: .file) } else if !i.importSymbolsIntoScope { guard let name = i.resolvedName else { reportError("Cannot infer an import name for '\(i.path)'", at: i.path.start) @@ -144,22 +160,16 @@ extension Checker { return } let ident = Ident(start: noPos, name: name) - entity = newEntity(ident: ident, flags: .file) + fileEntity = newEntity(ident: ident, flags: .file) } - // TODO: Ensure the import has been fully checked - if i.importSymbolsIntoScope { - for member in i.scope.members.values { - guard !member.isFile && !member.isLibrary else { - continue - } - - declare(member, scopeOwnsEntity: i.exportSymbolsOutOfScope) - } - } else if let entity = entity { - entity.memberScope = i.scope - entity.type = ty.File(memberScope: i.scope) - declare(entity) + // NOTE: If i.importSymbolsIntoScope we leave the import of entities until the file containing the import + // statement is starting to be checked. Only then do we know that all of the entities for the imported file + // have been created. + if let fileEntity = fileEntity { + fileEntity.memberScope = i.scope + fileEntity.type = ty.File(memberScope: i.scope) + declare(fileEntity) } } diff --git a/Sources/Core/Type.swift b/Sources/Core/Type.swift index f80f8d2..80a415b 100644 --- a/Sources/Core/Type.swift +++ b/Sources/Core/Type.swift @@ -310,9 +310,14 @@ func convert(_ type: Type, to target: Type, at expr: Expr) -> Bool { case (is ty.Boolean, is ty.Boolean): allowed = true - case (let exprType as ty.Enum, let targetType as ty.Integer): + case (let enumType as ty.Enum, is ty.Integer), + (is ty.Integer, let enumType as ty.Enum): // FIXME: Decide the rules for casting to and from integers - allowed = canCast(exprType.backingType, to: targetType) + allowed = canCast(enumType.backingType, to: target) + + case (is ty.Enum, is ty.UntypedInteger), + (is ty.UntypedInteger, is ty.Enum): + allowed = true case (_, is ty.Anyy): allowed = true diff --git a/code/bugs/open/issue121/a.kai b/code/bugs/closed/issue121/a.kai similarity index 100% rename from code/bugs/open/issue121/a.kai rename to code/bugs/closed/issue121/a.kai diff --git a/code/bugs/open/issue121/b.kai b/code/bugs/closed/issue121/b.kai similarity index 100% rename from code/bugs/open/issue121/b.kai rename to code/bugs/closed/issue121/b.kai diff --git a/code/bugs/open/issue121/c.kai b/code/bugs/closed/issue121/c.kai similarity index 100% rename from code/bugs/open/issue121/c.kai rename to code/bugs/closed/issue121/c.kai diff --git a/code/bugs/open/issue122/a.kai b/code/bugs/open/issue122/a.kai new file mode 100644 index 0000000..568d2fb --- /dev/null +++ b/code/bugs/open/issue122/a.kai @@ -0,0 +1,7 @@ + +#import "b.kai" _ +#import "c.kai" _ +main :: fn() -> void { + z := ent +} + diff --git a/code/bugs/open/issue122/b.kai b/code/bugs/open/issue122/b.kai new file mode 100644 index 0000000..655fe60 --- /dev/null +++ b/code/bugs/open/issue122/b.kai @@ -0,0 +1 @@ +ent :: 1 diff --git a/code/bugs/open/issue122/c.kai b/code/bugs/open/issue122/c.kai new file mode 100644 index 0000000..1129ee2 --- /dev/null +++ b/code/bugs/open/issue122/c.kai @@ -0,0 +1 @@ +ent :: 2