fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Attributes defined in a rec module can't be used in the same rec module

Open Booksbaum opened this issue 7 years ago • 2 comments

An Attribute defined in a rec module can't be used in the same rec module.

Repro steps

module rec M

type CustomAttribute () =
  inherit System.Attribute ()

type A = | [<CustomAttribute>] A
type B<[<CustomAttribute>]'a> = | B of 'a

Expected behavior

Snippet should compile without any errors.

Actual behavior

Error for A:

CustomAttribute.fs(6,14): error FS1133: No constructors are available for the type 'CustomAttribute'

Error for B:

CustomAttribute.fs(7,10): error FS0039: The type 'CustomAttribute' is not defined.

(on sharplab)

Known workarounds

Use a non-rec module instead of a rec module (if possible) or move CustomAttribute out of module M

Additional Notes

Moving the Attribute into a nested module doesn't work either:

module rec M

module Nested =
  type CustomAttribute () =
    inherit System.Attribute ()

type A = | [<Nested.CustomAttribute>] A               // Error
type B<[<Nested.CustomAttribute>]'a> = | B of 'a      // Error

A still gives the same error, but for B it can't even find the module Nested:

error FS0039: The namespace or module 'Nested' is not defined.



All snippets work in non-rec modules:

module M

type CustomAttribute () =
  inherit System.Attribute ()

type A = | [<CustomAttribute>] A                    // Valid
type B<[<CustomAttribute>]'a> = | B of 'a           // Valid

In rec modules the CustomAttribute can be used without errors in certain places like:

module rec M

type CustomAttribute () =
  inherit System.Attribute ()

[<CustomAttribute>] type A = | A                    // Valid
[<CustomAttribute>] let a = ()                      // Valid



Special behaviour when Attribute with same name in outer scope:

module Root

type CustomAttribute () =
  inherit System.Attribute ()

module rec M =
  type CustomAttribute () =
    inherit System.Attribute ()

  type A = | [<CustomAttribute>] A                // Error
  type B<[<CustomAttribute>]'a> = | B of 'a       // Valid

A still can't find the ctor for Root.M.CustomAttribute, while B compiles -- but uses Root.CustomAttribute instead of Root.M.CustomAttribute.

So for generic parameters (type B) it seems the compiler still uses the attributes available only in the outer scope, while for union cases (type A) it seems to have updated the current environment with the available types in the rec module -- but only the names, not their content.

The Scoping results in a strange behaviour with a custom MeasureAttribute:

module rec M

type MeasureAttribute () =
  inherit System.Attribute ()

type A<[<Measure>]'a> = A of 'a                   // Error
type B<[<Measure>]'u> = B of int<'u>              // Valid

Instead of using the custom MeasureAttribute it uses Microsoft.FSharp.Core.MeasureAttribute -- making the generic type parameter a measure. Without the rec it uses the correct attribute and correctly recognizes the generics:

module M

type MeasureAttribute () =
  inherit System.Attribute ()

type A<[<Measure>]'a> = A of 'a                   // Valid
type B<[<Measure>]'u> = B of int<'u>              // Error

Related information

This might be related to #3511. Just like here it seems to not correctly update the available attributes in a rec module:

module rec M
open System.Runtime.CompilerServices

type CustomAttribute () =
  inherit System.Attribute ()

[<Custom>]
[<assembly: InternalsVisibleTo("System")>]
do()

Both Attribute usages fail with the same error:

error FS0039: The type 'Custom' is not defined.

error FS0039: The type 'InternalsVisibleTo' is not defined.



  • F# Compiler version 10.2.3 for F# 4.5

Booksbaum avatar Oct 19 '18 06:10 Booksbaum

This is related to #6338 and would be fixed at the same time

dsyme avatar Aug 26 '20 14:08 dsyme

I ran into this issue today and found this thread by trying to figure out what was happening. If support is still not planned, a more relevant error message would be useful.

jcmrva avatar Jul 05 '23 22:07 jcmrva