Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ascandone committed Jan 4, 2025
1 parent c6d22a5 commit 2e60c5d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 12 deletions.
21 changes: 9 additions & 12 deletions src/analysis/analyse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1712,24 +1712,21 @@ describe("traits", () => {
});
});

test.todo(
"succeeds to typecheck when a required trait is not implemented",
() => {
// resetTraitsRegistry([
// { trait: "Show", moduleName: "Int", typeName: "Int" },
// ]);
test("succeeds to typecheck when a required trait is not implemented", () => {
// resetTraitsRegistry([
// { trait: "Show", moduleName: "Int", typeName: "Int" },
// ]);

const [a] = performAnalysis(
`
const [a] = performAnalysis(
`
extern type String
extern pub let show: Fn(a) -> String where a: Show
pub let x = show(42)
`,
);
);

expect(a.errors).toEqual([]);
},
);
expect(a.errors).toEqual([]);
});

test("propagates the trait constraint", () => {
const [a] = performAnalysis(
Expand Down
55 changes: 55 additions & 0 deletions src/analysis/analyse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import {
import { bool, char, float, int, list, string } from "./coreTypes";
import { TypeAstsHydration } from "./typesHydration";
import { defaultMapGet } from "../data/defaultMap";
import { TraitImpl, defaultTraitImpls } from "../typecheck/defaultImports";
import { TraitImplDependency } from "../typecheck/type";

export type AnalyseOptions = {
getDependency?: (namespace: string) => Analysis | undefined;
Expand Down Expand Up @@ -437,6 +439,45 @@ export class Analysis {
}
}
}

private static namedTypesTraitImpls = new Map<
string,
TraitImplDependency[]
>();

public static resetTraitImpls() {
Analysis.namedTypesTraitImpls = new Map();
}

/**
* E.g.
* // impl Eq for Int
* registerTraitImpl("Basics", "Int", "Eq")
*
* // impl Eq for Result<a, b> where a: Eq, b: Eq
* registerTraitImpl("Basics", "Result", "Eq", [["Eq"], ["Eq"]])
*/
public static registerTraitImpl(
moduleName: string,
typeName: string,
trait: string,
dependencies: TraitImplDependency[],
) {
const id = getNamedTypeTraitId(moduleName, typeName, trait);
if (Analysis.namedTypesTraitImpls.has(id)) {
throw new Error("Cannot register trait twice for the same type");
}

Analysis.namedTypesTraitImpls.set(id, dependencies);
}
}

function getNamedTypeTraitId(
moduleName: string,
typeName: string,
trait: string,
): string {
return `${moduleName}.${typeName}:${trait}`;
}

// Keep this in sync with core
Expand All @@ -456,6 +497,20 @@ function getConstantType(lit: ConstLiteral): Type {
}
}

export function resetTraitsRegistry(
traitImpls: TraitImpl[] = defaultTraitImpls,
) {
Analysis.resetTraitImpls();
for (const impl of traitImpls) {
TVar.registerTraitImpl(

Check failure on line 505 in src/analysis/analyse.ts

View workflow job for this annotation

GitHub Actions / main

Cannot find name 'TVar'.
impl.moduleName,
impl.typeName,
impl.trait,
impl.deps ?? [],
);
}
}

// TODO move to type
// function applyHint(
// valueType: Type,
Expand Down

0 comments on commit 2e60c5d

Please sign in to comment.