Skip to content

Commit

Permalink
Semantic: upcast for method call operand
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Mar 18, 2024
1 parent 09699d8 commit 5a4f917
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/semantic/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
unexpectedTypeError
} from './error'
import { checkExpr, checkOperand } from './expr'
import { upcast } from './upcast'

export const checkFieldAccess = (operand: Operand, name: Name, ctx: Context): VirtualType | undefined => {
checkOperand(operand, ctx)
Expand Down Expand Up @@ -143,6 +144,7 @@ export const checkMethodCall = (expr: UnaryExpr, mCall: MethodCallOp, ctx: Conte
}
if (mCall.call.impl) {
ctx.moduleStack.at(-1)!.relImports.push(mCall.call.impl)
upcast(operand, operand.type!, ref.def.rel.implType, ctx)
}

mCall.call.generics = fnType.generics.map(g => {
Expand Down
22 changes: 13 additions & 9 deletions src/semantic/upcast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,7 @@ export interface Upcast {
export const upcast = (virtual: Partial<Virtual>, type: VirtualType, traitType: VirtualType, ctx: Context): void => {
const upcastMap = makeUpcastMap(type, traitType, ctx)
if (upcastMap) {
virtual.upcasts ??= new Map()
upcastMap.forEach((up, k) => {
const existing = virtual.upcasts!.get(k)
if (existing) {
up.traits.forEach((t, tk) => existing.traits.set(tk, t))
} else {
virtual.upcasts!.set(k, up)
}
})
writeUpcast(virtual, upcastMap)
}
}

Expand Down Expand Up @@ -50,3 +42,15 @@ export const makeUpcastMap = (
ctx.moduleStack.at(-1)!.relImports.push(res.impl)
return upcasts
}

const writeUpcast = (virtual: Partial<Virtual>, upcastMap: Map<string, Upcast>): void => {
virtual.upcasts ??= new Map()
upcastMap.forEach((up, k) => {
const existing = virtual.upcasts!.get(k)
if (existing) {
up.traits.forEach((t, tk) => existing.traits.set(tk, t))
} else {
virtual.upcasts!.set(k, up)
}
})
}

0 comments on commit 5a4f917

Please sign in to comment.