Roslyn: Aspnetcore allowing void -> object casting

Created on 9 Apr 2019  路  10Comments  路  Source: dotnet/roslyn

Original Issue: https://github.com/aspnet/AspNetCore/issues/9197

Here's a simple standalone repro on .NET Core 2.2:

using Microsoft.AspNetCore.Mvc;
using System;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            new Test().FaultyMethod();
        }
    }

    public class Test
    {
        private void ReturnVoid() { }

        public ActionResult<object> FaultyMethod()
        {
            return ReturnVoid();
        }
    }
}


namespace Microsoft.AspNetCore.Mvc
{
    public sealed class ActionResult<TValue>
    {
        public ActionResult(TValue value)
        {
        }

        public static implicit operator ActionResult<TValue>(TValue value)
        {
            return new ActionResult<TValue>(value);
        }
    }
}

Run it and you get:

Unhandled Exception: System.InvalidProgramException: Common Language Runtime detected an invalid program.
at ConsoleApp2.Test.FaultyMethod()
at ConsoleApp2.Program.Main(String[] args) in C:\Users\elipton\source\repos\ConsoleApp2\ConsoleApp2\

Area-Compilers Bug

Most helpful comment

@wisepotato

Things like "can convert void to something" have a tendency to terrify compiler devs 馃槈

All 10 comments

@chsienki can you take a look at this?

Thanks for the fast response! :)

@wisepotato

Things like "can convert void to something" have a tendency to terrify compiler devs 馃槈

i was already afraid i'd have to get peverify into this, i'm 'happy' it scares you guys so much. Maybe it will prevent another person banging their head against a wall for 6-7 hours ...

@RikkiGibson in case he can get to this earlier.

More minimal repro:

class C<T>
{
    public static implicit operator C<T>(T t) => new C<T>();

    private static void M1() { }
    private static C<object> M2()
    {
        return M1();
    }
}

Seems to compile without errors when using C<object> or C<dynamic>, but not C<string> or C<int>.

I suspect this is because object appears to be a base class of System.Void and we improperly conclude that there is an implicit conversion. If my suspicion is right, ValueType would work too.

C<ValueType> M2() does work.

I have been looking around in here for a bit and it feels like I should be able to just find a spot to add a check to the effect of "no, conversions can't ever be to/from void". But I haven't figured it out yet.

Note: this is not a regression in C# 8.0, it's actually been around since at least 7.3

https://sharplab.io/#v2:D4AQDABCCMDcCwAoEBmKAmCBhCBvJEhUaIALBALIAUAlHgUQL5LOJIiZYA8AKgHxJ8iIsSjQAbBACWAWwAOAGykBjKQBcIAezkBTAE4BDNZr3ZefKjwhq6AXj4QAdjoDuZ/rQTCiDQnL1SAG5GOmKSZJTQtHgQrCL+QSFhZpoARgBWOspqDhTotL703oQAkCAA7JGehayMQA

It doesn't appear to be an error in VB. Perhaps I'll check the VB side as a starting point for how to solve this.

https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQBsQDdhJiAligHwEkwAHAewRigAIBlAT1jjAFgAoABQFdgVcAxjQDCKaLWEAKAPIAzGgBUAlBxpqaPPoPoALCAjgATGgHVchuADtclgOY1ppRBBiURChk8kwaAQVrKfhIy8sqq6gCQAEpwMNwIljQAcnAA7iIhiirsEQCilsaOzq4I4WplGrz8QnS8NACyktnqNPnGtcAcFZrVNABi3JYCMLjkifUATE1BGXIOwABWcMPZEdGx8eNNHHkF/YPDo5YcbSJiUFBAA

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MadsTorgersen picture MadsTorgersen  路  3Comments

nlwolf picture nlwolf  路  3Comments

codingonHP picture codingonHP  路  3Comments

glennblock picture glennblock  路  3Comments

DavidArno picture DavidArno  路  3Comments