fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

"Unused open" is reported for a module when a provided type abbreviation constructor is used from it

Open DedSec256 opened this issue 5 years ago • 0 comments

Repro steps

  1. Create module A with abbreviated provided type
  2. Create module B with opened module A
  3. Сall the abbreviation constructor inside the module B

Expected behavior

Open is used, similar to non-provided abbreviations

Actual behavior

Opened module A with a provided type is reported as unused

Screenshots example:

image

And here really open is not redundant

image

Known workarounds

Module revealed symbols are stored in a HashSet, and when the UnusedOpens analyzer tries to find called abbreviation constructor among them using ItemsAreEffectivelyEqual/ItemsAreEffectivelyEqualHash, it maps the constructor to its ApparentEnclosingType, which will compare against the module revealed symbols. https://github.com/dotnet/fsharp/blob/main/src/fsharp/NameResolution.fs#L1683

Here is the root cause I think: ApparentEnclosingType from provided method/constructor returns its declaring type, when for non-provided -- true abbreviation, which symbol contains in the opened module. https://github.com/dotnet/fsharp/blob/main/src/fsharp/infos.fs#L930

One easy way to solve the problem is to add the abbreviated provided type symbol to the revealed symbols of the open module in https://github.com/dotnet/fsharp/blob/main/src/fsharp/service/ServiceAnalysis.fs#L23

if ent.IsFSharpAbbreviation then
    let abbrType = ent.AbbreviatedType
    if abbrType.HasTypeDefinition then
        let typeDefinition = abbrType.TypeDefinition
        if typeDefinition.IsProvided then
            yield typeDefinition :> FSharpSymbol

However, this solution only applies to UnusedOpens analyzer and is probably hiding some problems.

Repro project: UnusedOpenRepro.zip

DedSec256 avatar Feb 08 '21 20:02 DedSec256