Skip to content

Commit

Permalink
Semantic: respect resolved malleable types in method call type
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Mar 26, 2024
1 parent f5c65b4 commit e76f9a4
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 9 deletions.
6 changes: 2 additions & 4 deletions src/semantic/expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
resolveType
} from '../typecheck/generic'
import { holeType, unitType, unknownType } from '../typecheck/type'
import { assert, unreachable } from '../util/todo'
import { assert, todo, unreachable } from '../util/todo'
import {
argCountMismatchError,
missingFieldsError,
Expand Down Expand Up @@ -439,9 +439,7 @@ export const checkClosureExpr = (
}

checkBlock(closureExpr.block, ctx)
if (closureExpr.type.returnType.kind === 'unknown-type') {
closureExpr.type.returnType = closureExpr.block.type!
}
closureExpr.type.returnType = closureExpr.block.type!

module.scopeStack.pop()
}
Expand Down
10 changes: 7 additions & 3 deletions src/semantic/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Context, addError } from '../scope'
import { getInstanceForType, resolveMethodImpl, resolveTypeImpl } from '../scope/trait'
import { vidFromString, vidToString } from '../scope/util'
import { MethodDef, VirtualIdentifier, resolveVid, typeKinds } from '../scope/vid'
import { VirtualFnType, VirtualType, combine, genericToVirtual, typeToVirtual } from '../typecheck'
import { VirtualFnType, VirtualType, combine, genericToVirtual, typeToVirtual, virtualTypeToString } from '../typecheck'
import {
makeFnGenericMap,
makeFnTypeArgGenericMap,
Expand Down Expand Up @@ -139,14 +139,18 @@ export const checkMethodCall = (expr: UnaryExpr, mCall: MethodCallOp, ctx: Conte
}
if (mCall.call.impl) {
ctx.moduleStack.at(-1)!.relImports.push(mCall.call.impl)
// TODO: upcast only happen to the direct implType, but not its supertypes
// Use case: std::range has to return Iter<T> instead of RangeIter. When RangeIter is passed into a method
// where MapIter is expected, upcast of RangeIter for MapIter does not upcast it to Iter
upcast(operand, operand.type!, ref.def.rel.implType, ctx)
}

const genericMaps = makeMethodGenericMaps(operand, ref.def, mCall, ctx)
let genericMaps = makeMethodGenericMaps(operand, ref.def, mCall, ctx)
const args = ref.def.fn.static ? mCall.call.args.map(a => a.expr) : [operand, ...mCall.call.args.map(a => a.expr)]
const paramTypes = fnType.paramTypes.map(pt => resolveType(pt, genericMaps, ctx))
console.log('check method', methodName)
checkCallArgs(mCall, args, paramTypes, ctx)
// recalculate generic maps since malleable args might've been updated
genericMaps = makeMethodGenericMaps(operand, ref.def, mCall, ctx)

const implForType = getInstanceForType(ref.def.rel.instanceDef, ctx)
const implForGenericMap = makeGenericMapOverStructure(operand.type!, implForType)
Expand Down
4 changes: 2 additions & 2 deletions src/std/iter/range.no
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ impl Iter<Int> for RangeIter {
}
}

pub fn range(start: Int, end: Int): RangeIter {
pub fn range(start: Int, end: Int): Iter<Int> {
RangeIter(head: start, end)
}

pub fn rangeClosed(start: Int, end: Int): RangeIter {
pub fn rangeClosed(start: Int, end: Int): Iter<Int> {
RangeIter(head: start, end: end + 1)
}

0 comments on commit e76f9a4

Please sign in to comment.