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

Extended property patterns: IOperation and Symbols #53082

Merged

Conversation

alrz
Copy link
Contributor

@alrz alrz commented May 1, 2021

Test plan: #52468

  • Split BoundPropertySubpattern and BoundPositionalSubpattern
  • Introduce BoundPropertySubpatternMember to keep track of symbol/syntax mapping
  • Adjust IOperation (There's an open issue on operation tree representation of unwrapped nullables: Test plan for "extended property patterns" #52468 (comment))

@alrz alrz marked this pull request as ready for review May 3, 2021 16:45
@alrz alrz requested review from a team as code owners May 3, 2021 16:45
@jinujoseph jinujoseph added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label May 4, 2021
Comment on lines +500 to +563
if (this is { Prop.Prop: null })
{
this.Prop.ToString();
this.Prop.Prop.ToString(); // 1
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have no idea why this works already. There's no changes to account for nested members in this PR.

@alrz alrz requested review from jcouv and 333fred May 5, 2021 15:19
@alrz alrz removed request for a team May 5, 2021 16:11
@jcouv jcouv self-assigned this May 5, 2021
@jcouv jcouv added this to the C# 10 milestone May 5, 2021
Symbol last = subpattern.Symbols.Last();
// PROTOTYPE(extended-property-patterns) For a chain of members, the input type is no longer `inputType`
if (last.ContainingType.Equals(inputType, TypeCompareKind.AllIgnoreOptions))
if (subpattern.Member is { Symbol: Symbol symbol, Receiver: var receiver } member &&
Copy link
Member

@jcouv jcouv May 5, 2021

Choose a reason for hiding this comment

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

var

I didn't understand how the nullability analysis of the chain of accesses falls out from this implementation. I would have expected we'd analyze the nullability of the receiver first (the chain of receivers is not null) then learn that the current member/symbol is also not null.

nit: please use an explicit type here for readability #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Me neither. I'll have to investigate to see where the state is produced.

nit: please use an explicit type here for readability

We don't want the null check here. Filed a suggestion to address this: dotnet/csharplang#4724

Copy link
Member

Choose a reason for hiding this comment

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

Let's keep a PROTOTYPE marker here then. Thanks

}

[Fact]
public void ExtendedPropertyPatterns_Nullability()
Copy link
Member

@jcouv jcouv May 5, 2021

Choose a reason for hiding this comment

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

Could you add a simliar test with two types (each having a property/field)?

class C1 { C2? Prop1 { get; } }
class C2 { object? Prop2 { get; } }
``` #Closed

Console.WriteLine(p is { X.Y: {}, Y.X: {} });
}
}
class P
Copy link
Member

@jcouv jcouv May 5, 2021

Choose a reason for hiding this comment

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

It would be better to split this type into two (one containing X and one for Y) #Closed

AssertEmpty(model.GetSymbolInfo(subpatterns[0]));
AssertEmpty(model.GetSymbolInfo(subpatterns[0].ExpressionColon));
var xy = subpatterns[0].ExpressionColon.Expression;
var xySymbol = model.GetSymbolInfo(xy);
Copy link
Member

@jcouv jcouv May 5, 2021

Choose a reason for hiding this comment

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

Please also verify GetTypeInfo on those various pieces of syntax. #Closed

Diagnostic(ErrorCode.ERR_PropertyLacksGet, "action").WithArguments("action").WithLocation(8, 38)
};

VerifyOperationTreeAndDiagnosticsForTest<IsPatternExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics, parseOptions: TestOptions.RegularWithExtendedPropertyPatterns);
Copy link
Member

@jcouv jcouv May 5, 2021

Choose a reason for hiding this comment

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

Let's also verify the control flow graph with VerifyFlowGraphAndDiagnosticsForTest (for a positive case above). PROTOTYPE for follow-up is okay too. #Closed

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.

Done with review pass (iteration 12)

@@ -2029,6 +2033,10 @@ private static bool IsUserDefinedTrueOrFalse(BoundUnaryOperator @operator)
pattern.InputType, pattern.NarrowedType, nullability: default, convertedNullability: default,
Compilation.Conversions.ClassifyBuiltInConversion(pattern.InputType, pattern.NarrowedType, ref discardedUseSiteInfo));
}
if (lowestBoundNode is BoundPropertySubpatternMember member)
{
return new CSharpTypeInfo(member.Type, member.Type, nullability: default, convertedNullability: default, Conversion.Identity);
Copy link
Contributor Author

@alrz alrz May 6, 2021

Choose a reason for hiding this comment

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

I guess we want to return the unwrapped type + nullable conversion if this is a nested member? If so, we probably need to capture this info from binding. Also I'm not sure what is the expected NullabilityInfo here.

Copy link
Contributor Author

@alrz alrz May 6, 2021

Choose a reason for hiding this comment

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

Sounds like GetTypeInfo on subpattern name wasn't handled before or am I missing something?

if (last.ContainingType.Equals(inputType, TypeCompareKind.AllIgnoreOptions))
// PROTOTYPE(extended-property-patterns): Investigate if we need to visit nested members; is there a test gap?
if (subpattern.Member is { Symbol: Symbol symbol, Receiver: var receiver } member &&
symbol.ContainingType.Equals(receiver is not null ? receiver.Type : inputType, TypeCompareKind.AllIgnoreOptions))
Copy link
Member

@cston cston May 6, 2021

Choose a reason for hiding this comment

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

symbol.ContainingType.Equals(receiver is not null ? receiver.Type : inputType, TypeCompareKind.AllIgnoreOptions)

It's not clear to me why we compare the containing type to the receiver or input type using Equals(). Could the receiver or input type be a derived type?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The logic is unchanged from before but it sounds like the check is actually redundant. Remove?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do recall one or two tests failing without the check but I couldn't find it now. I'll remove it to see if CI fails.

Copy link
Member

Choose a reason for hiding this comment

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

If no tests fail without this check, is there a simple test with a derived type that we could add that would demonstrate the difference in behavior?

Copy link
Contributor Author

@alrz alrz May 6, 2021

Choose a reason for hiding this comment

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

I think this is the one: RecursivePatternNullInferenceWithDowncast_01 but now it's green.

Copy link
Contributor Author

@alrz alrz May 6, 2021

Choose a reason for hiding this comment

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

I actually went back to main and rechecked. No test fails. I might be missing something though.

property.GetPublicSymbol(), ImmutableArray<IArgumentOperation>.Empty, createReceiver(), _semanticModel, nameSyntax, property.Type.GetPublicSymbol(),
isImplicit: isImplicit);
return new PropertyReferenceOperation(property.GetPublicSymbol(), ImmutableArray<IArgumentOperation>.Empty,
createReceiver(), _semanticModel, member.Syntax, property.Type.StrippedType().GetPublicSymbol(), isImplicit: 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.

I don't think we should use StrippedType here. Maybe only if this is a nested member?

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.

LGTM Thanks (iteration 17). Will merge as soon as CI is green.

@jcouv jcouv enabled auto-merge (squash) May 7, 2021 19:24
@alrz
Copy link
Contributor Author

alrz commented May 7, 2021

I think both #53082 (comment) and #53082 (comment) need to be revised based on the expected behavior.

@jcouv jcouv disabled auto-merge May 8, 2021 07:05
@jcouv
Copy link
Member

jcouv commented May 8, 2021

I think both #53082 (comment) and #53082 (comment) need to be revised based on the expected behavior.

Would you mind capturing those follow-up comments with PROTOTYPE markers? I'm afraid we'll lose or forget them otherwise.

@alrz
Copy link
Contributor Author

alrz commented May 9, 2021

@RikkiGibson Integration legs are consistently failing on x86. Is this normal?

@jcouv
Copy link
Member

jcouv commented May 10, 2021

azp /run

@jcouv
Copy link
Member

jcouv commented May 10, 2021

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@jcouv jcouv enabled auto-merge (squash) May 10, 2021 20:24
@jcouv jcouv merged commit 2a82d69 into dotnet:features/extended-property-patterns May 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Community The pull request was submitted by a contributor who is not a Microsoft employee.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants