Check 'scoped' differences in overrides and interface implementations#61738
Check 'scoped' differences in overrides and interface implementations#61738cston merged 3 commits intodotnet:features/ref-fieldsfrom
Conversation
a955c94 to
6be761e
Compare
| <value>The 'scoped' modifier can be used for refs and ref struct values only.</value> | ||
| </data> | ||
| <data name="ERR_ScopedMismatchInParameterOfOverrideOrImplementation" xml:space="preserve"> | ||
| <value>The 'scoped' declaration of parameter '{0}' doesn't match overridden or implemented member.</value> |
| <data name="ERR_ScopedMismatchInParameterOfOverrideOrImplementation" xml:space="preserve"> | ||
| <value>The 'scoped' declaration of parameter '{0}' doesn't match overridden or implemented member.</value> | ||
| </data> | ||
| <data name="ERR_ScopedMismatchInParameterOfTargetDelegate" xml:space="preserve"> |
There was a problem hiding this comment.
I think we won't need to because scoped can't be used in a function pointer parameter. d'oy, we're talking about a scenario where a method group is converted to function pointer.
There was a problem hiding this comment.
There could still be a mismatch if the assigned method has a scoped parameter, although the resulting function pointer will be safe presumably because the method has a stronger contract than the function pointer.
static R F1(R x, scoped R y) => x;
delegate*<R, R, R> d1 = &F1;I'll add a test.
| case ConversionKind.MethodGroup: | ||
| if (node.Operand is BoundMethodGroup group) | ||
| { | ||
| checkValidScopedMethodConversion(group.Syntax, node.Conversion.Method, node.Type, invokedAsExtensionMethod: node.IsExtensionMethod, _diagnostics); |
There was a problem hiding this comment.
| } | ||
| static void Explicit() | ||
| { | ||
| var d1 = (D1)M2; |
| } | ||
|
|
||
| [Fact] | ||
| public void DelegateConversions_04() |
|
Done with review pass (commit 1) |
src/Compilers/CSharp/Test/Emit2/Attributes/AttributeTests_LifetimeAnnotation.cs
Show resolved
Hide resolved
| var boundLambda = unboundLambda.Bind((NamedTypeSymbol)destination, isExpressionTree: destination.IsGenericOrNonGenericExpressionType(out _)); | ||
| diagnostics.AddRange(boundLambda.Diagnostics); | ||
|
|
||
| bool hasErrors = CheckValidScopedMethodConversion(syntax, boundLambda.Symbol, destination, invokedAsExtensionMethod: false, diagnostics); |
There was a problem hiding this comment.
I wouldn't mark node with hasErrors flag because of this. The purpose of the flag is mostly to suppress cascading diagnostics for completely broken scenarios. When we cannot accurately figure out the result type, etc. It is not required to reflect if there are any errors associated with the node. In this case, it doesn't look like the new error can cause a cascading diagnostics. #Closed
| } | ||
| else if (targetType is FunctionPointerTypeSymbol functionPointerType) | ||
| { | ||
| delegateMethod = functionPointerType.Signature; |
| return true; | ||
| } | ||
|
|
||
| bool result = CheckValidScopedMethodConversion(syntax, selectedMethod, delegateOrFuncPtrType, isExtensionMethod, diagnostics); |
| hasErrors = !conversion.IsImplicit; | ||
| if (!hasErrors) | ||
| { | ||
| hasErrors = CheckValidScopedMethodConversion(unboundLambda.Syntax, boundLambda.Symbol, type, invokedAsExtensionMethod: false, diagnostics); |
| // (8,19): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter. | ||
| // delegate*<scoped R, void> f1 = &F1; | ||
| Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(8, 19), | ||
| // (8,40): error CS8989: The 'scoped' modifier of parameter 'r1' doesn't match target delegate 'delegate*<R, void>'. |
| } | ||
|
|
||
| [Fact] | ||
| public void DelegateConversions_01() |
|
Done with review pass (commit 2) |
Proposal: low-level-struct-improvements.md
Test plan: #59194
Require
scopedmodifiers to match exactly in overrides and implicit and explicit interface implementations.Require
scopedmodifiers to match exactly in implicit and explicit conversions of lambda expressions and method group to delegates.