Make kind inferencer support structs inside let-declarations

This commit is contained in:
Sam Vervaeck 2022-09-15 13:56:58 +02:00
parent 487e6d4994
commit 6110509c41

View file

@ -741,27 +741,21 @@ export class TypeEnv {
class KindEnv { class KindEnv {
private mapping1 = new Map<string, Kind>(); private mapping = new Map<string, Kind>();
private mapping2 = new Map<number, Kind>();
public constructor(public parent: KindEnv | null = null) { public constructor(public parent: KindEnv | null = null) {
} }
public setNamed(name: string, kind: Kind): void { public setNamed(name: string, kind: Kind): void {
assert(!this.mapping1.has(name)); assert(!this.mapping.has(name));
this.mapping1.set(name, kind); this.mapping.set(name, kind);
} }
public setVar(tv: TVar, kind: Kind): void { public lookup(name: string): Kind | null {
assert(!this.mapping2.has(tv.id));
this.mapping2.set(tv.id, kind);
}
public lookupNamed(name: string): Kind | null {
let curr: KindEnv | null = this; let curr: KindEnv | null = this;
do { do {
const kind = curr.mapping1.get(name); const kind = curr.mapping.get(name);
if (kind !== undefined) { if (kind !== undefined) {
return kind; return kind;
} }
@ -770,10 +764,6 @@ class KindEnv {
return null; return null;
} }
public lookupVar(tv: TVar): Kind | null {
return this.mapping2.get(tv.id) ?? null;
}
} }
export interface InferContext { export interface InferContext {
@ -880,7 +870,7 @@ export class Checker {
case SyntaxKind.VarTypeExpression: case SyntaxKind.VarTypeExpression:
case SyntaxKind.ReferenceTypeExpression: case SyntaxKind.ReferenceTypeExpression:
{ {
const kind = env.lookupNamed(node.name.text); const kind = env.lookup(node.name.text);
if (kind === null) { if (kind === null) {
this.diagnostics.add(new BindingNotFoudDiagnostic(node.name.text, node.name)); this.diagnostics.add(new BindingNotFoudDiagnostic(node.name.text, node.name));
// Create a filler kind variable that still will be able to catch other errors. // Create a filler kind variable that still will be able to catch other errors.
@ -993,7 +983,7 @@ export class Checker {
} }
case SyntaxKind.EnumDeclaration: case SyntaxKind.EnumDeclaration:
{ {
const declKind = env.lookupNamed(node.name.text)!; const declKind = env.lookup(node.name.text)!;
const innerEnv = new KindEnv(env); const innerEnv = new KindEnv(env);
let kind: Kind = new KStar(); let kind: Kind = new KStar();
// FIXME should I go from right to left or left to right? // FIXME should I go from right to left or left to right?
@ -1026,9 +1016,9 @@ export class Checker {
this.unifyKind(this.inferKindFromTypeExpression(node.typeAssert.typeExpression, env), new KStar(), node.typeAssert.typeExpression); this.unifyKind(this.inferKindFromTypeExpression(node.typeAssert.typeExpression, env), new KStar(), node.typeAssert.typeExpression);
} }
if (node.body !== null && node.body.kind === SyntaxKind.BlockBody) { if (node.body !== null && node.body.kind === SyntaxKind.BlockBody) {
const innerEnv = new KindEnv(env);
for (const element of node.body.elements) { for (const element of node.body.elements) {
// TODO fork `env` to support local type declarations this.inferKind(element, innerEnv);
this.inferKind(element, env);
} }
} }
break; break;