Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/Fable.Transforms/FSharp2Fable.Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1998,6 +1998,36 @@ module Identifiers =
let tryGetIdentFromScope (ctx: Context) r typ (fsRef: FSharpMemberOrFunctionOrValue) =
tryGetIdentFromScopeIf ctx r typ fsRef.Equals

let getDeclaredIdentNames (expr: Fable.Expr) =
let names = HashSet<string>()

let rec loop (e: Fable.Expr) =
let declared: Fable.Ident list =
match e with
| Fable.Let(i, _, _)
| Fable.Lambda(i, _, _)
| Fable.ForLoop(i, _, _, _, _, _)
| Fable.TryCatch(_, Some(i, _), _, _) -> [ i ]
| Fable.LetRec(bindings, _) -> List.map fst bindings
| Fable.Delegate(args, _, _, _) -> args
| Fable.DecisionTree(_, targets) -> List.collect fst targets
| Fable.ObjectExpr(members, _, _) -> List.collect (fun (m: Fable.ObjectExprMember) -> m.Args) members
| _ -> []

for i in declared do
names.Add(i.Name) |> ignore

match e with
| Fable.Unresolved(Fable.UnresolvedTraitCall(argExprs = argExprs), _, _) -> argExprs
| Fable.Unresolved(Fable.UnresolvedInlineCall(_, _, callee, info), _, _) ->
Option.toList callee @ Option.toList info.ThisArg @ info.Args
| Fable.Unresolved(Fable.UnresolvedReplaceCall(thisArg, args, _, _), _, _) -> Option.toList thisArg @ args
| e -> getSubExpressions e
|> List.iter loop

loop expr
set names

module Util =
open Helpers
open Patterns
Expand Down
4 changes: 3 additions & 1 deletion src/Fable.Transforms/FSharp2Fable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2875,13 +2875,15 @@ let resolveInlineExpr (com: IFableCompiler) ctx info expr =
| None -> transformTraitCall com ctx r t sourceTypes traitName isInstance argTypes argExprs
| Some w ->
// As witnesses come from the context, idents may be duplicated, see #2855
// The same witness can be inlined several times in one scope, see #3921
let info =
{ info with
ScopeIdents = Set.union info.ScopeIdents (getDeclaredIdentNames w.Expr)
ResolvedIdents = Dictionary()
FileName = w.FileName
}

let callee = resolveInlineExpr com ctx { info with FileName = w.FileName } w.Expr
let callee = resolveInlineExpr com ctx info w.Expr

let callInfo = makeCallInfo None argExprs argTypes
makeCall r t callInfo callee
Expand Down
50 changes: 50 additions & 0 deletions tests/Js/Main/ApplicativeTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,9 +1093,9 @@
testCase "SRTP with inlined functions relying on generic info works" <| fun () -> // See #2135
let t2: int option =
Error 1
|> fun x -> (^``Applicative<'T>`` : (static member Return : ^T -> ^``Applicative<'T>``) x)

Check warning on line 1096 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (ubuntu-latest)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1096 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (windows-latest)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1096 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Compiler/Fable.Compiler.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1096 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.AST/Fable.AST.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1096 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Transforms/Fable.Transforms.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.
// |> Const.Return
|> Const.run

Check warning on line 1098 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (ubuntu-latest)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1098 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (ubuntu-latest)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1098 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (windows-latest)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1098 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (windows-latest)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1098 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Compiler/Fable.Compiler.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1098 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Compiler/Fable.Compiler.fsproj)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1098 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Transforms/Fable.Transforms.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1098 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Transforms/Fable.Transforms.fsproj)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.
|> First.run

equal None t2
Expand Down Expand Up @@ -1718,7 +1718,7 @@
static member inline map (Functor, f: 'a -> 'b, x: List<'a>) = List.map f x

let inline map (f: ^a -> ^b) (x: ^x) =
((^x or ^Functor): (static member map: ^Functor * (^a -> ^b) * ^x -> ^r) (Functor, f, x))

Check warning on line 1721 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (ubuntu-latest)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

Check warning on line 1721 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / build-javascript (windows-latest)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

Check warning on line 1721 in tests/Js/Main/ApplicativeTests.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Compiler/Fable.Compiler.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

type NonEmptyList<'T> = NonEmptyList of 'T * List<'T> with
static member inline map (Functor, f: 'a -> 'b, NonEmptyList(h, t): NonEmptyList<'a>) =
Expand All @@ -1727,6 +1727,53 @@
let private mapMyList (xs: NonEmptyList<string>) : NonEmptyList<string> =
map (fun s -> s + "_") xs

let mutable codecCalls = 0

type Codec<'a> = Codec of (unit -> int)

type Codecs =
static member inline Codecs(_output: int, _mthd: Codecs) : Codec<int> = Codec(fun () -> 0)
static member inline Codecs(_output: bool, _mthd: Codecs) : Codec<bool> = Codec(fun () -> 0)

static member inline Invoke() =
let inline call_2 (a: ^a, b: ^b) =
((^a or ^b): (static member Codecs: _ * _ -> _) b, a)

let inline call (a: 'a) =
call_2 (a, Unchecked.defaultof<'r>): Codec<'r>

call Unchecked.defaultof<Codecs>

type Codecs with
static member inline Codecs< ^a, ^b
when (^a): (static member codecInner: Codec< ^b > -> Codec< ^a >)
and (Codecs or ^b): (static member Codecs: ^b * Codecs -> Codec< ^b >)>
(_output: ^a, _mthd: Codecs)
: Codec< ^a > =
codecCalls <- codecCalls + 1
let x = codecCalls * 10
let (Codec inner) = 'a.codecInner (Codecs.Invoke())
Codec(fun () -> x + inner ())

let inline getCodecs<'a, 'b
when (Codecs or ^a): (static member Codecs: ^a * Codecs -> Codec< ^a >)
and (Codecs or ^b): (static member Codecs: ^b * Codecs -> Codec< ^b >)>
()
: Codec< ^a > * Codec< ^b > =
let a: Codec<'a> = Codecs.Invoke()
let b: Codec<'b> = Codecs.Invoke()
(a, b)

type CodecContainer<'T> =
| CodecContainer

static member codecInner(Codec f: Codec<'T>) : Codec<CodecContainer<'T>> = Codec(fun () -> f () + 1)

let getContainerCodecs () =
codecCalls <- 0
let (Codec a), (Codec b) = (getCodecs () : Codec<CodecContainer<int>> * Codec<CodecContainer<int>>)
a (), b ()

let tests = [
testCase "Trait call works with multiple inlined functions I" <| fun () -> // See #2809
let account = Some { Details = { Tag = "Test"; InsurancePolicyData = None }}
Expand All @@ -1748,6 +1795,9 @@

testCase "Identifiers from witnesses don't get duplicated when resolving inline expressions" <| fun () -> // See #2855
NonEmptyList("a", ["b"; "c"]) |> mapMyList |> equal (NonEmptyList("a_", ["b_"; "c_"]))

testCase "Identifiers from a witness inlined twice in the same scope don't get duplicated" <| fun () -> // See #3921
getContainerCodecs () |> equal (11, 21)
]

module AccessorFunctionShorthand =
Expand Down
51 changes: 51 additions & 0 deletions tests/Python/TestApplicative.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,9 +1085,9 @@
let ``test SRTP with inlined functions relying on generic info works`` () = // See #2135
let t2: int option =
Error 1
|> fun x -> (^``Applicative<'T>`` : (static member Return : ^T -> ^``Applicative<'T>``) x)

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Transforms/Rust/AST/Rust.AST.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.13)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Compiler/Fable.Compiler.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.15)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.14)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.13)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.AST/Fable.AST.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.15)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Transforms/Fable.Transforms.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.

Check warning on line 1088 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.14)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'Result<'a,int>'.
// |> Const.Return
|> Const.run

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Transforms/Rust/AST/Rust.AST.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Transforms/Rust/AST/Rust.AST.fsproj)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.13)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.13)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.15)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.15)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.14)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.14)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.13)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.13)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.AST/Fable.AST.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.AST/Fable.AST.fsproj)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.15)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.15)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.Transforms/Fable.Transforms.fsproj)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.14)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Applicative<'T> has been constrained to be type 'Const<'a,Result<'b,int>>'.

Check warning on line 1090 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.14)

The instantiation of the generic type 'Const' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. 'Const<_,_>'.
|> First.run

equal None t2
Expand Down Expand Up @@ -1650,7 +1650,7 @@
static member inline map (Functor, f: 'a -> 'b, x: List<'a>) = List.map f x

let inline map (f: ^a -> ^b) (x: ^x) =
((^x or ^Functor): (static member map: ^Functor * (^a -> ^b) * ^x -> ^r) (Functor, f, x))

Check warning on line 1653 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.13)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

Check warning on line 1653 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.15)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

Check warning on line 1653 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.14)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

Check warning on line 1653 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (windows-latest, 3.13)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

Check warning on line 1653 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / analyzers (src/Fable.AST/Fable.AST.fsproj)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

Check warning on line 1653 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.15)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

Check warning on line 1653 in tests/Python/TestApplicative.fs

View workflow job for this annotation

GitHub Actions / build-python (ubuntu-latest, 3.14)

This construct causes code to be less generic than indicated by the type annotations. The type variable 'Functor has been constrained to be type 'Functor'.

type NonEmptyList<'T> = NonEmptyList of 'T * List<'T> with
static member inline map (Functor, f: 'a -> 'b, NonEmptyList(h, t): NonEmptyList<'a>) =
Expand All @@ -1659,6 +1659,53 @@
let mapMyList (xs: NonEmptyList<string>) : NonEmptyList<string> =
map (fun s -> s + "_") xs

let mutable codecCalls = 0

type Codec<'a> = Codec of (unit -> int)

type Codecs =
static member inline Codecs(_output: int, _mthd: Codecs) : Codec<int> = Codec(fun () -> 0)
static member inline Codecs(_output: bool, _mthd: Codecs) : Codec<bool> = Codec(fun () -> 0)

static member inline Invoke() =
let inline call_2 (a: ^a, b: ^b) =
((^a or ^b): (static member Codecs: _ * _ -> _) b, a)

let inline call (a: 'a) =
call_2 (a, Unchecked.defaultof<'r>): Codec<'r>

call Unchecked.defaultof<Codecs>

type Codecs with
static member inline Codecs< ^a, ^b
when (^a): (static member codecInner: Codec< ^b > -> Codec< ^a >)
and (Codecs or ^b): (static member Codecs: ^b * Codecs -> Codec< ^b >)>
(_output: ^a, _mthd: Codecs)
: Codec< ^a > =
codecCalls <- codecCalls + 1
let x = codecCalls * 10
let (Codec inner) = 'a.codecInner (Codecs.Invoke())
Codec(fun () -> x + inner ())

let inline getCodecs<'a, 'b
when (Codecs or ^a): (static member Codecs: ^a * Codecs -> Codec< ^a >)
and (Codecs or ^b): (static member Codecs: ^b * Codecs -> Codec< ^b >)>
()
: Codec< ^a > * Codec< ^b > =
let a: Codec<'a> = Codecs.Invoke()
let b: Codec<'b> = Codecs.Invoke()
(a, b)

type CodecContainer<'T> =
| CodecContainer

static member codecInner(Codec f: Codec<'T>) : Codec<CodecContainer<'T>> = Codec(fun () -> f () + 1)

let getContainerCodecs () =
codecCalls <- 0
let (Codec a), (Codec b) = (getCodecs () : Codec<CodecContainer<int>> * Codec<CodecContainer<int>>)
a (), b ()

open MultipleInlines

[<Fact>]
Expand All @@ -1685,6 +1732,10 @@
let ``test Identifiers from witnesses don't get duplicated when resolving inline expressions`` () = // See #2855
NonEmptyList("a", ["b"; "c"]) |> mapMyList |> equal (NonEmptyList("a_", ["b_"; "c_"]))

[<Fact>]
let ``test Identifiers from a witness inlined twice in the same scope don't get duplicated`` () = // See #3921
getContainerCodecs () |> equal (11, 21)

module AccessorFunctionShorthand =

type User =
Expand Down
Loading