dotnet / dotnet/vblang

Target type context does not flow into result operands of conditional 'If' expressions

Open
#97 8 comments 0 reactions 0 assignees View on GitHub
Scenario
Dominant language
No language data
Stars
328
Forks
71
PR merge metrics
No merged PRs in 30d

Description

Visual Basic has several "typeless" expressions whose final value depends on target type information:

* The `Nothing` literal

``` VB.NET
Dim ns As String = Nothing
Dim i As Integer = Nothing
Dim ni As Integer? = Nothing
```

* `AddressOf` expressions

``` VB.NET
Dim s As Action(Of String) = AddressOf Console.WriteLine
```
`AddressOf` expressions don't have a type. Target-typing allows overload resolution to pick the correct method and instantiate a delegate referring to that method.

* Lambda expressions

``` VB.NET
Dim f1 = Function() True
Dim f2 As Func(Of Boolean) = Function() True
Dim f3 As Expression(Of Func(Of Boolean)) = Function() True
```

In the code above the same text, `Function() True`, may have an anonymous delegate type ``, named delegate type `Func(Of Boolean)`, or may produce an expression tree based on target type context.

* Array literals

``` VB.NET
Dim arr As Byte() = {1, 2, 3, 4}
```

The code above does not first produce an Integer array then convert it to a Byte array; that's impossible. Instead the array literal is always realized as a Byte array and its elements are each converted to Byte.

``` VB.NET
Dim value = $"Cost {value:C02}"
Dim value
```

* Interpolated string expressions

Because the conditional 'If' operator doesn't propagate target type context into its operands these expressions may be reclassified incorrectly producing programs with subtle bugs or which fail at run-time.

This makes the simple refactoring of an `If` block into an `If` expression dangerous. Additionally, each time we consider adding more target-typed expressions we compound this issue.

Examples of programs failing to compile or compiling with surprising behavior.

``` VB.NET
' Actually assigns False, not null.
Dim trueOrNull As Boolean? = If(False, True, Nothing)

' Fails to infer common type; doesn't compile with Option Strict On.
Dim control As Control = If(isReadOnly, New Label, New TextBox)
control.Text = ...

' Fails to infer common type; doesn't compile at all.
Dim a As Action(Of String) = If(True, AddressOf Debug.WriteLine, AddressOf Trace.WriteLine)
```

Similar "common-type" examples can be made whenever both operands are typeless.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.