Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when property has same name as DU case #17088

Merged
merged 14 commits into from
Apr 30, 2024
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.400.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
### Fixed

* Improve error reporting for abstract members when used in classes. ([PR #17063](https://github.com/dotnet/fsharp/pull/17063))
* Improve error reporting when property has same name as DU case. ([Issue #16646](https://github.com/dotnet/fsharp/issues/16646), [PR #17088](https://github.com/dotnet/fsharp/pull/17088))
* Make typechecking of indexed setters with tuples on the right more consistent. ([Issue #16987](https://github.com/dotnet/fsharp/issues/16987), [PR #17017](https://github.com/dotnet/fsharp/pull/17017))
* Static abstract method on classes no longer yields internal error. ([Issue #17044](https://github.com/dotnet/fsharp/issues/17044), [PR #17055](https://github.com/dotnet/fsharp/pull/17055))
* Disallow calling abstract methods directly on interfaces. ([Issue #14012](https://github.com/dotnet/fsharp/issues/14012), [Issue #16299](https://github.com/dotnet/fsharp/issues/16299), [PR #17021](https://github.com/dotnet/fsharp/pull/17021))
Expand Down
11 changes: 10 additions & 1 deletion src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9411,7 +9411,17 @@ and TcLookupItemThen cenv overallTy env tpenv mObjExpr objExpr objExprTy delayed
TcTraitItemThen cenv overallTy env (Some objExpr) traitInfo tpenv mItem delayed

| Item.DelegateCtor _ -> error (Error (FSComp.SR.tcConstructorsCannotBeFirstClassValues(), mItem))

| Item.UnionCase(info, _) ->
let clashingNames = info.Tycon.MembersOfFSharpTyconSorted |> List.tryFind(fun mem -> mem.DisplayNameCore = info.DisplayNameCore)
match clashingNames with
| None -> ()
| Some value ->
let kind = if value.IsMember then "member" else "value"
errorR (NameClash(info.DisplayNameCore, kind, info.DisplayNameCore, value.Range, FSComp.SR.typeInfoUnionCase(), info.DisplayNameCore, value.Range))
errorR (NameClash(info.DisplayNameCore, kind, info.DisplayNameCore, mItem, FSComp.SR.typeInfoUnionCase(), info.DisplayNameCore, mItem))

error (Error (FSComp.SR.tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields(), mItem))
// These items are not expected here - they can't be the result of a instance member dot-lookup "expr.Ident"
| Item.ActivePatternResult _
| Item.CustomOperation _
Expand All @@ -9421,7 +9431,6 @@ and TcLookupItemThen cenv overallTy env tpenv mObjExpr objExpr objExprTy delayed
| Item.ModuleOrNamespaces _
| Item.TypeVar _
| Item.Types _
| Item.UnionCase _
| Item.UnionCaseField _
| Item.UnqualifiedType _
| Item.Value _
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -721,3 +721,33 @@ type U =
|> shouldFail
|> withSingleDiagnostic (Error 912, Line 4, Col 3, Line 4, Col 28, "This declaration element is not permitted in an augmentation")


[<Fact>]
let ``Error when property has same name as DU case`` () =
Fsx """
type MyId =
| IdA of int
| IdB of string
| IdC of float

member this.IdA =
match this with
| IdA x -> Some x
| _ -> None

member this.IdX =
match this with
| IdB x -> Some x
| _ -> None

member this.IdC =
match this with
| IdC x -> Some x
| _ -> None
"""
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 23, Line 7, Col 17, Line 7, Col 20, "The member 'IdA' can not be defined because the name 'IdA' clashes with the union case 'IdA' in this type or module")
(Error 23, Line 17, Col 17, Line 17, Col 20, "The member 'IdC' can not be defined because the name 'IdC' clashes with the union case 'IdC' in this type or module")
]
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,42 @@ let _ = asQ.Select _.Length
"""
|> withLangVersion80
|> typecheck
|> shouldSucceed
|> shouldSucceed

[<Fact>]
let ``Error when property has same name as DU case`` () =
Fsx """
type MyId =
| IdA of int
| IdB of string
| IdC of float

member this.IdA =
match this with
| IdA x -> Some x
| _ -> None

member this.IdX =
match this with
| IdB x -> Some x
| _ -> None

member this.IdC =
match this with
| IdC x -> Some x
| _ -> None

let onlyIdA (ids: MyId list) = ids |> List.choose _.IdA
let onlyIdX (ids: MyId list) = ids |> List.choose _.IdX
edgarfgp marked this conversation as resolved.
Show resolved Hide resolved
let onlyIdD (ids: MyId list) = ids |> List.choose _.IdC
"""
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 23, Line 7, Col 17, Line 7, Col 20, "The member 'IdA' can not be defined because the name 'IdA' clashes with the union case 'IdA' in this type or module");
edgarfgp marked this conversation as resolved.
Show resolved Hide resolved
(Error 23, Line 22, Col 51, Line 22, Col 56, "The member 'IdA' can not be defined because the name 'IdA' clashes with the union case 'IdA' in this type or module");
(Error 812, Line 22, Col 51, Line 22, Col 56, "The syntax 'expr.id' may only be used with record labels, properties and fields");
(Error 23, Line 17, Col 17, Line 17, Col 20, "The member 'IdC' can not be defined because the name 'IdC' clashes with the union case 'IdC' in this type or module");
(Error 23, Line 24, Col 51, Line 24, Col 56, "The member 'IdC' can not be defined because the name 'IdC' clashes with the union case 'IdC' in this type or module");
(Error 812, Line 24, Col 51, Line 24, Col 56, "The syntax 'expr.id' may only be used with record labels, properties and fields")
]
Loading