Skip to content

Commit

Permalink
Semantic: check qualified method call improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Apr 19, 2024
1 parent 26d85dd commit 349c6bf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 15 deletions.
26 changes: 20 additions & 6 deletions src/semantic/expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,10 +490,12 @@ export const checkQualifiedMethodCall = (
identifier: Identifier,
ref: VirtualIdentifierMatch<MethodDef>,
ctx: Context,
inferredType: VirtualFnType
call?: CallOp,
inferred?: VirtualFnType
): VirtualType => {
assert(!!call || !!inferred)
const fnType = <VirtualFnType>ref.def.fn.type
const self = !ref.def.fn.static ? inferredType.paramTypes[0] : undefined
const self = !ref.def.fn.static ? call?.args[0].expr.type! ?? inferred : undefined

let impl: InstanceRelation | undefined = undefined
if (ref.def.rel.instanceDef.kind === 'trait-def' && self && self.kind === 'vid-type') {
Expand Down Expand Up @@ -537,14 +539,25 @@ export const checkQualifiedMethodCall = (
} else {
maps.push(new Map([[selfType.name, implForType]]))
}
const fnGenericMap = makeFnGenericMap(fnType, inferredType.paramTypes)
const fnGenericMap = makeFnGenericMap(fnType, call?.args.map(a => a.expr.type!) ?? inferred!.paramTypes)
maps.push(fnGenericMap)

if (call) {
checkCallArgs(
call,
call.args.map(a => a.expr),
fnType.paramTypes,
ctx
)
}

const argTypes = call?.args.map(a => a.expr.type!) ?? inferred!.paramTypes
return {
kind: 'fn-type',
paramTypes: inferredType.paramTypes.map(pt => resolveType(pt, maps, ctx)),
paramTypes: argTypes.map(t => resolveType(t, maps, ctx)),
returnType: resolveType(fnType.returnType, maps, ctx),
generics: inferredType.generics
// TODO: generics
generics: []
}
}

Expand Down Expand Up @@ -648,11 +661,12 @@ export const checkCall_ = (call: CallOp, operand: Operand, args: Expr[], ctx: Co
// TODO: properly
const ref = operand.type!.operand.ref
if (ref?.def.kind !== 'method-def') return unreachable()
call.methodDef = ref.def
operand.type = checkQualifiedMethodCall(
operand.type.operand,
<VirtualIdentifierMatch<MethodDef>>ref,
ctx,
inferredType
call
)
break
default:
Expand Down
19 changes: 10 additions & 9 deletions src/semantic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -787,22 +787,23 @@ export const checkType = (type: Type, ctx: Context) => {
}
}

export const resolveMallebleType = (arg: Operand, paramType: VirtualType, ctx: Context): void => {
if (arg.type!.kind === 'malleable-type' && paramType.kind === 'fn-type') {
switch (arg.type!.operand.kind) {
export const resolveMallebleType = (operand: Operand, inferred: VirtualType, ctx: Context): void => {
if (operand.type!.kind === 'malleable-type' && inferred.kind === 'fn-type') {
switch (operand.type!.operand.kind) {
case 'closure-expr':
const closure = arg.type!.operand
arg.type! = checkResolvedClosureExpr(closure, ctx, arg, paramType)
const closure = operand.type!.operand
operand.type! = checkResolvedClosureExpr(closure, ctx, operand, inferred)
break
case 'identifier':
// TODO: properly
const ref = arg.type!.operand.ref
const ref = operand.type!.operand.ref
if (ref?.def.kind !== 'method-def') return unreachable()
arg.type = checkQualifiedMethodCall(
arg.type!.operand,
operand.type = checkQualifiedMethodCall(
operand.type!.operand,
<VirtualIdentifierMatch<MethodDef>>ref,
ctx,
paramType
undefined,
inferred
)
break
default:
Expand Down

0 comments on commit 349c6bf

Please sign in to comment.