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

[CompilerPerf] make tuples support Item* with warning #4034

Merged
merged 24 commits into from
Jan 22, 2018

Conversation

dsyme
Copy link
Contributor

@dsyme dsyme commented Nov 29, 2017

The RFC issue for this is at https://github.com/fsharp/fslang-design/blob/master/FSharp-4.1b/FS-1046-consistent-tuple-types.md

This is an alternative to #4029 to deal with the gradual emergence of more serious cases of regressions in #3729 because of change #3283

  • For Tuples allow Item1-7 + Rest + new System.Tuple...
  • Warn on explicit use of Item* and Rest
  • Hide these Tuple members from intellisense
  • Only invert correctly encoded tuples into F# tuples

This does not add Item* and Rest* access for struct tuples, since they only became available in F# 4.1 and it is not really necessary to add those to give good warnings for the regression

@cartermp
Copy link
Contributor

This is definitely the better route to go!

@dsyme
Copy link
Contributor Author

dsyme commented Nov 29, 2017

@cartermp Here are the known issues:

  1. Explicit uses of System.Tuple constructors System.Tuple<int,int>(1,2,3) still do not work. They worked in F# 4.0/4.1.early where they returned a .NET tuple type. Uses of System.Tuple.Create do work.

  2. Item* and Rest are not available in any form on System.ValueTuple. This could be enabled but is extra work.

  3. The return type of Rest for large tuples is a .NET tuple type, not made equivalent to its F# tuple type. This doesn't really matter I think since the only programming instances we know of treat Rest as an object, e.g. FsPickler serialization. If necessary a box/unbox can be applied to get it to an equivalent F# tuple type

  4. Because of (3) SRTP programming patterns over tuples relying on complex compile-time resolution of Item and Rest properties (without using any reflection) will not work I expect

@dsyme
Copy link
Contributor Author

dsyme commented Dec 1, 2017

@dotnet-bot Test Windows_NT Release_ci_part1 Build please

@dsyme
Copy link
Contributor Author

dsyme commented Dec 1, 2017

CI is broken, we need to re-test this

@gusty
Copy link
Contributor

gusty commented Dec 4, 2017

I've tested this with some code I had working since F# 2.0, using overload resolution and now it breaks.
I still don't know how to fix it.
I think it's not related to (3).

Copy link
Contributor

@gusty gusty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be great if this commit is split in 3:

  • Add support for Item* and Rest
  • Add warning
  • Add tests

@realvictorprm
Copy link
Contributor

I wouldn't separate the tests

@gusty
Copy link
Contributor

gusty commented Dec 5, 2017

@realvictorprm Why not?

I think it will be better to have them separated to make it easier to understand what makes each change and so I (or someone else) can eventually contribute to fix it.

@dsyme
Copy link
Contributor Author

dsyme commented Dec 5, 2017

@dotnet-bot Test this please

@dsyme
Copy link
Contributor Author

dsyme commented Dec 5, 2017

I've tested this with some code I had working since F# 2.0, using overload resolution and now it breaks. I still don't know how to fix it. I think it's not related to (3).

@gusty I think we'll need a repro for this - could you make one for us? thanks

@realvictorprm
Copy link
Contributor

@gusty In terms of stability I prefer to add tests with a new feature if testable.

@gusty
Copy link
Contributor

gusty commented Dec 5, 2017

@dsyme Yes I can, but since the new Tuple <_, .. syntax is still broken I can't put it in a single snippet.
I have to compile a library with an old version of the compiler in order to get the helpers for the tuple creation and then I can run my code by referencing that dll. That's the way I managed to test my code.

Otherwise, do you know another way to create a System.Tuple ?

I tried this:

let tp2 ((x:'a * 'b)) = unbox<System.Tuple<'a,'b>> (box x)

But it get converted to a syntactic tuple. Honestly I still don't understand the new auto-conversion rules. Because not all System.Tuples get automatically converted, for instance you mention that .Rest will return a System.Tuple and that one somehow doesn't get automatically converted to a syntactic one.

@gusty
Copy link
Contributor

gusty commented Dec 5, 2017

Here's the repro:

Create a dll with this helpers:

let t1 x = Tuple<_>(x)
let t2 (x1,x2) = Tuple<_,_>(x1,x2)
let t3 (x1,x2,x3) = Tuple<_,_,_>(x1,x2,x3)
let t4 (x1,x2,x3,x4) = Tuple<_,_,_,_>(x1,x2,x3,x4)
let t5 (x1,x2,x3,x4,x5) = Tuple<_,_,_,_,_>(x1,x2,x3,x4,x5)
let t6 (x1,x2,x3,x4,x5,x6) = Tuple<_,_,_,_,_,_>(x1,x2,x3,x4,x5,x6)
let t7 (x1,x2,x3,x4,x5,x6,x7) = Tuple<_,_,_,_,_,_,_>(x1,x2,x3,x4,x5,x6,x7)
let cp (x1,x2,x3,x4,x5,x6,x7) t = Tuple<_,_,_,_,_,_,_,_>(x1,x2,x3,x4,x5,x6,x7, t)

Compile it with F# 4.0, then run this script with the FSI produced by this PR

#r "AboveMentioned.dll"
open System
open TupleConstructors  // the helpers contained in that dll
type T = T with
    static member inline ($) (T, t:Tuple<_,_,_,_,_,_,_,'rst>) = fun x -> cp (x,t.Item1, t.Item2,t.Item3,t.Item4,t.Item5,t.Item6) ((T $ t.Rest) t.Item7)
    static member        ($) (T, ())                          = fun x -> t1 (x)
    static member        ($) (T, t:Tuple<_>)                  = fun x -> t2 (x,t.Item1)
    static member        ($) (T, t:Tuple<_,_>)                = fun x -> t3 (x,t.Item1, t.Item2)
    static member        ($) (T, t:Tuple<_,_,_>)              = fun x -> t4 (x,t.Item1, t.Item2,t.Item3)
    static member        ($) (T, t:Tuple<_,_,_,_>)            = fun x -> t5 (x,t.Item1, t.Item2,t.Item3,t.Item4)
    static member        ($) (T, t:Tuple<_,_,_,_,_>)          = fun x -> t6 (x,t.Item1, t.Item2,t.Item3,t.Item4,t.Item5)
    static member        ($) (T, t:Tuple<_,_,_,_,_,_>)        = fun x -> t7 (x,t.Item1, t.Item2,t.Item3,t.Item4,t.Item5,t.Item6)
    static member        ($) (T, t:Tuple<_,_,_,_,_,_,_>)      = fun x -> cp (x,t.Item1, t.Item2,t.Item3,t.Item4,t.Item5,t.Item6) (t1(t.Item7))

This compiled always fine, but now I get all the desired warnings plus:

          static member inline ($) (T, t:Tuple<_,_,_,_,_,_,_,'rst>) = fun x -> cp (x,t.Item1, t.Item2,t.Item3,t.Item4,t.Item5,t.Item6) ((T $ t.Rest) t.Item7)
  -----------------------------------------------------------------------------------------------------------------------------------------^

stdin(32,138): error FS0043: A unique overload for method 'op_Dollar' could not be determined based on type information prior to this program point.
A type annotation may be needed. Candidates: static member T.( $ ) : T:'a * 'b -> 'c, static member T.( $ ) : T:'a * t:Tuple<'b> -> 'c

@cartermp
Copy link
Contributor

cartermp commented Dec 5, 2017

Tagging this for the 15.6 milestone, which is targeted to release early next year.

@gusty
Copy link
Contributor

gusty commented Dec 6, 2017

Regarding SRTPs, the following was always working until the breaking change, this is what I get with this PR:

  (^T : (member get_Item1 : unit -> _ ) (System.Tuple<int,int>(1,3))) ;;
  ---------------------------------------^^^^^^^^^^^^^^^^^^^^^

stdin(1,40): error FS0001: This expression was expected to have type
    'System.Tuple<'a,'b>'
but here has type
    'int * int'

so I try like this (note the following warning was always there, is not new and it makes sense):

  (^T : (member get_Item1 : unit -> _ ) ((1,3))) ;;
  ----------------------------------------^^^

stdin(2,41): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type ''a * 'b'.


  (^T : (member get_Item1 : unit -> _ ) ((1,3))) ;;
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

stdin(2,1): error FS0073: internal error: destAppTy (Failure)
Stack Trace
Microsoft.FSharp.Compiler.ErrorLogger+InternalError: destAppTy (Failure)stdin (2,0--2,46) IsSynthetic=false

... still trying to understand what are the new autoconversion rules

@dsyme
Copy link
Contributor Author

dsyme commented Dec 8, 2017

@gusty OK, - just to clarify - the things you mention are not made particularly worse by this PR (except for the destAppTy (Failure)), but are mostly further examples of problems caused by #3283.

... still trying to understand what are the new autoconversion rules...

The change implemented by #3283 is this:

any occurrence of System.Tuple<...> (whether in .NET metadata or F# syntax) is treated as an F# tuple type if it conforms to the encoding pattern for F# tuple types.

Previously this conversion applied only to occurrences of System.Tuple<...> occurring in .NET metadata and not those occurring in F# syntax.

@gusty
Copy link
Contributor

gusty commented Dec 8, 2017

Thanks @dsyme

just to clarify - the things you mention are not made particularly worse by this PR

Yes, that's what I thought. But hopefully it can be fixed here.

Previously this conversion applied only to occurrences of System.Tuple<...> occurring in .NET metadata and not those occurring in F# syntax.

But then how's possible that the .Rest method returns a System.Tuple and that one is not autoconverted. This makes me think that autoconversion does not happen in all scenarios though I'm still trying to understand in which ones.

@dsyme
Copy link
Contributor Author

dsyme commented Dec 8, 2017

But then how's possible that the .Rest method returns a System.Tuple and that one is not autoconverted.

It is a mistake in this PR, I will fix it for the sake of consistency

@dsyme
Copy link
Contributor Author

dsyme commented Dec 8, 2017

@gusty I've fixed the problems with both SRTP and new Tuple<int,int>(3,4).

@cartermp I've created an F# 4. RFC about this whole mess https://github.com/fsharp/fslang-design/blob/master/FSharp-4.1b/FS-1046-consistent-tuple-types.md. We can gradually fill in more detail there to document the issue

@gusty
Copy link
Contributor

gusty commented Dec 8, 2017

@dsyme I can see it's fixed but I still notice some inconsistencies:

  • From my first repro, if you call the constructor methods from the compiled .dll you still get a System tuple.

  • Also the result of calling the overloaded functions in that repro is seen as a System.Tuple

@gusty
Copy link
Contributor

gusty commented Dec 8, 2017

Actually is the 8-tuple constructor which is not converting, try this:

> new System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,(8,9));;
val it : Tuple<int,int,int,int,int,int,int,(int * int)> =
 (1, 2, 3, 4, 5, 6, 7, 8, 9)

@dsyme
Copy link
Contributor Author

dsyme commented Jan 20, 2018

I made some code sanitizations that reduced some indirections and indirect calls, and this seemed to improve things

master   248.19 11.42                30.85                49.38                58.30                60.07               
this pr: 252.87 11.39                31.05                47.19                59.79                60.41               

So perhaps a small slow down showing now but nothing like the previous measure (which may have been a mis-measurement in any case)

CI part 2 failed due to a virus check failure on load-script

@dsyme
Copy link
Contributor Author

dsyme commented Jan 20, 2018

@dotnet-bot test Windows_NT Release_ci_part1 Build please

@dsyme
Copy link
Contributor Author

dsyme commented Jan 20, 2018

A test failure was causing CI part 1 to hang. Now that's fixed the actual failures from those unit tests have been revealed, and there a whole bunch of them - it looks like there is some common cause to all of these

1) Failed : Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn.CompletionProviderTests.ShouldDisplaySystemNamespace

Expected completions not found:
	Console
	Array
	String

in Completions:
	<Note>
at Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn.CompletionProviderTests.VerifyCompletionList(String fileContents, String marker, FSharpList`1 expected, FSharpList`1 unexpected) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\CompletionProviderTests.fs:line 100
at Microsoft.VisualStudio.FSharp.Editor.Tests.Roslyn.CompletionProviderTests.ShouldDisplaySystemNamespace() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\CompletionProviderTests.fs:line 310

2) Failed : Tests.LanguageService.AutoCompletion.UsingMSBuild.Array.AfterOperator...Bug65732_A
Couldn't find 'Int32' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@59-2.Invoke(CompletionItem[] completions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 60
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoCompleteUsingExtraRefs(FSharpList`1 refs, Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 50
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoComplete(Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 54
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@58-1.Invoke(FSharpList`1 code, String marker, FSharpList`1 should, FSharpList`1 shouldnot) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 58
at Tests.LanguageService.AutoCompletion.UsingMSBuild.Array.AfterOperator...Bug65732_A() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 3110

3) Failed : Tests.LanguageService.AutoCompletion.UsingMSBuild.BestMatch.Bug4320a
Expected:
Some ("GC", false, true)

but got:
Some ("", false, false).
at UnitTests.TestLib.Salsa.AssertEqual[a](a expected, a actual) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\TestLib.Salsa.fs:line 23
at Tests.LanguageService.AutoCompletion.UsingMSBuild.BestMatch.Bug4320a() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 4774

4) Failed : Tests.LanguageService.AutoCompletion.UsingMSBuild.HandleInlineComments1
Couldn't find 'Int32' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@59-2.Invoke(CompletionItem[] completions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 60
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoCompleteUsingExtraRefs(FSharpList`1 refs, Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 50
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoComplete(Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 54
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@58-1.Invoke(FSharpList`1 code, String marker, FSharpList`1 should, FSharpList`1 shouldnot) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 58
at Tests.LanguageService.AutoCompletion.UsingMSBuild.HandleInlineComments1() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 3625

5) Failed : Tests.LanguageService.AutoCompletion.UsingMSBuild.Identifier.NonDottedNamespace.Bug1347

at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertCtrlSpaceCompletionContains@202.Invoke(CompletionItem[] completions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 207
at Tests.LanguageService.AutoCompletion.UsingMSBuild.AssertCtrlSpaceCompletion(FSharpList`1 fileContents, String marker, FSharpFunc`2 checkCompletion, FSharpOption`1 addtlRefAssy) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 215

6) Failed : Tests.LanguageService.AutoCompletion.UsingMSBuild.ImportStatment.System.ImportAsIdentifier
Couldn't find 'IO' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234

7) Failed : Tests.LanguageService.AutoCompletion.UsingMSBuild.LongIdent.PInvoke.AsReturnType
Couldn't find 'Boolean' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234

8) Failed : Tests.LanguageService.AutoCompletion.UsingMSBuild.Regression4702.SystemWord
Couldn't find 'Console' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234

9) Failed : Tests.LanguageService.AutoCompletion.UsingMSBuild.StandardTypes.Bug4403
Couldn't find 'int8' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@59-2.Invoke(CompletionItem[] completions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 60
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoCompleteUsingExtraRefs(FSharpList`1 refs, Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 50
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoComplete(Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 54
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@58-1.Invoke(FSharpList`1 code, String marker, FSharpList`1 should, FSharpList`1 shouldnot) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 58
at Tests.LanguageService.AutoCompletion.UsingMSBuild.StandardTypes.Bug4403() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 2146

10) Failed : Tests.LanguageService.AutoCompletion.UsingProjectSystem.Array.AfterOperator...Bug65732_A
Couldn't find 'Int32' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@59-2.Invoke(CompletionItem[] completions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 60
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoCompleteUsingExtraRefs(FSharpList`1 refs, Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 50
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoComplete(Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 54
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@58-1.Invoke(FSharpList`1 code, String marker, FSharpList`1 should, FSharpList`1 shouldnot) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 58
at Tests.LanguageService.AutoCompletion.UsingMSBuild.Array.AfterOperator...Bug65732_A() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 3110

11) Failed : Tests.LanguageService.AutoCompletion.UsingProjectSystem.BestMatch.Bug4320a
Expected:
Some ("GC", false, true)

but got:
Some ("", false, false).
at UnitTests.TestLib.Salsa.AssertEqual[a](a expected, a actual) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\TestLib.Salsa.fs:line 23
at Tests.LanguageService.AutoCompletion.UsingMSBuild.BestMatch.Bug4320a() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 4774

12) Failed : Tests.LanguageService.AutoCompletion.UsingProjectSystem.HandleInlineComments1
Couldn't find 'Int32' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@59-2.Invoke(CompletionItem[] completions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 60
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoCompleteUsingExtraRefs(FSharpList`1 refs, Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 50
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoComplete(Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 54
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@58-1.Invoke(FSharpList`1 code, String marker, FSharpList`1 should, FSharpList`1 shouldnot) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 58
at Tests.LanguageService.AutoCompletion.UsingMSBuild.HandleInlineComments1() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 3625

13) Failed : Tests.LanguageService.AutoCompletion.UsingProjectSystem.Identifier.NonDottedNamespace.Bug1347

at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertCtrlSpaceCompletionContains@202.Invoke(CompletionItem[] completions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 207
at Tests.LanguageService.AutoCompletion.UsingMSBuild.AssertCtrlSpaceCompletion(FSharpList`1 fileContents, String marker, FSharpFunc`2 checkCompletion, FSharpOption`1 addtlRefAssy) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 215

14) Failed : Tests.LanguageService.AutoCompletion.UsingProjectSystem.ImportStatment.System.ImportAsIdentifier
Couldn't find 'IO' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234

15) Failed : Tests.LanguageService.AutoCompletion.UsingProjectSystem.LongIdent.PInvoke.AsReturnType
Couldn't find 'Boolean' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234

16) Failed : Tests.LanguageService.AutoCompletion.UsingProjectSystem.Regression4702.SystemWord
Couldn't find 'Console' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234

17) Failed : Tests.LanguageService.AutoCompletion.UsingProjectSystem.StandardTypes.Bug4403
Couldn't find 'int8' in completion list: [|"<Note>"|]
at Salsa.VsOpsUtils.AssertCompListContains$cont@216(String membername, CompletionItem[] completions, Unit unitVar) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 219
at Salsa.VsOpsUtils.AssertCompListContains(CompletionItem[] completions, String membername) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 216
at Salsa.VsOpsUtils.AssertCompListContainsAll(CompletionItem[] completions, FSharpList`1 expectedCompletions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\Salsa\SalsaUtils.fs:line 234
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@59-2.Invoke(CompletionItem[] completions) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 60
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoCompleteUsingExtraRefs(FSharpList`1 refs, Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 50
at Tests.LanguageService.AutoCompletion.UsingMSBuild.DoWithAutoComplete(Boolean coffeeBreak, SourceFileKind fileKind, BackgroundRequestReason reason, FSharpList`1 code, String marker, FSharpFunc`2 f) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 54
at <StartupCode$VisualFSharp-UnitTests>.$Tests.LanguageService.Completion.AssertAutoCompleteContains@58-1.Invoke(FSharpList`1 code, String marker, FSharpList`1 should, FSharpList`1 shouldnot) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 58
at Tests.LanguageService.AutoCompletion.UsingMSBuild.StandardTypes.Bug4403() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.Completion.fs:line 2146

18) Failed : Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.Class.Printing.CSharp.Classes.Only..Bug4592

at Tests.LanguageService.QuickInfo.UsingMSBuild.AssertMemberDataTipContainsInOrder(FSharpList`1 code, String marker, String completionName, FSharpList`1 rhsContainsOrder) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1709
at Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.Class.Printing.CSharp.Classes.Only..Bug4592() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 2101

19) Failed : Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.MemberDefinition.DocComments.Bug5856_12

at Tests.LanguageService.QuickInfo.UsingMSBuild.AssertMemberDataTipContainsInOrder(FSharpList`1 code, String marker, String completionName, FSharpList`1 rhsContainsOrder) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1709
at Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.MemberDefinition.DocComments.Bug5856_12() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1948

20) Failed : Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.MemberDefinition.DocComments.Bug5856_14

at Tests.LanguageService.QuickInfo.UsingMSBuild.AssertMemberDataTipContainsInOrder(FSharpList`1 code, String marker, String completionName, FSharpList`1 rhsContainsOrder) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1709
at Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.MemberDefinition.DocComments.Bug5856_14() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1996

21) Failed : Tests.LanguageService.QuickInfo.UsingProjectSystem.Regression.Class.Printing.CSharp.Classes.Only..Bug4592

at Tests.LanguageService.QuickInfo.UsingMSBuild.AssertMemberDataTipContainsInOrder(FSharpList`1 code, String marker, String completionName, FSharpList`1 rhsContainsOrder) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1709
at Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.Class.Printing.CSharp.Classes.Only..Bug4592() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 2101

22) Failed : Tests.LanguageService.QuickInfo.UsingProjectSystem.Regression.MemberDefinition.DocComments.Bug5856_12

at Tests.LanguageService.QuickInfo.UsingMSBuild.AssertMemberDataTipContainsInOrder(FSharpList`1 code, String marker, String completionName, FSharpList`1 rhsContainsOrder) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1709
at Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.MemberDefinition.DocComments.Bug5856_12() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1948

23) Failed : Tests.LanguageService.QuickInfo.UsingProjectSystem.Regression.MemberDefinition.DocComments.Bug5856_14

at Tests.LanguageService.QuickInfo.UsingMSBuild.AssertMemberDataTipContainsInOrder(FSharpList`1 code, String marker, String completionName, FSharpList`1 rhsContainsOrder) in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1709
at Tests.LanguageService.QuickInfo.UsingMSBuild.Regression.MemberDefinition.DocComments.Bug5856_14() in D:\j\w\release_ci_pa---3f142ccc\vsintegration\tests\unittests\LegacyLanguageService\Tests.LanguageService.QuickInfo.fs:line 1996

@dsyme
Copy link
Contributor Author

dsyme commented Jan 20, 2018

@KevinRansom @cartermp I won't be at a computer where I can properly look at those failures until Sunday evening GMT

@cartermp
Copy link
Contributor

No worries

@dsyme
Copy link
Contributor Author

dsyme commented Jan 22, 2018

@cartermp I think I've finally got this sorted. Tracking down the last couple of test failures now.

Copy link
Member

@KevinRansom KevinRansom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good ... a few cosmetic items, if you want to take care of them.


//let isUnseenByBeingTupleMethod () = isAnyTupleTy g typ

isUnseenByObsoleteAttrib () || isUnseenByHidingAttribute () //|| isUnseenByBeingTupleMethod ()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented out code.

@@ -1421,3 +1421,4 @@ notAFunctionButMaybeIndexer,"This expression is not a function and cannot be app
notAFunctionButMaybeDeclaration,"This value is not a function and cannot be applied. Did you forget to terminate a declaration?"
3218,ArgumentsInSigAndImplMismatch,"The argument names in the signature '%s' and implementation '%s' do not match. The argument name from the signature file will be used. This may cause problems when debugging or profiling."
3219,pickleUnexpectedNonZero,"An error occurred while reading the F# metadata of assembly '%s'. A reserved construct was utilized. You may need to upgrade your F# compiler or use an earlier version of the assembly that doesn't make use of a specific construct."
3220,tcTupleMemberNotNormallyUsed,"This method or property is not normally used from F# code, use an explicit tuple pattern for deconstruction instead"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"This method or property is not normally used from F# code, use an explicit tuple pattern for deconstruction."

delete instead add full stop.

//| CanImplementSpecificInterfaceSlot parentTy -> isInterfaceTy g dispatchSlot.EnclosingType && typeEquiv g parentTy dispatchSlot.EnclosingType
| CanImplementAnyInterfaceSlot -> isInterfaceTy g dispatchSlot.EnclosingType)
| CanImplementAnyClassHierarchySlot -> not (isInterfaceTy g dispatchSlot.LogicalEnclosingType)
//| CanImplementSpecificInterfaceSlot parentTy -> isInterfaceTy g dispatchSlot.LogicalEnclosingType && typeEquiv g parentTy dispatchSlot.LogicalEnclosingType
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more commented out code

@@ -845,7 +866,7 @@ type ILMethInfo =
/// Describes an F# use of a method
[<NoComparison; NoEquality>]
type MethInfo =
/// FSMeth(tcGlobals, declaringType, valRef, extensionMethodPriority).
/// FSMeth(tcGlobals, enclosingType, valRef, extensionMethodPriority).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented out code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is part of the comment showing the use of the union case

/// Get the enclosing ("parent"/"declaring") type of the field.
member x.LogicalEnclosingType = match x with ILEventInfo(tinfo,_) -> tinfo.ToType

// Note: events are always assocaited with nominal types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: assocaited

@dsyme
Copy link
Contributor Author

dsyme commented Jan 22, 2018

Yay, it is green at last

However, this PR ended up quite big because it broke an invariant that previously held in the compiler.

As mentioned above in this PR we continue to normalize all tuple types to use the TType_tuple node in the TAST TType type. Prior to this change only TType_app nodes supported members of their own. This means that as of this PR we could no longer assume that the "declaring type" (of a member) or "apparent enclosing type" (of an extension member) was a TType_app. This caused various uses of tcrefOfAppTy to fail in quite a number of different places.

To get a grip on this, the PR carefully

  1. applies consistent naming and shape for DeclaringType and ApparentEnclosingType
  2. applies shape and naming to the infos.fs members concerned with DeclaringType and ApparentEnclosingType
  3. removes many uses of tcrefOfAppTy which were assuming the invariant above.

@cartermp @KevinRansom I assume the PR is much too big to apply in escrow. There's not a lot I can do about this. I knew that making F# tuples support the same metadata members as are declared in .NET tuple type metadata would be an invasive change, which is why I held off making this change at all. Now it is done, I'll leave it up to you about when to integrate it, thanks

@KevinRansom
Copy link
Member

@dsyme, targeting for 15.6 preview 4.

@cartermp
Copy link
Contributor

Just to confirm what was communicated via email:

  1. We'll manually validate scenarios when this is inserted into a testable build for Preview 4
  2. Although the code churn is big, it's still entirely within the F# component itself and is unlikely to affect other components, thus the risk is really just that we make the existing regression with tuples worse than it already is. Having tested this PR out myself, I find this unlikely.

@KevinRansom
Copy link
Member

@dotnet-bot test Ubuntu14.04 Release_fcs Build please

@KevinRansom KevinRansom merged commit 52391ed into dotnet:master Jan 22, 2018
@auduchinok auduchinok mentioned this pull request Jan 24, 2018
@cartermp cartermp moved this from To do to Done in [15.6] Compiler Jan 30, 2018
@psantoro
Copy link

psantoro commented Feb 2, 2018

I’ve actually been working on another totally unrelated, nasty breaking change (haf/DotNetZip.Semverd#113), so I’m very late to this conversation. However, I’d like to offer some advice in the hopes that it may be useful to the F# community in the future. I apologize if what I’m going to say has been said before, but I haven’t had time to read every comment in detail.

Breaking changes are never fun, but given that we are all human, they will continue to happen. I’ve probably been developing software longer than most of you have been alive. I’ve been both the receiver and creator of breaking changes – and I have respect for both sides. (Nowadays, most of the breaking changes that I create are on purpose and are related to refactoring.) I do think it’s important to have a proper balance between how the two sides are ultimately asked to handle these unforeseen events.

Whenever possible, breaking changes at the F# application source level should be avoided. However, I don’t believe that we should be opposed to all breaking changes – as none of us is so smart that we will always get things right the first time. Sometimes breaking changes at the F# source level may be necessary/wise in order to maintain/enforce/enhance language idioms/consistency and allow the F# compiler writers more latitude to do their work (e.g. more easily support new features, ease ongoing maintenance efforts, take advantage of performance opportunities, etc.).

In this particular breaking change, it’s totally understandable why this issue was missed before it was released. I betting that most F# developers use the F# syntax for constructing/deconstructing tuples and let the compiler deal with the underlying representation – in lieu of using Tuple or ItemN.

If the work to develop the new warning message for this issue was only a small part of the patch, perhaps it might have been better to have made this an error message instead (this was briefly discussed). Here’s my reasoning behind this:

  • as the issue appears to be specific to F# application source code only, some F# applications (probably a small percentage) would need to be modified to use F# tuple construction/deconstruction syntax (unfortunate, but not a disaster in my opinion)

  • the F# language team could choose to only support the F# idiom for tuple construction/deconstruction, in order to maintain language consistency/idioms and lessen ongoing compiler maintenance (yes, this might surprise/upset some OOP folks – let them learn the F# syntax)

Other communities, that I’m familiar with, handle breaking changes by doing the following:

  • if possible and the effort is not too great, provide a temporary workaround
  • include a deprecation warning stating that in some future release this syntax/API will no longer be supported
  • at the previously telegraphed release, change the deprecation warning to an error message and remove the temporary workaround

This allows the language maintainers to throw away cruft at predetermined times and gives application developers time to make any necessary changes. Perhaps this is an approach the F# community can use in the future, too?

Peter Santoro

@abelbraaksma
Copy link
Contributor

@psantoro, this was not an intentional breaking change. It was a regression bug that caused code to break. This PR fixes the regression. Wrt to the rest you're saying: breaking changes are very rarely accepted, if ever. When they are, they are communicated and discussed thoroughly with the users and a graceful path to the new situation is offered. I think that's in line with what you're suggesting.

If you do find that you're still having issues, you can of course write a bug report or a feature request.

@gusty
Copy link
Contributor

gusty commented Jan 20, 2020

@dsyme for tuples greater than 7, is there a way (strong type way) to 'force' a conversion to F# syntactic tuple?

I know that if at compile-time the expected type is known I can "retype" the .net tuple (using inlined IL) and it will work, but what if I only know that the type is a tuple of n elements and not the individual type of each element?

nosami pushed a commit to xamarin/visualfsharp that referenced this pull request Jan 26, 2022
* make tuples support Item* with warning

* add deactivated tests for struct tuple

* proper return types for Rest, prototype ctors

* fix SRTP

* fix tests

* fix tests

* add more protection

* improve code for decompiling types

* fix unit tests

* don't rebuild

* make infos systematic to reduce use of tcrefOfAppTy

* update test cases

* fix build

* update test cases

* bump FCS version consistently

* use consistent names

* code review
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

7 participants