dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.88k stars 783 forks source link

8.0.300 LangVersion preview fails to compile with attribute on DU constructors #17165

Closed dlidstrom closed 4 months ago

dlidstrom commented 4 months ago

I've just discovered that my code doesn't build with F# 8.0.300 and preview language version.

Repro steps

This is my project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Program.fs" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Argu" Version="6.2.3" />
  </ItemGroup>
</Project>

and this is my Program.fs:

open Argu

type Arguments =
  | [<Mandatory>] Username of string
  interface IArgParserTemplate with
    member this.Usage =
      match this with
      | Username _ -> "Specifies the username"

printfn "Hello from F#"

Expected behavior

I expect this to compile cleanly.

Actual behavior

This fails to compile after I upgraded to 8.0.300 (from 8.0.204):

Program.fs(4,7): error FS0842: This attribute is not valid for use on this language element

Known workarounds

Work around is to revert back to latest language version. I am using preview language version for improved string slicing (please upgrade this feature from preview to latest).

Related information

Provide any related information (optional):

.NET SDK:
 Version:           8.0.300
 Commit:            326f6e68b2
 Workload version:  8.0.300-manifests.bce0cb54
 MSBuild version:   17.10.4+10fbfbf2e

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  14.4
 OS Platform: Darwin
 RID:         osx-arm64
 Base Path:   /usr/local/share/dotnet/sdk/8.0.300/

.NET workloads installed:
There are no installed workloads to display.

Host:
  Version:      8.0.5
  Architecture: arm64
  Commit:       087e15321b

.NET SDKs installed:
  8.0.101 [/usr/local/share/dotnet/sdk]
  8.0.204 [/usr/local/share/dotnet/sdk]
  8.0.300 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.15 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
KevinRansom commented 4 months ago

@dlidstrom

Hi, there have been a number of recent PR's improving AttributeTarget evaluation in the F# compiler.

The definition in the Argu repo needs updating: https://github.com/fsprojects/Argu/blob/e3bc012e1ab4d122901a9a0e959943ed26bc27fe/src/Argu/Attributes.fs#L21

In order to be applied to a Union Case, it needs to be modified to include AttributeTargets.Method:

/// Demands at least one parsed result for this argument; a parse exception is raised otherwise.
[<AttributeUsage(AttributeTargets.Class ||| AttributeTargets.Method ||| AttributeTargets.Property, AllowMultiple = false)>]
type MandatoryAttribute () = inherit Attribute ()

I imagine that a few more options need adding as well.

Thanks

Kevin

image

KevinRansom commented 4 months ago

Here is the text of a repro:

open System

/// Interface that must be implemented by all Argu template types
type IArgParserTemplate =
    /// returns a usage string for every union case
    abstract Usage : string

/// Demands at least one parsed result for this argument; a parse exception is raised otherwise.
[<AttributeUsage(AttributeTargets.Class ||| AttributeTargets.Method ||| AttributeTargets.Property, AllowMultiple = false)>]
type MandatoryAttribute () = inherit Attribute ()

type Arguments =
  | [<Mandatory>] Username of string
  interface IArgParserTemplate with
    member this.Usage =
      match this with
      | Username _ -> "Specifies the username"

printfn "Hello from F#"
dlidstrom commented 4 months ago

Hi @KevinRansom ! Thanks for letting me know. I will take this with the Argu project then :+1: Feel free to close this.

Martin521 commented 4 months ago

This leaves the question why FS-1076 / #7781, which was merged in November 2019, is still in preview.

vzarytovskii commented 4 months ago

This leaves the question why FS-1076 / #7781, which was merged in November 2019, is still in preview.

It's incomplete.

KevinRansom commented 4 months ago

@Martin521 it's in preview because we don't know that there aren't bugs. Preview allows us to get it in front of developers who can try it out on their code, so that we can decide. It would be fair to say though that for this particular feature, probably not a lot of review is required.

KevinRansom commented 4 months ago

closing this issue - as I suppose "By Design"