RequireQualifiedAccess does not prevent names from being shadowed
RequireQualifiedAccess typically prevents names from being shadowed, but in at least one specific case it does not seem to do so.
Repro steps
module Foo =
[<RequireQualifiedAccess>]
type Bar = A
[<RequireQualifiedAccess>]
type Baz = Bar | B
match Foo.Bar.A with
| Foo.Bar.A -> ()
| Foo.Bar.A -> ();;
----------^
stdin(8,11): error FS1127: This is not a constructor or literal, or a constructor is being used incorrectly
The removal of B makes the problem go away, as does opening Foo. Removing RequireQualifiedAccess from the first Bar makes no difference.
Known workarounds
Opening the module works around the issue, but is not always desirable. An AutoOpen module can be abused to simulate a local open:
[<AutoOpen>]
module Workaround =
open Foo
let work around =
match around with
| Bar.A -> ()
let x = work Foo.Bar.A
Related information
https://github.com/dotnet/fsharp/issues/8875 looks similar but RequireQualifiedAccess, which does not work here, is mentioned as a workaround.
I see what's happening now - this is actually hitting a deprecated feature that is only giving a warning - we resolve Foo.Bar to the union case but give a warning:
> module Foo =
- [<RequireQualifiedAccess>]
- type Bar = A
- [<RequireQualifiedAccess>]
- type Baz = Bar | B
- ;;
> Foo.Bar;;
Foo.Bar;;
^^^^^^^
stdin(7,1): warning FS0035: This construct is deprecated: The union type for union case 'Bar' was defined with the RequireQualifiedAccessAttribute. Include the name of the union type ('Baz') in the name you are using.
This was done to avoid giving a breaking change.
We should turn this deprecation warning into an error for next release of F#
I've added #13182 to give an error for the deprecated feature.
This will allow us in some subsequent version to give the adjusted name resolution.
Resolved by https://github.com/dotnet/fsharp/pull/13182