Skip to content

Do not offer to remove cast if it will cause the compiler to warn about it.#43492

Merged
CyrusNajmabadi merged 3 commits intodotnet:masterfrom
CyrusNajmabadi:orWideningCastCheck
Apr 22, 2020
Merged

Do not offer to remove cast if it will cause the compiler to warn about it.#43492
CyrusNajmabadi merged 3 commits intodotnet:masterfrom
CyrusNajmabadi:orWideningCastCheck

Conversation

@CyrusNajmabadi
Copy link
Contributor

Fixes #40414

@CyrusNajmabadi CyrusNajmabadi requested review from a team as code owners April 19, 2020 22:18
default:
return false;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

same impl as VB. moved to common location so C#/VB compilers can reference this, as can IDE.

/// <summary>
/// Returns true if the conversion is an nullable conversion.
/// </summary>
public bool IsNullable => (_conversionKind & ConversionKind.IsNullable) == ConversionKind.IsNullable;
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 seems safe to add to the common layer. Both VB and C# have htis concept and it seems identical from my reading. Namely:

c#:

Implicit nullable conversions

Predefined implicit conversions that operate on non-nullable value types can also be used with nullable forms of those types. For each of the predefined implicit identity and numeric conversions that convert from a non-nullable value type S to a non-nullable value type T, the following implicit nullable conversions exist:

  • An implicit conversion from S? to T?.
  • An implicit conversion from S to T?.

Evaluation of an implicit nullable conversion based on an underlying conversion from S to T proceeds as follows:

  • If the nullable conversion is from S? to T?:

    • If the source value is null (HasValue property is false), the result is the null value of type T?.
    • Otherwise, the conversion is evaluated as an unwrapping from S? to S, followed by the underlying conversion from S to T, followed by a wrapping (Nullable types) from T to T?.
  • If the nullable conversion is from S to T?, the conversion is evaluated as the underlying conversion from S to T followed by a wrapping from T to T?.

(and the corresponding explicit version of this)

VB:

A value type T can convert to and from the nullable version of the type, T?. The conversion from T? to T throws a System.InvalidOperationException exception if the value being converted is Nothing. Also, T? has a conversion to a type S if T has an intrinsic conversion to S. And if S is a value type, then the following intrinsic conversions exist between T? and S?:

  • A conversion of the same classification (narrowing or widening) from T? to S?.
  • A conversion of the same classification (narrowing or widening) from T to S?.
  • A narrowing conversion from S? to T.

Case Else
Return False
End Select
End Function
Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed in favor of the identical common version.

@CyrusNajmabadi
Copy link
Contributor Author

@dotnet/roslyn-compiler @jcouv @333fred could i get eyes here? Thanks!

Microsoft.CodeAnalysis.InitializationContext
Microsoft.CodeAnalysis.InitializationContext.CancellationToken.get -> System.Threading.CancellationToken
Microsoft.CodeAnalysis.InitializationContext.RegisterForSyntaxNotifications(Microsoft.CodeAnalysis.SyntaxReceiverCreator receiverCreator) -> void
Microsoft.CodeAnalysis.Operations.CommonConversion.IsNullable.get -> bool
Copy link
Member

Choose a reason for hiding this comment

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

Tagging @jaredpar @gafter @333fred as FYI for public API change

/// <summary>
/// Checks if a type is considered a "built-in integral" by CLR.
/// </summary>
public static bool IsIntegralType(this SpecialType specialType)
Copy link
Member

Choose a reason for hiding this comment

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

IsIntegralType [](start = 27, length = 14)

Please add a compiler test that will fail once this change is merged with the native ints feature. That way we'll be reminded/forced to add logic here.

Copy link
Member

Choose a reason for hiding this comment

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

Hum, I got confused. Native ints have been merged already.
Tagging @cston to confirm whether this method should handle them.


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

Copy link
Contributor

Choose a reason for hiding this comment

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

I reviewed this method before merging the native integers feature, and didn't find a caller that might have a native integer type.


In reply to: 412468506 [](ancestors = 412468506,412454952)

<ItemGroup Condition="'$(DefaultLanguageSourceExtension)' != '' AND '$(BuildingInsideVisualStudio)' != 'true'">
<ExpectedCompile Include="$(MSBuildThisFileDirectory)**\*$(DefaultLanguageSourceExtension)" />
</ItemGroup>
<ItemGroup>
Copy link
Member

Choose a reason for hiding this comment

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

What does this do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

basically, it gives us a folder in the UI where this linked file goes. it seems needed because we have our own file called SpecialTypeExtensions, and we want to link in yours.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Compiler change LGTM Thanks (iteration 3)

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

Compiler changes LGTM (commit 3)

@CyrusNajmabadi
Copy link
Contributor Author

Thanks all!

@CyrusNajmabadi CyrusNajmabadi merged commit 8f4fdad into dotnet:master Apr 22, 2020
@ghost ghost added this to the Next milestone Apr 22, 2020
@CyrusNajmabadi CyrusNajmabadi deleted the orWideningCastCheck branch April 22, 2020 04:28

private static bool CastRemovalWouldCauseSignExtensionWarning(ExpressionSyntax expression, SemanticModel semanticModel, CancellationToken cancellationToken)
{
// Logic copied from DiagnosticsPass_Warnings.CheckForBitwiseOrSignExtend. Including comments.
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible to move this logic to a shared helper class in a separate file in compiler layer, so it can be linked into this project instead of cloned? I am concerned this would diverge pretty soon and introduce bugs.

Copy link
Contributor

Choose a reason for hiding this comment

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

I understand this has lot of customer logic specific to the analyzer, but it would be good if at least the core logic that can possibly be shared is shared. Please let me know if you have already done so for everything possible, in which case it is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. Unfortunately, the compiler logic is all built on compiler internals (i.e. bound nodes).
  2. i did have to tweak some things. for example, our function says: would this be an issue if the cast was removed. the compiler version obviously is written analyzing the actual expression witht the cast.

I am concerned this would diverge pretty soon and introduce bugs.

So i looked, and this hasn't changed in the compiler layer since we went open source. it's effectively a very very old holdover from the native compiler. So i'm not really concerned about that.

Please let me know if you have already done so for everything possible, in which case it is fine.

I tried to share as much as i could. all the helper extensions are shared. but the core logic that does this specific check is still a copy :-/

@sharwell sharwell modified the milestones: Next, temp, 16.7.P1 Apr 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid IDE0004 diagnostic

6 participants