fix type inferencing bug

This commit is contained in:
Joeri Exelmans 2025-05-24 18:35:06 +02:00
parent 69175c8cb1
commit b2584a2495
2 changed files with 12 additions and 7 deletions

View file

@ -97,7 +97,7 @@ function InputParams({ ...rest }) {
const globalContext = useContext(GlobalContext); const globalContext = useContext(GlobalContext);
const typeInfo = inferTypeCall(rest.state, env); const typeInfo = inferTypeCall(rest.state, env);
const inputEnv = typeInfo.fn.newEnv; const inputEnv = typeInfo.fn.newEnv;
const isOffending = rest.state.err; const isOffending = typeInfo.err;
return <div className={"inputParam" + (isOffending ? " offending" : "")}> return <div className={"inputParam" + (isOffending ? " offending" : "")}>
{rest.state.fn.kind === "call" {rest.state.fn.kind === "call"
&& globalContext?.syntacticSugar && globalContext?.syntacticSugar

View file

@ -101,7 +101,6 @@ export function inferTypeInput(s: InputBlockState, env: Environment): TypeInfoIn
} }
} }
// @ts-ignore
export function inferTypeCall(s: CallBlockState, env: Environment): TypeInfoCall { export function inferTypeCall(s: CallBlockState, env: Environment): TypeInfoCall {
const fnTypeInfo = inferType(s.fn, env); const fnTypeInfo = inferType(s.fn, env);
const inputEnv = fnTypeInfo.newEnv; const inputEnv = fnTypeInfo.newEnv;
@ -112,7 +111,6 @@ export function inferTypeCall(s: CallBlockState, env: Environment): TypeInfoCall
const subs = unify( const subs = unify(
fnTypeInfo.type, fnTypeInfo.type,
fakeFnType); fakeFnType);
// console.log("subs:", prettySS(subs));
let type, newEnv; let type, newEnv;
if (subs.has(returnType!.symbol)) { if (subs.has(returnType!.symbol)) {
type = subs.get(returnType!.symbol); type = subs.get(returnType!.symbol);
@ -159,6 +157,7 @@ export function inferTypeCall(s: CallBlockState, env: Environment): TypeInfoCall
input: inputTypeInfo, input: inputTypeInfo,
} }
} }
throw e;
} }
} }
@ -195,13 +194,13 @@ export function inferTypeLambda(s: LambdaBlockState, env: Environment): TypeInfo
const subsWithoutPType = new Map(innerTypeInfo.subs); const subsWithoutPType = new Map(innerTypeInfo.subs);
subsWithoutPType.delete(paramTypeVar); subsWithoutPType.delete(paramTypeVar);
const inferredPType = substitute(paramType, innerTypeInfo.subs, []); const inferredPType = substitute(paramType, innerTypeInfo.subs, []);
const inferredPType2 = rewriteInferredType(inferredPType, env); const [inferredPType2, newEnv] = rewriteInferredType(inferredPType, env);
if (eqType(inferredPType2)(paramType)) { if (eqType(inferredPType2)(paramType)) {
return { return {
kind: "lambda", kind: "lambda",
type: fnType(_ => paramType)(_ => innerTypeInfo.type), type: fnType(_ => paramType)(_ => innerTypeInfo.type),
subs: subsWithoutPType, subs: subsWithoutPType,
newEnv: env, // no change newEnv,
paramType, paramType,
inner: innerTypeInfo, inner: innerTypeInfo,
innerEnv, innerEnv,
@ -245,8 +244,9 @@ function typeUnknown(env: Environment): [Type, Environment] {
}; };
return [type, newEnv]; return [type, newEnv];
} }
function rewriteInferredType(type: Type, env: Environment) { function rewriteInferredType(type: Type, env: Environment): [Type, Environment] {
const substitutions = new Map(); const substitutions = new Map();
const newTypeVars = new Set(env.typevars);
let i = 0; let i = 0;
for (const o of occurring(type)) { for (const o of occurring(type)) {
while (env.typevars.has(UNBOUND_SYMBOLS[i])) { while (env.typevars.has(UNBOUND_SYMBOLS[i])) {
@ -254,9 +254,14 @@ function rewriteInferredType(type: Type, env: Environment) {
} }
if (!env.typevars.has(o)) { if (!env.typevars.has(o)) {
substitutions.set(o, TYPE_VARS[i]); substitutions.set(o, TYPE_VARS[i]);
newTypeVars.add(UNBOUND_SYMBOLS[i]);
} }
} }
return substitute(type, substitutions, []); const rewrittenType = substitute(type, substitutions, []);
return [rewrittenType, {
names: env.names,
typevars: env.typevars.union(newTypeVars),
}];
} }
export function scoreTypeInfo(typeInfo: TypeInfo): number { export function scoreTypeInfo(typeInfo: TypeInfo): number {
const bias = typeInfo.err ? -1 : 0; const bias = typeInfo.err ? -1 : 0;