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

Move IDS_FeatureRefLocalsReturns out of the parser #65710

Merged
merged 140 commits into from
Dec 3, 2022
Merged
Show file tree
Hide file tree
Changes from 139 commits
Commits
Show all changes
140 commits
Select commit Hold shift + click to select a range
cf0ff82
Move IDS_FeatureFileScopedNamespace check out of the parser
CyrusNajmabadi Nov 14, 2022
2e14765
Move IDS_FeatureExternAlias check out of the parser
CyrusNajmabadi Nov 14, 2022
c77a8df
Move IDS_FeatureUsingStatic check out of the parser
CyrusNajmabadi Nov 14, 2022
9214e58
Move IDS_FeatureGlobalUsing check out of the parser
CyrusNajmabadi Nov 14, 2022
57f76d1
Move IDS_FeatureNamedArgument check out of the parser
CyrusNajmabadi Nov 14, 2022
95190e5
Move IDS_FeatureAsync check out of the parser
CyrusNajmabadi Nov 14, 2022
b9d15d0
Move IDS_FeatureStaticClasses check out of the parser
CyrusNajmabadi Nov 14, 2022
6ebd08e
Move IDS_FeatureReadOnlyStructs check out of the parser
CyrusNajmabadi Nov 14, 2022
5465712
Move IDS_FeatureDefaultTypeParameterConstraint check out of the parser
CyrusNajmabadi Nov 14, 2022
8b23be3
Move IDS_FeatureExpressionBodiedIndexer check out of the parser
CyrusNajmabadi Nov 14, 2022
3f573a6
Move IDS_FeatureExpressionBodiedProperty check out of the parser
CyrusNajmabadi Nov 14, 2022
d6fcf67
Move IDS_FeatureAutoPropertyInitializer check out of the parser
CyrusNajmabadi Nov 14, 2022
7ddd2b3
Move IDS_FeatureOptionalParameter check out of the parser
CyrusNajmabadi Nov 14, 2022
8efce60
Move IDS_FeatureFixedBuffer check out of the parser
CyrusNajmabadi Nov 14, 2022
13db8fc
Move IDS_FeatureGenerics check out of the parser
CyrusNajmabadi Nov 14, 2022
e643c1c
Move IDS_FeatureStaticLocalFunctions check out of the parser
CyrusNajmabadi Nov 14, 2022
7470991
Move IDS_FeatureExternLocalFunctions check out of the parser
CyrusNajmabadi Nov 14, 2022
541e46c
Move IDS_FeatureLocalFunctions check out of the parser
CyrusNajmabadi Nov 14, 2022
f47b8bf
Move IDS_FeatureThrowExpression check out of the parser
CyrusNajmabadi Nov 14, 2022
ce53f95
Move IDS_FeaturePatternMatching check out of the parser
CyrusNajmabadi Nov 14, 2022
e952cca
Move IDS_FeatureNullPropagatingOperator check out of the parser
CyrusNajmabadi Nov 14, 2022
f463c06
Move IDS_FeatureNullableReferenceTypes check out of the parser
CyrusNajmabadi Nov 14, 2022
dce4b3f
Move IDS_FeatureDefault check out of the parser
CyrusNajmabadi Nov 14, 2022
fb50dd4
Move IDS_FeatureDefaultLiteral check out of the parser
CyrusNajmabadi Nov 14, 2022
8914d2e
Move IDS_FeatureAnonymousTypes check out of the parser
CyrusNajmabadi Nov 14, 2022
de1d7c8
Move IDS_FeatureImplicitObjectCreation check out of the parser
CyrusNajmabadi Nov 14, 2022
f5a8263
Move IDS_FeatureRecords check out of the parser
CyrusNajmabadi Nov 14, 2022
94702e9
Move IDS_FeatureDictionaryInitializer check out of the parser
CyrusNajmabadi Nov 14, 2022
c538085
Move IDS_FeatureImplicitArray check out of the parser
CyrusNajmabadi Nov 14, 2022
43bcf61
Move IDS_FeatureStackAllocInitializer check out of the parser
CyrusNajmabadi Nov 14, 2022
550828e
Move IDS_FeatureAnonDelegates check out of the parser
CyrusNajmabadi Nov 14, 2022
0aa23d6
Move IDS_FeatureAsync and IDS_FeatureStaticAnonymousFunction check ou…
CyrusNajmabadi Nov 14, 2022
499c7e4
Move IDS_FeatureLambda check out of the parser
CyrusNajmabadi Nov 14, 2022
f7bfbfc
Move IDS_FeatureQueryExpression check out of the parser
CyrusNajmabadi Nov 14, 2022
33185d6
Move IDS_FeatureRefStructs check out of the parser
CyrusNajmabadi Nov 14, 2022
01b8d6f
Move IDS_FeatureRecursivePatterns check out of the parser
CyrusNajmabadi Nov 14, 2022
ece1590
Move IDS_FeatureExtendedPropertyPatterns check out of the parser
CyrusNajmabadi Nov 14, 2022
66350f1
Move IDS_FeatureParenthesizedPattern check out of the parser
CyrusNajmabadi Nov 14, 2022
8b7ae44
Move IDS_FeatureTypePattern check out of the parser
CyrusNajmabadi Nov 14, 2022
ac9f64b
Move IDS_FeatureRecursivePatterns check out of the parser
CyrusNajmabadi Nov 14, 2022
0dd7d23
Move IDS_FeatureOrPattern check out of the parser
CyrusNajmabadi Nov 14, 2022
158eea0
Move IDS_FeatureAndPattern check out of the parser
CyrusNajmabadi Nov 14, 2022
ff4d75b
Move IDS_FeatureRelationalPattern IDS_FeatureNotPattern and check out…
CyrusNajmabadi Nov 14, 2022
5d316ad
Move IDS_FeatureTypeVariance check out of the parser
CyrusNajmabadi Nov 14, 2022
4badea9
Remove version check when we're always going to report a parse error …
CyrusNajmabadi Nov 14, 2022
22de551
Move IDS_FeatureFunctionPointers check out of the parser
CyrusNajmabadi Nov 14, 2022
b378a29
Move IDS_FeatureExceptionFilter check out of the parser
CyrusNajmabadi Nov 14, 2022
eb6a35b
Move IDS_FeatureRefForEach check out of the parser
CyrusNajmabadi Nov 14, 2022
ad7c696
Move IDS_FeatureIterators check out of the parser
CyrusNajmabadi Nov 14, 2022
d2a504a
Move IDS_FeatureAsync check out of the parser
CyrusNajmabadi Nov 14, 2022
7d471b1
Move IDS_FeatureCoalesceAssignmentExpression check out of the parser
CyrusNajmabadi Nov 14, 2022
0654a20
Move IDS_FeaturePatternMatching check out of the parser
CyrusNajmabadi Nov 14, 2022
7279de9
Move IDS_FeatureReadOnlyReferences check out of the parser
CyrusNajmabadi Nov 14, 2022
0648826
Move IDS_FeatureOutVar check out of the parser
CyrusNajmabadi Nov 14, 2022
9705697
Move IDS_FeatureRefReassignment check out of the parser
CyrusNajmabadi Nov 14, 2022
662f71a
Remove blank lines
CyrusNajmabadi Nov 15, 2022
d18cdbf
UPdate comments
CyrusNajmabadi Nov 15, 2022
49b6f6f
Renames
CyrusNajmabadi Nov 15, 2022
03a2623
Merge remote-tracking branch 'upstream/main' into langVersionChecks
CyrusNajmabadi Nov 16, 2022
eaf7e8d
Merge remote-tracking branch 'upstream/main' into langVersionChecks
CyrusNajmabadi Nov 17, 2022
3e5826b
Fix errant semicolon
CyrusNajmabadi Nov 17, 2022
a9f8451
Fix indentation
CyrusNajmabadi Nov 17, 2022
2fabba1
Simplify code
CyrusNajmabadi Nov 17, 2022
0263fee
Fixup change
CyrusNajmabadi Nov 17, 2022
0b663a1
Merge remote-tracking branch 'upstream/main' into langVersionChecks
CyrusNajmabadi Nov 18, 2022
29ae829
Fix
CyrusNajmabadi Nov 18, 2022
f1592dc
Move IDS_TopLevelStatements check out of the parser
CyrusNajmabadi Nov 18, 2022
e7a983f
Move IDS_FeatureModuleAttrLoc check out of the parser
CyrusNajmabadi Nov 18, 2022
9442adc
Move IDS_FeatureRecordXXX check out of the parser
CyrusNajmabadi Nov 18, 2022
4ebf39b
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont
CyrusNajmabadi Nov 18, 2022
ce9db2d
Move IDS_FeatureExpressionBodiedXXX check out of the parser
CyrusNajmabadi Nov 18, 2022
7900e3a
Move IDS_FeatureStaticAbstractMembersInInterfaces check out of the pa…
CyrusNajmabadi Nov 18, 2022
a27cb92
Move IDS_FeaturePropertyAccessorMods check out of the parser
CyrusNajmabadi Nov 18, 2022
4670c78
Move IDS_FeatureXXXInitializer check out of the parser
CyrusNajmabadi Nov 18, 2022
636d6fd
Simplify
CyrusNajmabadi Nov 18, 2022
e4d9d3d
Simplify
CyrusNajmabadi Nov 18, 2022
7437a9e
Simplify
CyrusNajmabadi Nov 18, 2022
dd1a55d
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont
CyrusNajmabadi Nov 18, 2022
933db45
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont
CyrusNajmabadi Nov 19, 2022
c0a1ad7
Lint
CyrusNajmabadi Nov 19, 2022
8b66b65
Lint
CyrusNajmabadi Nov 19, 2022
5470687
Fix test
CyrusNajmabadi Nov 19, 2022
f14cf24
FIx tests
CyrusNajmabadi Nov 19, 2022
18dabb5
Fix record check
CyrusNajmabadi Nov 19, 2022
b910b94
Unify checks
CyrusNajmabadi Nov 19, 2022
a666886
Fix speculation
CyrusNajmabadi Nov 19, 2022
a23e082
Restore
CyrusNajmabadi Nov 19, 2022
c56a716
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont
CyrusNajmabadi Nov 21, 2022
e008fc3
Fix tests
CyrusNajmabadi Nov 21, 2022
c4a42bc
Remove errant code
CyrusNajmabadi Nov 21, 2022
966a269
Move modifiers check
CyrusNajmabadi Nov 21, 2022
1877677
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont2
CyrusNajmabadi Nov 22, 2022
a671a90
Move IDS_FeaturePartialTypes check out of parser
CyrusNajmabadi Nov 22, 2022
165f266
Remove unnecessary check
CyrusNajmabadi Nov 22, 2022
eafb6d0
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont2
CyrusNajmabadi Nov 23, 2022
5e7505d
Move IDS_FeatureReadOnlyMembers checks out of parser
CyrusNajmabadi Nov 23, 2022
71ef8d2
Move IDS_FeatureGlobalNamespace checks out of parser
CyrusNajmabadi Nov 23, 2022
74d11be
Move IDS_FeatureNullable checks out of parser
CyrusNajmabadi Nov 23, 2022
d84dd99
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont2
CyrusNajmabadi Nov 29, 2022
376773e
lint
CyrusNajmabadi Nov 30, 2022
fedc280
lint
CyrusNajmabadi Nov 30, 2022
40f1612
invert
CyrusNajmabadi Nov 30, 2022
641fe28
Move IDS_FeatureRefLocalsReturns out of the parser
CyrusNajmabadi Nov 30, 2022
c7e8640
Move IDS_FeatureRefLocalsReturns out of the parser
CyrusNajmabadi Nov 30, 2022
ef2d6e7
Move IDS_FeatureTuples out of the parser
CyrusNajmabadi Nov 30, 2022
aa09a1b
Move IDS_FeatureTuples out of the parser
CyrusNajmabadi Nov 30, 2022
2362fa8
Move IDS_FeatureTuples out of the parser
CyrusNajmabadi Nov 30, 2022
e179d0d
Fix test
CyrusNajmabadi Nov 30, 2022
3813462
Merge branch 'langVersionChecksCont2' into langVersionChecksCont3
CyrusNajmabadi Nov 30, 2022
f52d0ce
Update comments
CyrusNajmabadi Nov 30, 2022
dd34e81
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont2
CyrusNajmabadi Dec 1, 2022
899c48f
Simplify
CyrusNajmabadi Dec 1, 2022
2b2ba15
Simplify
CyrusNajmabadi Dec 1, 2022
85dc588
Clarify code
CyrusNajmabadi Dec 1, 2022
b075975
Merge branch 'langVersionChecksCont2' into langVersionChecksCont3
CyrusNajmabadi Dec 1, 2022
9bd07ce
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont3
CyrusNajmabadi Dec 1, 2022
1a1d171
Formatting
CyrusNajmabadi Dec 1, 2022
94ddd02
Move one more case
CyrusNajmabadi Dec 1, 2022
ce4eb33
Move one more case
CyrusNajmabadi Dec 1, 2022
40c7415
Fix test
CyrusNajmabadi Dec 1, 2022
5fb16ee
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont3
CyrusNajmabadi Dec 1, 2022
fdf71e5
Update test
CyrusNajmabadi Dec 1, 2022
049b812
Work on ref-types
CyrusNajmabadi Dec 1, 2022
6b43371
Remove from parser
CyrusNajmabadi Dec 1, 2022
cca1319
Merge remote-tracking branch 'upstream/main' into langVersionChecksCont4
CyrusNajmabadi Dec 1, 2022
4d05f1d
Restore
CyrusNajmabadi Dec 2, 2022
788ecf7
Simplify
CyrusNajmabadi Dec 2, 2022
e99a3d6
Add comment
CyrusNajmabadi Dec 2, 2022
5677838
Update src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs
CyrusNajmabadi Dec 2, 2022
d42839c
Remove redundant lang-version check
CyrusNajmabadi Dec 2, 2022
21fcaca
Merge branch 'langVersionChecksCont4' of https://github.com/CyrusNajm…
CyrusNajmabadi Dec 2, 2022
693ecd0
Update src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberField…
CyrusNajmabadi Dec 2, 2022
2f9e73d
Update src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
CyrusNajmabadi Dec 2, 2022
099a8fa
Rename for clarity
CyrusNajmabadi Dec 2, 2022
0d2a458
PR feedback
CyrusNajmabadi Dec 2, 2022
c145880
PR feedback
CyrusNajmabadi Dec 2, 2022
532b2d0
Copy paste error
CyrusNajmabadi Dec 2, 2022
bfaf1d5
PR feedback
CyrusNajmabadi Dec 2, 2022
bc203e0
No extension
CyrusNajmabadi Dec 2, 2022
ba7ca5f
PR feedback
CyrusNajmabadi Dec 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ private DeconstructionVariable BindDeconstructionVariables(
bool isVar;
bool isConst = false;
AliasSymbol alias;
var declType = BindVariableTypeWithAnnotations(component.Designation, diagnostics, component.Type.SkipScoped(out _).SkipRef(out _), ref isConst, out isVar, out alias);
var declType = BindVariableTypeWithAnnotations(component.Designation, diagnostics, component.Type.SkipScoped(out _).SkipRef(), ref isConst, out isVar, out alias);
Copy link
Member Author

Choose a reason for hiding this comment

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

here's teh general intuition (which i commented in the PR). If a feature is ignoring 'ref', then it's a place where 'ref' is not legal (otherwise they wouldn't be able to ignore it). And those places already have a syntactic check to report that. i.e. we already hve code on line 841 in this file to error for that case. As such, we don't need to report a diagnostic about needing a particular lang version to use 'ref'.

However, if hte feature does care about ref-type and actually uses that ref-kind, then it is only legal to do that in a version of c# that supports ref. So if it uses the actual RefKind, it needs to pass in diagnostics to get the right version checks.

Copy link
Contributor

Choose a reason for hiding this comment

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

It seemed like in some places, we are skipping ref, but some other check is deciding conditionally whether ref is OK in that position. For example, in BindVariableTypeWithAnnotations. It looks like some of the time you deliberately called the overload to pass diagnostics: null, like in SourceLocalSymbol.

It looks like the SkipRef overload that takes a diagnostic bag is specifically checking for the ref locals and returns feature. I am wondering if the name of this method should be changed, e.g. SkipRef() with no parameters sticks around, and SkipRef(DiagnosticBag, out RefKind gets renamed to something like SkipRefInLocalOrReturn(DiagnosticBag, out RefKind). Then it might be slightly easier to tell at a glance why it's expected to pass a diagnostic bag or not.

Debug.Assert(isVar == !declType.HasType);
if (component.Designation.Kind() == SyntaxKind.ParenthesizedVariableDesignation)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ private BoundExpression BindDeclarationExpressionAsError(DeclarationExpressionSy
bool isVar;
bool isConst = false;
AliasSymbol alias;
var declType = BindVariableTypeWithAnnotations(node.Designation, diagnostics, node.Type.SkipScoped(out _).SkipRef(out _), ref isConst, out isVar, out alias);
var declType = BindVariableTypeWithAnnotations(node.Designation, diagnostics, node.Type.SkipScoped(out _).SkipRef(), ref isConst, out isVar, out alias);
Error(diagnostics, ErrorCode.ERR_DeclarationExpressionNotPermitted, node);
return BindDeclarationVariablesForErrorRecovery(declType, node.Designation, node, diagnostics);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ static void checkAttributes(AnonymousFunctionExpressionSyntax syntax, SyntaxList
MessageID.IDS_FeatureLambdaReturnType.CheckFeatureAvailability(diagnostics, syntax);

Debug.Assert(syntax is not ScopedTypeSyntax);
syntax = syntax.SkipScoped(out _).SkipRef(out RefKind refKind);
if ((syntax as IdentifierNameSyntax)?.Identifier.ContextualKind() == SyntaxKind.VarKeyword)
syntax = syntax.SkipScoped(out _).SkipRefInLocalOrReturn(diagnostics, out RefKind refKind);
if (syntax is IdentifierNameSyntax { Identifier.RawContextualKind: (int)SyntaxKind.VarKeyword })
{
diagnostics.Add(ErrorCode.ERR_LambdaExplicitReturnTypeVar, syntax.Location);
}
Expand Down
9 changes: 6 additions & 3 deletions src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,10 @@ private BoundStatement BindDeclarationStatementParts(LocalDeclarationStatementSy
typeSyntax = scopedType.Type;
}

typeSyntax = typeSyntax.SkipRef(out _);
// Slightly odd, but we unwrap ref here (and report a lang-version diagnostic when appropriate). Ideally,
// this would be in the constructor of SourceLocalSymbol, but it lacks a diagnostics bag passed to it to add
// this diagnostic.
typeSyntax = typeSyntax.SkipRefInLocalOrReturn(diagnostics, out _);

bool isVar;
AliasSymbol alias;
Expand Down Expand Up @@ -795,7 +798,7 @@ declarationNode is VariableDesignationSyntax ||
// we want to treat the declaration as an explicitly typed declaration.

Debug.Assert(typeSyntax is not ScopedTypeSyntax);
TypeWithAnnotations declType = BindTypeOrVarKeyword(typeSyntax.SkipScoped(out _).SkipRef(out _), diagnostics, out isVar, out alias);
TypeWithAnnotations declType = BindTypeOrVarKeyword(typeSyntax.SkipScoped(out _).SkipRef(), diagnostics, out isVar, out alias);
Debug.Assert(declType.HasType || isVar);

if (isVar)
Expand Down Expand Up @@ -2726,7 +2729,7 @@ internal BoundStatement BindForOrUsingOrFixedDeclarations(VariableDeclarationSyn
// Fixed and using variables are not allowed to be ref-like, but regular variables are
if (localKind == LocalDeclarationKind.RegularVariable)
{
typeSyntax = typeSyntax.SkipRef(out _);
typeSyntax = typeSyntax.SkipRef();
}

AliasSymbol alias;
Expand Down
4 changes: 4 additions & 0 deletions src/Compilers/CSharp/Portable/Binder/ForLoopBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ private BoundForStatement BindForParts(ForStatementSyntax node, Binder originalB
var type = _syntax.Declaration.Type.SkipScoped(out _);

if (type is RefTypeSyntax)
{
// Checking for 'ref for' (7.3) automatically checks for 'ref' (7.0), so no need for an explicit
// check feature as well here.
MessageID.IDS_FeatureRefFor.CheckFeatureAvailability(diagnostics, type);
}

initializer = originalBinder.BindForOrUsingOrFixedDeclarations(node.Declaration, LocalDeclarationKind.RegularVariable, diagnostics, out _);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ internal BoundExpression SetInferredTypeWithAnnotations(TypeWithAnnotations type
if (localSymbol.Scope == DeclarationScope.ValueScoped && !type.Type.IsErrorTypeOrRefLikeType())
{
diagnosticsOpt.Add(ErrorCode.ERR_ScopedRefAndRefStructOnly,
(typeOrDesignationSyntax is TypeSyntax typeSyntax ? typeSyntax.SkipScoped(out _).SkipRef(out _) : typeOrDesignationSyntax).Location);
(typeOrDesignationSyntax is TypeSyntax typeSyntax ? typeSyntax.SkipScoped(out _).SkipRef() : typeOrDesignationSyntax).Location);
}
}
}
Expand Down
17 changes: 4 additions & 13 deletions src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7165,19 +7165,10 @@ private TypeSyntax ParseType(ParseTypeMode mode = ParseTypeMode.Normal)
{
if (this.CurrentToken.Kind == SyntaxKind.RefKeyword)
{
var refKeyword = this.EatToken();
refKeyword = this.CheckFeatureAvailability(refKeyword, MessageID.IDS_FeatureRefLocalsReturns);

SyntaxToken readonlyKeyword = null;
if (this.CurrentToken.Kind == SyntaxKind.ReadOnlyKeyword)
{
readonlyKeyword = this.EatToken();
readonlyKeyword = this.CheckFeatureAvailability(readonlyKeyword, MessageID.IDS_FeatureReadOnlyReferences);
}

var type = ParseTypeCore(ParseTypeMode.AfterRef);

return _syntaxFactory.RefType(refKeyword, readonlyKeyword, type);
return _syntaxFactory.RefType(
this.EatToken(),
this.CurrentToken.Kind == SyntaxKind.ReadOnlyKeyword ? this.EatToken() : null,
ParseTypeCore(ParseTypeMode.AfterRef));
}

return ParseTypeCore(mode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal static GlobalExpressionVariable Create(
Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax);

var syntaxReference = syntax.GetReference();
return (typeSyntax == null || typeSyntax.SkipScoped(out _).SkipRef(out _).IsVar)
return (typeSyntax == null || typeSyntax.SkipScoped(out _).SkipRef().IsVar)
Copy link
Member Author

Choose a reason for hiding this comment

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

sidenote: we have a ton of code taht does this unwrapping to check .IsVar. We may want to consider having that property just do this unwinding anyways.

? new InferrableGlobalExpressionVariable(containingType, modifiers, typeSyntax, name, syntaxReference, location, containingFieldOpt, nodeToBind)
: new GlobalExpressionVariable(containingType, modifiers, typeSyntax, name, syntaxReference, location);
}
Expand Down Expand Up @@ -88,7 +88,7 @@ internal override TypeWithAnnotations GetFieldType(ConsList<FieldSymbol> fieldsB

if (typeSyntax != null)
{
type = binder.BindTypeOrVarKeyword(typeSyntax.SkipScoped(out _).SkipRef(out _), diagnostics, out isVar);
type = binder.BindTypeOrVarKeyword(typeSyntax.SkipScoped(out _).SkipRef(), diagnostics, out isVar);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,7 @@ public LocalFunctionSymbol(
ReportAttributesDisallowed(param.AttributeLists, _declarationDiagnostics);
}

if (syntax.ReturnType.Kind() == SyntaxKind.RefType)
{
var returnType = (RefTypeSyntax)syntax.ReturnType;
if (returnType.ReadOnlyKeyword.Kind() == SyntaxKind.ReadOnlyKeyword)
{
_refKind = RefKind.RefReadOnly;
}
else
{
_refKind = RefKind.Ref;
}
}
else
{
_refKind = RefKind.None;
}

syntax.ReturnType.SkipRefInLocalOrReturn(_declarationDiagnostics, out _refKind);
_binder = binder;
}

Expand Down Expand Up @@ -235,7 +219,7 @@ internal void ComputeReturnType()
var diagnostics = BindingDiagnosticBag.GetInstance(_declarationDiagnostics);
TypeSyntax returnTypeSyntax = Syntax.ReturnType;
Debug.Assert(returnTypeSyntax is not ScopedTypeSyntax);
TypeWithAnnotations returnType = WithTypeParametersBinder.BindType(returnTypeSyntax.SkipScoped(out _).SkipRef(out _), diagnostics);
TypeWithAnnotations returnType = WithTypeParametersBinder.BindType(returnTypeSyntax.SkipScoped(out _).SkipRef(), diagnostics);

var compilation = DeclaringCompilation;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal static void AddDelegateMembers(
TypeSyntax returnTypeSyntax = syntax.ReturnType;
Debug.Assert(returnTypeSyntax is not ScopedTypeSyntax);

returnTypeSyntax = returnTypeSyntax.SkipScoped(out _).SkipRef(out RefKind refKind);
returnTypeSyntax = returnTypeSyntax.SkipScoped(out _).SkipRefInLocalOrReturn(diagnostics, out RefKind refKind);
var returnType = binder.BindType(returnTypeSyntax, diagnostics);

// reuse types to avoid reporting duplicate errors if missing:
Expand Down
29 changes: 12 additions & 17 deletions src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,23 +71,18 @@ private SourceLocalSymbol(
typeSyntax = typeSyntax.SkipScoped(out isScoped);
isScoped = isScoped && allowScoped;

if (allowRefKind && typeSyntax is RefTypeSyntax refTypeSyntax)
{
this._refKind = refTypeSyntax.ReadOnlyKeyword.Kind() == SyntaxKind.ReadOnlyKeyword ?
RefKind.RefReadOnly :
RefKind.Ref;
this._scope = isScoped ? DeclarationScope.RefScoped : DeclarationScope.Unscoped;
}
else
{
this._refKind = RefKind.None;
this._scope = isScoped ? DeclarationScope.ValueScoped : DeclarationScope.Unscoped;
}
// Diagnostics for ref-locals is reported by caller in BindDeclarationStatementParts.
if (allowRefKind)
typeSyntax.SkipRefInLocalOrReturn(diagnostics: null, out _refKind);

_scope = _refKind != RefKind.None
? isScoped ? DeclarationScope.RefScoped : DeclarationScope.Unscoped
: isScoped ? DeclarationScope.ValueScoped : DeclarationScope.Unscoped;

this._declarationKind = declarationKind;

// create this eagerly as it will always be needed for the EnsureSingleDefinition
_locations = ImmutableArray.Create<Location>(identifierToken.GetLocation());
_locations = ImmutableArray.Create(identifierToken.GetLocation());

_refEscapeScope = this._refKind == RefKind.None ?
scopeBinder.LocalScopeDepth :
Expand Down Expand Up @@ -208,7 +203,7 @@ public static SourceLocalSymbol MakeDeconstructionLocal(
Debug.Assert(closestTypeSyntax != null);
Debug.Assert(nodeBinder != null);

return closestTypeSyntax.SkipScoped(out _).SkipRef(out _).IsVar
return closestTypeSyntax.SkipScoped(out _).SkipRef().IsVar
? new DeconstructionLocalSymbol(containingSymbol, scopeBinder, nodeBinder, closestTypeSyntax, identifierToken, kind, deconstruction)
: new SourceLocalSymbol(containingSymbol, scopeBinder, allowRefKind: false, allowScoped: true, closestTypeSyntax, identifierToken, kind);
}
Expand Down Expand Up @@ -239,7 +234,7 @@ internal static LocalSymbol MakeLocalSymbolWithEnclosingContext(
Contains(nodeToBind.Ancestors().OfType<StatementSyntax>().First().Kind()) ||
nodeToBind is ExpressionSyntax);
Debug.Assert(!(nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm) || nodeBinder is SwitchExpressionArmBinder);
return typeSyntax?.SkipScoped(out _).SkipRef(out _).IsVar != false && kind != LocalDeclarationKind.DeclarationExpressionVariable
return typeSyntax?.SkipScoped(out _).SkipRef().IsVar != false && kind != LocalDeclarationKind.DeclarationExpressionVariable
? new LocalSymbolWithEnclosingContext(containingSymbol, scopeBinder, nodeBinder, typeSyntax, identifierToken, kind, nodeToBind, forbiddenZone)
: new SourceLocalSymbol(containingSymbol, scopeBinder, allowRefKind: false, allowScoped: true, typeSyntax, identifierToken, kind);
}
Expand Down Expand Up @@ -383,7 +378,7 @@ public bool IsVar
return true;
}

TypeSyntax typeSyntax = _typeSyntax.SkipScoped(out _).SkipRef(out _);
TypeSyntax typeSyntax = _typeSyntax.SkipScoped(out _).SkipRef();

if (typeSyntax.IsVar)
{
Expand Down Expand Up @@ -419,7 +414,7 @@ private TypeWithAnnotations GetTypeSymbol()
}
else
{
declType = typeBinder.BindTypeOrVarKeyword(_typeSyntax.SkipScoped(out _).SkipRef(out _), diagnostics, out isVar);
declType = typeBinder.BindTypeOrVarKeyword(_typeSyntax.SkipScoped(out _).SkipRef(), diagnostics, out isVar);
}

if (isVar)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4477,7 +4477,8 @@ private void AddNonTypeMembers(
{
var fieldSyntax = (FieldDeclarationSyntax)m;

_ = fieldSyntax.Declaration.Type.SkipScoped(out _).SkipRef(out RefKind refKind);
// Lang version check for ref-fields is done inside SourceMemberFieldSymbol;
_ = fieldSyntax.Declaration.Type.SkipScoped(out _).SkipRefInField(out var refKind);

if (IsImplicitClass && reportMisplacedGlobalCode)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,31 +489,26 @@ private TypeAndRefKind GetTypeAndRefKind(ConsList<FieldSymbol> fieldsBeingBound)
binder = binder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);
if (!ContainingType.IsScriptClass)
{
var typeOnly = typeSyntax.SkipScoped(out _).SkipRef(out refKind);
var typeOnly = typeSyntax.SkipScoped(out _).SkipRefInField(out refKind);
Debug.Assert(refKind is RefKind.None or RefKind.Ref or RefKind.RefReadOnly);
type = binder.BindType(typeOnly, diagnosticsForFirstDeclarator);
if (refKind != RefKind.None)
{
MessageID.IDS_FeatureRefFields.CheckFeatureAvailability(diagnostics, compilation, typeSyntax.SkipScoped(out _).Location);
if (!compilation.Assembly.RuntimeSupportsByRefFields)
{
diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportRefFields, ErrorLocation);
}

if (!containingType.IsRefLikeType)
{
diagnostics.Add(ErrorCode.ERR_RefFieldInNonRefStruct, ErrorLocation);
}

if (type.Type?.IsRefLikeType == true)
{
diagnostics.Add(ErrorCode.ERR_RefFieldCannotReferToRefStruct, typeSyntax.SkipScoped(out _).Location);
}
}
}
else
{
bool isVar;
type = binder.BindTypeOrVarKeyword(typeSyntax.SkipScoped(out _).SkipRef(out RefKind refKindToAssert), diagnostics, out isVar);
type = binder.BindTypeOrVarKeyword(typeSyntax.SkipScoped(out _).SkipRefInField(out RefKind refKindToAssert), diagnostics, out isVar);
Debug.Assert(refKindToAssert == RefKind.None); // Otherwise we might need to report an error
Debug.Assert(type.HasType || isVar);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private SourceOrdinaryMethodSymbol(
bool hasBody = hasBlockBody || _isExpressionBodied;
_hasAnyBody = hasBody;
Debug.Assert(syntax.ReturnType is not ScopedTypeSyntax);
_refKind = syntax.ReturnType.SkipScoped(out _).GetRefKind();
_refKind = syntax.ReturnType.SkipScoped(out _).GetRefKindInLocalOrReturn(diagnostics);

CheckForBlockAndExpressionBody(
syntax.Body, syntax.ExpressionBody, syntax, diagnostics);
Expand Down Expand Up @@ -144,7 +144,7 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray<ParameterSymb
var returnTypeSyntax = syntax.ReturnType;
Debug.Assert(returnTypeSyntax is not ScopedTypeSyntax);

returnTypeSyntax = returnTypeSyntax.SkipScoped(out _).SkipRef(out RefKind refKind);
returnTypeSyntax = returnTypeSyntax.SkipScoped(out _).SkipRef();
TypeWithAnnotations returnType = signatureBinder.BindType(returnTypeSyntax, diagnostics);

// span-like types are returnable in general
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private SourcePropertySymbol(
isAutoProperty: isAutoProperty,
isExpressionBodied: isExpressionBodied,
isInitOnly: isInitOnly,
syntax.Type.SkipScoped(out _).GetRefKind(),
syntax.Type.SkipScoped(out _).GetRefKindInLocalOrReturn(diagnostics),
memberName,
syntax.AttributeLists,
location,
Expand Down Expand Up @@ -448,7 +448,7 @@ private TypeWithAnnotations ComputeType(Binder binder, SyntaxNode syntax, Bindin
var typeSyntax = GetTypeSyntax(syntax);
Debug.Assert(typeSyntax is not ScopedTypeSyntax);

typeSyntax = typeSyntax.SkipScoped(out _).SkipRef(out _);
typeSyntax = typeSyntax.SkipScoped(out _).SkipRef();
var type = binder.BindType(typeSyntax, diagnostics);
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = binder.GetNewCompoundUseSiteInfo(diagnostics);

Expand Down Expand Up @@ -560,7 +560,7 @@ protected override bool HasPointerTypeSyntactically
{
var typeSyntax = GetTypeSyntax(CSharpSyntaxNode);
Debug.Assert(typeSyntax is not ScopedTypeSyntax);
typeSyntax = typeSyntax.SkipScoped(out _).SkipRef(out _);
typeSyntax = typeSyntax.SkipScoped(out _).SkipRef();
return typeSyntax.Kind() switch { SyntaxKind.PointerType => true, SyntaxKind.FunctionPointerType => true, _ => false };
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ internal static bool IsIdentifierVarOrPredefinedType(this Syntax.InternalSyntax.
internal static bool IsDeclarationExpressionType(SyntaxNode node, [NotNullWhen(true)] out DeclarationExpressionSyntax? parent)
{
parent = node.ModifyingScopedOrRefTypeOrSelf().Parent as DeclarationExpressionSyntax;
return node == parent?.Type.SkipScoped(out _).SkipRef(out _);
return node == parent?.Type.SkipScoped(out _).SkipRef();
}

/// <summary>
Expand Down
Loading