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

Unable to compile conditional access expression in context of expression-bodied void method/lambda expression #11

Closed
controlflow opened this issue Jan 15, 2015 · 6 comments
Assignees
Labels
Area-Compilers Bug Language-C# Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented Verified
Milestone

Comments

@controlflow
Copy link

Related commit: dd8f041

?. invocation in context of a statement-expression should be allowed even if result type of the invocation cannot be made nullable.

I'm expecting it also to work with void methods in expression-bodied form, as well as void lambda expressions:

using System;

class C<T> {
    void F1(C<T> c) {
        c?.M(); // compiles fine

        // error CS0023: Operator '?' cannot be applied to operand of type 'T'
        Action a = () => c?.M();
    }

    // error CS0023: Operator '?' cannot be applied to operand of type 'T'
    void F2(C<T> c) => c?.M();


    T M() => default(T);
}
@controlflow
Copy link
Author

And from language design perspective: this whole idea of allowing more conditional access expressions to compile in context where value is ignored (is it defined by spec?) feels awkward and ad-hoc. What kind of scenarios this solves?

As a tooling developer, I have to disable 'introduce variable' refactoring for such expressions and this may be confusing for developers. Also I have no idea of what semantic model should tell about type of such c?.M() expression. Is it T (I think so) or void?

Maybe (I'm not sure), it's better to allow such calls of methods with non-liftable return types in any context, but simply lift unconstrained T type (and other non-liftable types) into void type?

@jaredpar jaredpar added this to the 1.1 milestone Jan 15, 2015
@theoy theoy assigned theoy and unassigned theoy Jan 16, 2015
@theoy
Copy link
Contributor

theoy commented Jan 16, 2015

I think the goal is more to allow it in contexts where the normal '.' dispatching is allowed - for example method calls that return a value are allowed as statement expressions.

The user intention is to find places where a NullReferenceException would normally occur and instead allow for a graceful null-propagation (or at least a lack of throwing) to occur.

@theoy
Copy link
Contributor

theoy commented Jan 16, 2015

By the way, great catch! I'm thrilled for all of the valuable points that you've been able to help us find as we are trying to land Roslyn v1. 😄

@controlflow
Copy link
Author

😉

@VSadov
Copy link
Member

VSadov commented Jan 16, 2015

It is allowed to have void returning conditional accesses in statement expression scenarios. Scenarios like resource?.Dispose() or event1?.Invoke() seem very useful.
Since we agree on allowing void in such scenarios, it makes sense to remove nullability requirement as well.

@theoy theoy modified the milestones: 1.0-rc2, 1.1 Feb 4, 2015
@theoy theoy changed the title Conditional access expression in context of expression-bodied void method/lambda expression Unable to compile conditional access expression in context of expression-bodied void method/lambda expression Feb 12, 2015
@AlekseyTs
Copy link
Contributor

I believe this issue has been addressed already. @VladimirReshetnikov, please verify and close if appropriate.

@gafter gafter added 4 - In Review A fix for the issue is submitted for review. and removed 2 - Ready labels Feb 22, 2015
@gafter gafter assigned gafter and unassigned VladimirReshetnikov Feb 23, 2015
@gafter gafter added Verified Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented and removed 4 - In Review A fix for the issue is submitted for review. labels Feb 23, 2015
@gafter gafter closed this as completed Feb 23, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Bug Language-C# Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented Verified
Projects
None yet
Development

No branches or pull requests

7 participants