(Aktualizacja: dodałem repro przykład)Ciekawy błędy podczas łączenia inline z ograniczeniami członkowskich wyraźnych
Z kod wygląda jak następuje:
type Lib =
static member inline tryMe (a: ^a) =
let name = (^a: (static member name: string)())
name
type Test =
struct
val Value: string
new v = {Value = v}
end
static member inline name with get() = "HiThere"
static member works(a:Test) = Lib.tryMe a
To będzie „po prostu działa” i kompilacji . Jeśli jednak przedłużyć go trochę, jak na przykład w następujący sposób:
/// Does a bounds check and raises an error if bounds check is not met
let inline checkBounds f (g: 'b -> ^c) (tp: ^a) =
let convertFrom = (^a: (static member name: string)())
let convertTo = (^c: (static member name : string)())
let value = (^a: (member Value: 'b) tp)
if f value then
g value
else
failwithf "Cannot convert from %s to %s." convertFrom convertTo
type ConverterA =
struct
val Value: sbyte
new v = { Value = v }
end
static member inline name with get() = "converter-a"
static member inline convert (x: ConverterA) : ConverterB =
checkBounds ((>=) 0y) (byte >> ConverterB) x
and ConverterB =
struct
val Value: byte
new v = { Value = v }
end
static member inline name with get() = "converter-b"
Podniesie całą masę fałszywych błędów FSharp kompilatora.
Błąd FS1114: Wartość „Foo.Bar.name” został oznaczony inline ale nie był związany w środowisku optymalizacji
Błąd FS1113: wartość „name” został oznaczony inline ale jego marki wdrożeniowe zastosowanie wewnętrznego lub prywatnego funkcji, która nie jest wystarczająco dostępny FS1116
ostrzeżenie: wartość oznaczone jako „inline” ma nieoczekiwaną wartość
błędzie FS1118: nie można wbudować t on wartość „name” oznaczone „inline”, być może dlatego, że wartość została oznaczona rekurencyjny „inline”
Nie widziałem tego dzieje się z innymi funkcjami inline. Nie jestem pewien, co się tutaj dzieje. Jeśli zmienię tylko trochę, na przykład usuń linię convertTo
i jej zależności, kompiluje się ona dobrze.
Błędy również nie pojawiają się podczas uruchamiania kodu w FSI, nawet przy ustawieniu FSI z --optimize
.
Mogę obejść go, usuwając inline
. Dla pól tego rodzaju nie ma to większego znaczenia, JIT będzie je wstawiał, nawet jeśli F # nie ma.
Czy to błąd kompilatora? Czy jest jakiś błąd w moim kodzie lub jakieś ograniczenie dotyczące wyraźnych ograniczeń członków, których nie znałem?
jak zresztą z drugiej kwestii, to rozwiązuje go jako obejście, ale nie usuwa fakt, że jest to (prawdopodobnie) błąd w F # jak porządek ma być nieistotne tutaj: [mój raport o błędzie z wczoraj] (https://github.com/Microsoft/visualfsharp/issues/1565). – Abel
To prawda, dziękuję za zgłoszenie. Tak jak powiedziałem w drugim komentarzu, myślę, że kompilator nie wie, co umieścić w miejscu, w którym próbuje wstawić. – CodeMonkey