-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Diagnose precedence inversion in a warning wave #46239
Changes from all commits
5c46c10
9ffb6b1
6f36cc0
a8a2b80
b112997
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10037,24 +10037,22 @@ private ExpressionSyntax ParseExpressionContinued(ExpressionSyntax leftOperand, | |
// We'll "take" this operator, as precedence is tentatively OK. | ||
var opToken = this.EatContextualToken(tk); | ||
|
||
if (leftOperand.Kind == SyntaxKind.IsPatternExpression || IsStrict) | ||
{ | ||
var leftPrecedence = GetPrecedence(leftOperand.Kind); | ||
if (newPrecedence > leftPrecedence) | ||
{ | ||
// Normally, a left operand with a looser precedence will consume all right operands that | ||
// have a tighter precedence. For example, in the expression `a + b * c`, the `* c` part | ||
// will be consumed as part of the right operand of the addition. However, there are a | ||
// few circumstances in which a tighter precedence is not consumed: that occurs when the | ||
// left hand operator does not have an expression as its right operand. This occurs for | ||
// the is-type operator and the is-pattern operator. Source text such as | ||
// `a is {} + b` should produce a syntax error, as parsing the `+` with an `is` | ||
// expression as its left operand would be a precedence inversion. Similarly, it occurs | ||
// with an anonymous method expression or a lambda expression with a block body. No | ||
// further parsing will find a way to fix things up, so we accept the operator but issue | ||
// an error. | ||
opToken = this.AddError(opToken, ErrorCode.ERR_UnexpectedToken, opToken.Text); | ||
} | ||
var leftPrecedence = GetPrecedence(leftOperand.Kind); | ||
if (newPrecedence > leftPrecedence) | ||
{ | ||
// Normally, a left operand with a looser precedence will consume all right operands that | ||
// have a tighter precedence. For example, in the expression `a + b * c`, the `* c` part | ||
// will be consumed as part of the right operand of the addition. However, there are a | ||
// few circumstances in which a tighter precedence is not consumed: that occurs when the | ||
// left hand operator does not have an expression as its right operand. This occurs for | ||
// the is-type operator and the is-pattern operator. Source text such as | ||
// `a is {} + b` should produce a syntax error, as parsing the `+` with an `is` | ||
// expression as its left operand would be a precedence inversion. Similarly, it occurs | ||
// with an anonymous method expression or a lambda expression with a block body. No | ||
// further parsing will find a way to fix things up, so we accept the operator but issue | ||
// a diagnostic. | ||
ErrorCode errorCode = leftOperand.Kind == SyntaxKind.IsPatternExpression ? ErrorCode.ERR_UnexpectedToken : ErrorCode.WRN_PrecedenceInversion; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Aren't we reporting an error in the non-pattern case now, where previously there was only an error if using "/strict"? #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, it is a warning In reply to: 463304547 [](ancestors = 463304547) |
||
opToken = this.AddError(opToken, errorCode, opToken.Text); | ||
} | ||
|
||
if (doubleOp) | ||
|
@@ -12446,9 +12444,9 @@ private QueryExpressionSyntax ParseQueryExpression(Precedence precedence) | |
this.EnterQuery(); | ||
var fc = this.ParseFromClause(); | ||
fc = CheckFeatureAvailability(fc, MessageID.IDS_FeatureQueryExpression); | ||
if (precedence > Precedence.Assignment && IsStrict) | ||
if (precedence > Precedence.Assignment) | ||
{ | ||
fc = this.AddError(fc, ErrorCode.ERR_InvalidExprTerm, SyntaxFacts.GetText(SyntaxKind.FromKeyword)); | ||
fc = this.AddError(fc, ErrorCode.WRN_PrecedenceInversion, SyntaxFacts.GetText(SyntaxKind.FromKeyword)); | ||
} | ||
|
||
var body = this.ParseQueryBody(); | ||
|
@@ -12695,8 +12693,6 @@ private QueryContinuationSyntax ParseQueryContinuation() | |
return _syntaxFactory.QueryContinuation(@into, name, body); | ||
} | ||
|
||
private bool IsStrict => this.Options.Features.ContainsKey("strict"); | ||
|
||
[Obsolete("Use IsIncrementalAndFactoryContextMatches")] | ||
private new bool IsIncremental | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a warning so it seems confusing that the message is "Operator cannot be used here due to precedence." We're allowing the operator so presumably it can be used. Should the message be more specific? Perhaps "Operator cannot be used here with the usual precedence." #ByDesign
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would "usual" add any clarity? We're accepting the operator because we're not paying any attention to precedence at all.
In reply to: 463301820 [](ancestors = 463301820)