Make kind inferencer support structs inside let-declarations
This commit is contained in:
parent
487e6d4994
commit
6110509c41
1 changed files with 9 additions and 19 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue