Skip to content

Commit

Permalink
Add test case to check that intersection with exact types is 'never' (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinbarabash committed Aug 11, 2024
1 parent 04c6532 commit 655400b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
27 changes: 26 additions & 1 deletion src/Escalier.TypeChecker.Tests/Exact.fs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ let InexactMappedTypesPreserveExactness () =

Assert.False(Result.isError res)


[<Fact>]
let ExactMappedTypesPreserveExactness () =
let res =
result {
Expand Down Expand Up @@ -225,3 +225,28 @@ let ExactMappedTypesPreserveExactness () =
}

Assert.False(Result.isError res)

[<Fact>]
let IntersectionOfExactTypesIsNever () =
let res =
result {
let src =
"""
type Foo = {foo: string};
type Bar = {bar: number, ...};
type FooAndBar = Foo & Bar;
"""

let! ctx, env = inferModule src

Assert.Empty(ctx.Report.Diagnostics)

let! t =
expandScheme ctx env None (env.FindScheme "FooAndBar") Map.empty None
|> Result.mapError CompileError.TypeError

Assert.Equal(t.ToString(), "never")
}

Assert.False(Result.isError res)
13 changes: 7 additions & 6 deletions src/Escalier.TypeChecker/Infer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2242,10 +2242,6 @@ module rec Infer =
result {
let mutable patternTypes = []

// TODO: do two passes
// 1. unify all of the patterns with `exprType`
// 2. infer the types of all of the bodies

// Infer all pattern types
let! assumps =
List.traverseResultM
Expand All @@ -2259,8 +2255,13 @@ module rec Infer =

let mutable newExprTypes: list<Type> = []

// TODO: check mutability when unifying by computing invariant paths
// using checkMutability
// TODO(#335): Check mutability when unifying by computing invariant paths
// using checkMutability.

// TODO(#332): Prevent pattern matching of unions of untagged inexact object
// types. Untagged inexact object types can have extra properties that we
// can't account for that could result in a different pattern being matched
// than the intended one.

// NOTE: the direction of assignability for patternType and exprType is
// reversed. This is because the type of the expression being assigned is
Expand Down
6 changes: 6 additions & 0 deletions src/Escalier.TypeChecker/Unify.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,12 @@ module rec Unify =
{ Kind = TypeKind.Intersection types
Provenance = None }
else if hasExactObjects then
// The intersection of exact types is never unless the types are
// exactly the same. Checking if two object types are exactly the
// same is expensive so we just return `never` for now. Spread
// types should be used instead of intersection types when working
// with object types since it actually corresponds to a real value-
// level operation.
return
{ Kind = TypeKind.Keyword Keyword.Never
Provenance = None }
Expand Down

0 comments on commit 655400b

Please sign in to comment.