Stress test on type system involving many statically resolved type parameters
Succinct description of the issue
I found a case involving a few inline functions/operators and many statically resolved type parameters for which the compiler cannot found a solution.
Steps required to reproduce the problem
Consider this code.
type Matrix<'a> =
{ m11: 'a; m12: 'a; m13: 'a
m21: 'a; m22: 'a; m23: 'a
m31: 'a; m32: 'a; m33: 'a } with
// fails to compile with the next line
static member inline (/) (m, s) =
// successfully compiles with the next line
//static member inline (/) ((m: Matrix<'b>), (s: 'b)) : Matrix<'b> =
{ m11 = m.m11 / s; m12 = m.m12 / s; m13 = m.m13 / s
m21 = m.m21 / s; m22 = m.m22 / s; m23 = m.m23 / s
m31 = m.m31 / s; m32 = m.m32 / s; m33 = m.m33 / s }
let inline determinant m =
m.m11 * m.m22 * m.m33
+ m.m12 * m.m23 * m.m31
+ m.m13 * m.m21 * m.m32
- m.m31 * m.m22 * m.m13
- m.m32 * m.m23 * m.m11
- m.m33 * m.m21 * m.m12
let inline inverse m =
{ m11 = m.m22 * m.m33 - m.m32 * m.m23; m12 = m.m13 * m.m32 - m.m33 * m.m12; m13 = m.m12 * m.m23 - m.m22 * m.m13
m21 = m.m23 * m.m31 - m.m33 * m.m21; m22 = m.m11 * m.m33 - m.m31 * m.m13; m23 = m.m13 * m.m21 - m.m23 * m.m11
m31 = m.m21 * m.m32 - m.m31 * m.m22; m32 = m.m12 * m.m31 - m.m32 * m.m11; m33 = m.m11 * m.m22 - m.m21 * m.m12 }
/ (determinant m)
ZIP of solution containing that code.
Expected behavior
The code compiles.
Actual behavior
The codes doesn't compile. Here is the build output.
1>------ Build started: Project: Temp, Configuration: Debug Any CPU ------
1>C:\Code\Temp\Program.fs(7,32): error FS0073: internal error: Undefined or unsolved type variable: ^_?16523
1>C:\Code\Temp\Program.fs(23,3): error FS0073: internal error: Undefined or unsolved type variable: ^_?16523
1>C:\Code\Temp\Program.fs(23,3): error FS0073: internal error: Undefined or unsolved type variable: ^_?16522
1>C:\Code\Temp\unknown(1,1): error FS0073: internal error: Undefined or unsolved type variable: ^_?16523
1>C:\Code\Temp\Program.fs(23,3): error FS0073: internal error: Undefined or unsolved type variable: ^_?16523
1>C:\Code\Temp\Program.fs(23,3): error FS0193: A type parameter is missing a constraint 'when ( ^i or ^?16523) : (static member ( / ) : ^i * ^?16523 -> ^?16522)'
1>Done building project "Temp.fsproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Known workarounds
Add more type annotations...specifically by commenting in the commented out line (and then commenting out the line it replaces).
Related information
- Operating system: WIndows 10 Enterprise Version 10.0.18362 Build 18362
- .NET Runtime kind: The MWE targets .NET Core and my most recent version of that is 3.1.202 (x64)
- Editing Tools: Visual Studio Enterprise 2019 Version 16.5.5
This does seem like a bug, here is another example that is smaller but has the same issue:
type Test<'a> =
{ x: 'a } with
static member inline (/) (m, s) = { x = m.x / s; }
let inline determinant m = m.x
let inline inverse m = { x = m.x } / (determinant m)
I'd imagine this is fixed in feature/ext branch, we should check
Smaller repro:
type Matrix<'a> = { m11: 'a }
static member inline (/) (m: Matrix<'b>, s) = { m11 = m.m11 / s }
let inline inverse (m: Matrix<'a>) = m / m