Skip to content

Commit cae9b22

Browse files
authored
Fix nativeptr type erasure to preserve element type in overload resolution (#18911)
1 parent 05b9999 commit cae9b22

File tree

10 files changed

+87
-13
lines changed

10 files changed

+87
-13
lines changed

docs/release-notes/.FSharp.Compiler.Service/11.0.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Scripts: Fix resolving the dotnet host path when an SDK directory is specified. ([PR #18960](https://github.com/dotnet/fsharp/pull/18960))
44
* Fix excessive StackGuard thread jumping ([PR #18971](https://github.com/dotnet/fsharp/pull/18971))
5+
* Adjust conservative method-overload duplicate detection rules for nativeptr types ([PR #18911](https://github.com/dotnet/fsharp/pull/18911))
56
* Checking: Fix checking nested fields for records and anonymous ([PR #18964](https://github.com/dotnet/fsharp/pull/18964))
67
* Fix name is bound multiple times is not reported in 'as' pattern ([PR #18984](https://github.com/dotnet/fsharp/pull/18984))
78
* Fix: warn FS0049 on upper union case label. ([PR #19003](https://github.com/dotnet/fsharp/pull/19003))

docs/release-notes/.Language/preview.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616

1717
* Warn on uppercase identifiers in patterns. ([PR #15816](https://github.com/dotnet/fsharp/pull/15816))
1818
* Error on invalid declarations in type definitions.([Issue #10066](https://github.com/dotnet/fsharp/issues/10066), [PR #18813](https://github.com/dotnet/fsharp/pull/18813))
19+
* Fix type erasure logic for `nativeptr<'T>` overloads to properly preserve element type differences during duplicate member checking. ([Issue #<ISSUE_NUMBER>](https://github.com/dotnet/fsharp/issues/<ISSUE_NUMBER>), [PR #<PR_NUMBER>](https://github.com/dotnet/fsharp/pull/<PR_NUMBER>))
1920

2021
### Changed

src/Compiler/TypedTree/TypedTreeOps.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,8 @@ let rec stripTyEqnsAndErase eraseFuncAndTuple (g: TcGlobals) ty =
799799
let reducedTy2 = addNullnessToTy nullness reducedTy
800800
stripTyEqnsAndErase eraseFuncAndTuple g reducedTy2
801801
elif tyconRefEq g tcref g.nativeptr_tcr && eraseFuncAndTuple then
802-
stripTyEqnsAndErase eraseFuncAndTuple g g.nativeint_ty
802+
// Regression fix (issue #7428): nativeptr<'T> erases to ilsigptr<'T>, not nativeint
803+
stripTyEqnsAndErase eraseFuncAndTuple g (TType_app(g.ilsigptr_tcr, args, nullness))
803804
else
804805
ty
805806

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module NativePtrOverloads01
2+
open Microsoft.FSharp.NativeInterop
3+
#nowarn "9"
4+
5+
type P =
6+
static member Do(p: nativeptr<int>) = 1
7+
static member Do(p: nativeptr<int64>) = 2
8+
9+
let _invoke (pi: nativeptr<int>) (pl: nativeptr<int64>) = P.Do pi + P.Do pl
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module NativePtrOverloads02
2+
open Microsoft.FSharp.NativeInterop
3+
#nowarn "9"
4+
5+
type Q =
6+
static member M(p: nativeptr<int>) = 0
7+
static member M(p: nativeptr<int>) = 1 // expect duplicate member error
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module NativePtrOverloads03
2+
open Microsoft.FSharp.NativeInterop
3+
#nowarn "9"
4+
// Regression test for issue #7428
5+
6+
type R =
7+
static member F(p: nativeptr<uint16>) = 0us
8+
static member F(p: nativeptr<int64>) = 0L
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module NativePtrOverloads04
2+
open Microsoft.FSharp.NativeInterop
3+
#nowarn "9"
4+
[<Measure>] type kg
5+
[<Measure>] type m
6+
7+
type S =
8+
static member H(p: nativeptr<int<kg>>) = 1
9+
static member H(p: nativeptr<int<m>>) = 2 // expect duplicate member error

tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OverloadingMembers/OverloadingMembers.fs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,49 @@ module MemberDefinitions_OverloadingMembers =
235235
compilation
236236
|> verifyCompileAndRun
237237
|> shouldSucceed
238+
239+
// Native pointer overload tests for regression fix
240+
241+
// NativePtrOverloads01.fs - distinct native pointer element types should compile
242+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"NativePtrOverloads01.fs"|])>]
243+
let ``NativePtrOverloads01_fs`` compilation =
244+
compilation
245+
|> asLibrary
246+
|> withOptions ["--nowarn:9"]
247+
|> compile
248+
|> shouldSucceed
249+
250+
// NativePtrOverloads02.fs - duplicate exact signatures should fail
251+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"NativePtrOverloads02.fs"|])>]
252+
let ``NativePtrOverloads02_fs`` compilation =
253+
compilation
254+
|> asLibrary
255+
|> withOptions ["--nowarn:9"]
256+
|> compile
257+
|> shouldFail
258+
|> withDiagnostics [
259+
(Error 438, Line 7, Col 19, Line 7, Col 20, "Duplicate method. The method 'M' has the same name and signature as another method in type 'Q'.")
260+
(Error 438, Line 6, Col 19, Line 6, Col 20, "Duplicate method. The method 'M' has the same name and signature as another method in type 'Q'.")
261+
]
262+
263+
// NativePtrOverloads03.fs - regression test, previously failing overloads should now compile
264+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"NativePtrOverloads03.fs"|])>]
265+
let ``NativePtrOverloads03_fs`` compilation =
266+
compilation
267+
|> asLibrary
268+
|> withOptions ["--nowarn:9"]
269+
|> compile
270+
|> shouldSucceed
271+
272+
// NativePtrOverloads04.fs - erased differences via measures should still fail
273+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"NativePtrOverloads04.fs"|])>]
274+
let ``NativePtrOverloads04_fs`` compilation =
275+
compilation
276+
|> asLibrary
277+
|> withOptions ["--nowarn:9"]
278+
|> compile
279+
|> shouldFail
280+
|> withDiagnostics [
281+
(Error 438, Line 9, Col 19, Line 9, Col 20, "Duplicate method. The method 'H' has the same name and signature as another method in type 'S' once tuples, functions, units of measure and/or provided types are erased.")
282+
(Error 438, Line 8, Col 19, Line 8, Col 20, "Duplicate method. The method 'H' has the same name and signature as another method in type 'S' once tuples, functions, units of measure and/or provided types are erased.")
283+
]

tests/fsharp/typecheck/sigs/neg23.bsl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@ neg23.fs(28,21,28,24): typecheck error FS0438: Duplicate method. The method 'Foo
1111

1212
neg23.fs(26,21,26,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure3.SomeClass'.
1313

14-
neg23.fs(55,21,55,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure6.SomeClass' once tuples, functions, units of measure and/or provided types are erased.
15-
16-
neg23.fs(53,21,53,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure6.SomeClass' once tuples, functions, units of measure and/or provided types are erased.
17-
18-
neg23.fs(64,21,64,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure7.SomeClass' once tuples, functions, units of measure and/or provided types are erased.
19-
20-
neg23.fs(62,21,62,24): typecheck error FS0438: Duplicate method. The method 'Foo' has the same name and signature as another method in type 'DuplicateOverloadUpToErasure7.SomeClass' once tuples, functions, units of measure and/or provided types are erased.
21-
2214
neg23.fs(76,9,76,11): typecheck error FS0410: The type 'IA' is less accessible than the value, member or type 'IB' it is used in.
2315

2416
neg23.fs(83,18,83,20): typecheck error FS0439: The method 'X0' has curried arguments but has the same name as another method in type 'TestCurriedMemberRestrictions.C'. Methods with curried arguments cannot be overloaded. Consider using a method taking tupled arguments.

tests/fsharp/typecheck/sigs/neg23.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,17 @@ module DuplicateOverloadUpToErasure5 = begin
4646
member this.Foo (x:System.Tuple<int,int,int,int,int,int,System.Tuple<int>>) = printfn "method 2"
4747
end
4848

49-
module DuplicateOverloadUpToErasure6 = begin
50-
49+
module NotAnyMoreDuplicateOverloadUpToErasure6 = begin
50+
// This is not the same IL type, not a duplicate
5151
type SomeClass() =
5252

5353
member this.Foo (x:nativeptr<int>) = printfn "method 1"
5454

5555
member this.Foo (x:nativeint) = printfn "method 2"
5656
end
5757

58-
module DuplicateOverloadUpToErasure7 = begin
59-
58+
module NotAnyMoreDuplicateOverloadUpToErasure7 = begin
59+
// This is not the same IL type, not a duplicate
6060
type SomeClass() =
6161

6262
member this.Foo (x:(int*int)*int*(int*nativeptr<int>)*int*int) = printfn "method 1"

0 commit comments

Comments
 (0)