dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.93k stars 787 forks source link

Stress test on type system involving many statically resolved type parameters #9382

Open TysonMN opened 4 years ago

TysonMN commented 4 years ago

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

TIHan commented 4 years ago

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)
dsyme commented 4 years ago

I'd imagine this is fixed in feature/ext branch, we should check

dsyme commented 3 years ago

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