Skip to content

Fix conversions on default literals#37596

Merged
jcouv merged 6 commits intodotnet:masterfrom
jcouv:default-conv
Aug 25, 2019
Merged

Fix conversions on default literals#37596
jcouv merged 6 commits intodotnet:masterfrom
jcouv:default-conv

Conversation

@jcouv
Copy link
Member

@jcouv jcouv commented Jul 30, 2019

This PR fixes two problems with default literal (from C# 7.1):

  • from a language perspective, we should not have re-used the "null literal conversion" (which is specifically a conversion from the null literal to a nullable value type), so I'm introducing a "default literal conversion" (conversion from the default literal to any type)
  • from a binding perspective, whenever a default was getting converted, we would incorrectly give it a natural type. This PR follows Neal's recent PRs by having a BoundDefaultExpression and a BoundConvertedDefaultExpression. This affects some scenarios
    1. default as TClass: becomes an error
    2. $"{default}": use object as target-type for expressions that don't have a natural type
    3. using (default) ...: becomes an error
      Also, during return type inference of lambdas, expressions are neither required to be target-typed or to have a natural type.
  • x == default will no longer bind as object equality.

But I reverted the part of this PR which affected public APIs (.Type in particular) because it had significant effect on the IDE (and therefore likely other consumers).

Fixes #31029
Fixes #18609
Fixes #35684 and #36492 (incorrectly emitting default as null, missing error, fix is a breaking change)
Fixes #30384

Relates to #22125

Opened issue tracking spec changes: #37821

Update: this breaking change was later adjusted in 16.4p2.

@jcouv jcouv added this to the 16.4 milestone Jul 30, 2019
@jcouv jcouv self-assigned this Jul 30, 2019
@jcouv jcouv force-pushed the default-conv branch 3 times, most recently from d039e5d to 28a2b18 Compare July 30, 2019 23:59
@jcouv jcouv force-pushed the default-conv branch 2 times, most recently from f1306f6 to 3176689 Compare August 8, 2019 00:51
@jcouv jcouv marked this pull request as ready for review August 8, 2019 00:53
@jcouv jcouv requested a review from a team as a code owner August 8, 2019 00:53
@jcouv jcouv added the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Aug 8, 2019
@jcouv
Copy link
Member Author

jcouv commented Aug 8, 2019

I'm investigating some test failures. Marking PR as "personal" for now. #Closed

@jcouv jcouv requested review from a team as code owners August 8, 2019 18:19
@jcouv jcouv force-pushed the default-conv branch 2 times, most recently from c9c8419 to b498181 Compare August 8, 2019 19:22
Copy link
Member Author

@jcouv jcouv Aug 8, 2019

Choose a reason for hiding this comment

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

@mavasani for review of the change to CustomDataFlowAnalysis.cs, DataFlowAnalyzer.cs and BasicBlockReachabilityDataFlowAnalyzer.cs.
For background, the comparison of default to an unconstrained type was improperly allowed (and interpreted as a comparison against null). With this PR, this becomes an error. #Resolved

Copy link
Member Author

@jcouv jcouv Aug 8, 2019

Choose a reason for hiding this comment

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

Hum, I just realized my fix is wrong :-( I'll take another look #Closed

Copy link
Contributor

@mavasani mavasani Aug 15, 2019

Choose a reason for hiding this comment

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

Yes, the intent is to allow the type parameter to be either a struct or class, and if it is default value then initialize it by invoking the GetEmptyAnalysisData API. What would be the recommended alternative here? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

@mavasani The way I fixed this is to require GetCurrentAnalysisData to return a value (possibly an empty one).


In reply to: 314401113 [](ancestors = 314401113)

Copy link
Contributor

@mavasani mavasani Aug 22, 2019

Choose a reason for hiding this comment

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

I see that you updated the comment on the abstract method GetCurrentAnalysisData, but did not change the override which may return null.

public override BasicBlockAnalysisData GetCurrentAnalysisData(BasicBlock basicBlock)
=> _analysisData.GetBlockAnalysisData(basicBlock);

Can you change the override to _analysisData.GetBlockAnalysisData(basicBlock) ?? GetEmptyAnalysisData();? #Resolved

@alrz
Copy link
Member

alrz commented Aug 9, 2019

after this goes in I'll try to sync target-typed-new branch with 16.4p1. let me know if there's other considerations. thanks. #Closed

@jcouv jcouv force-pushed the default-conv branch 2 times, most recently from 0f8b9da to 9980615 Compare August 9, 2019 16:48
@jcouv
Copy link
Member Author

jcouv commented Aug 9, 2019

@alrz Sounds good. Thanks! #Closed

Copy link
Member

@RikkiGibson RikkiGibson left a comment

Choose a reason for hiding this comment

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

I read the diff from starting my last review to now. LGTM.

@jcouv
Copy link
Member Author

jcouv commented Aug 20, 2019

I've rebased to resolve conflict.

@jcouv
Copy link
Member Author

jcouv commented Aug 21, 2019

@mavasani Did you have any other feedback? Thanks

Copy link
Contributor

Choose a reason for hiding this comment

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

Is the input source valid code now, hence CSharpReplaceDefaultLiteralCodeFixProvider is not triggered?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, case default: is still illegal. The behavior change here is a casualty of binding change: the compiler no longer tries to give default a type via conversion, so the IDE doesn't get a type to to drive the refactoring.

I took another look and managed to tweak that, which allowed to revert most of the IDE test changes. Thanks!

Copy link
Contributor

@mavasani mavasani left a comment

Choose a reason for hiding this comment

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

Thanks, IDE changes LGTM!

@jcouv jcouv changed the base branch from release/dev16.4-preview1 to master August 23, 2019 19:00
testData = new CompilationTestData();
context.CompileExpression("default", DkmEvaluationFlags.None, ImmutableArray<Alias>.Empty, out error, testData);
Assert.Equal(error, "error CS8716: No target type was found for the default literal.");
Assert.Equal(error, "error CS8716: No target type was found found for the default literal.");
Copy link
Member

Choose a reason for hiding this comment

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

This is really what the test wants? Strange..

@jcouv jcouv merged commit 1f867ac into dotnet:master Aug 25, 2019
@jcouv jcouv deleted the default-conv branch August 25, 2019 05:55
@jcouv jcouv modified the milestones: 16.4, 16.4.P1 Sep 6, 2019
billwert added a commit to billwert/performance that referenced this pull request Sep 9, 2019
dotnet/roslyn#37596 includes a breaking change in the 5.0 branch. This function is
intended to ensure reads happen from the array, so the test isn't strictly necessary.

Fixes dotnet#865
billwert added a commit to dotnet/performance that referenced this pull request Sep 9, 2019
dotnet/roslyn#37596 includes a breaking change in the 5.0 branch. This function is
intended to ensure reads happen from the array, so the test isn't strictly necessary.

Fixes #865
dlech added a commit to dlech/docfx that referenced this pull request Oct 12, 2019
Since updating to Microsoft.CodeAnalysis 3.3.1, the default keyword is
resolved to a vaule instead of the a default expression.

Probably comes from dotnet/roslyn#37596
superyyrrzz pushed a commit to dotnet/docfx that referenced this pull request Oct 12, 2019
* Update to Microsoft.CodeAnalysis 3.3.1

This updates to the latest Microsoft.CodeAnalysis packages for C#8
support.

Fixes the following error on a project that uses nullable reference
types:

Microsoft.DocAsCode.Exceptions.DocfxException: Unable to generate spec reference for !: ---> System.IO.InvalidDataException: Fail to parse id for symbol  in namespace .
  at Microsoft.DocAsCode.Metadata.ManagedReference.YamlModelGenerator.AddSpecReference (Microsoft.CodeAnalysis.ISymbol symbol, System.Collections.Generic.IReadOnlyList`1[T] typeGenericParameters, System.Collections.Generic.IReadOnlyList`1[T] methodGenericParameters, System.Collections.Generic.Dictionary`2[TKey,TValue] references, Microsoft.DocAsCode.Metadata.ManagedReference.SymbolVisitorAdapter adapter) [0x0005e] in <27b606b838ab45b788854d5e45efa610>:0
  at Microsoft.DocAsCode.Metadata.ManagedReference.SymbolVisitorAdapter.AddSpecReference (Microsoft.CodeAnalysis.ISymbol symbol, System.Collections.Generic.IReadOnlyList`1[T] typeGenericParameters, System.Collections.Generic.IReadOnlyList`1[T] methodGenericParameters) [0x00000] in <27b606b838ab45b788854d5e45efa610>:0

* Fix TODO for space after tuple

Since updating Microsoft.CodeAnalysis to 3.3.1, the automatic formatting
for tuples in C# has been fixed, so update tests accordingly.

dotnet/roslyn#29405

* Fix TestCSharpFeature_Default_7_1Class

Since updating to Microsoft.CodeAnalysis 3.3.1, the default keyword is
resolved to a vaule instead of the a default expression.

Probably comes from dotnet/roslyn#37596
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

5 participants