- 
                Notifications
    You must be signed in to change notification settings 
- Fork 4.2k
Extensions: allow extern and disallow in nameof #79021
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
Conversation
| <value>An extension member syntax is disallowed in nested position within an extension member syntax</value> | ||
| </data> | ||
| <data name="ERR_NameofExtensionMember" xml:space="preserve"> | ||
| <value>Extension member are not allowed as an argument to 'nameof'.</value> | 
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.
"members" (plural) or "are is allowed"? #Resolved
| { | ||
| CheckDefinitionInvariant(); | ||
| return AdaptedMethodSymbol.GetDllImportData(); | ||
| return AdaptedMethodSymbol.ContainingType.IsExtension ? null : AdaptedMethodSymbol.GetDllImportData(); | 
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.
Do we need to adjust GetImplementationAttributes similarly? #Resolved
| { | ||
| extension(int) | ||
| { | ||
| [DllImport("something.dll")] | 
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.
Should we also test [MethodImpl(MethodImplOptions.InternalCall)]? Something like here:
| public void Extern_InternalCall() | 
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.
Yup. Good catch and thanks for the pointer
| // (4,12): error CS1061: '<anonymous type: string Name, int Age>' does not contain a definition for 'P' and no accessible extension method 'P' accepting a first argument of type '<anonymous type: string Name, int Age>' could be found (are you missing a using directive or an assembly reference?) | ||
| // _ = person.P; | ||
| Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "P").WithArguments("<anonymous type: string Name, int Age>", "P").WithLocation(4, 12)); | ||
| CompileAndVerify(comp, expectedOutput: "method method2 property").VerifyDiagnostics(); | 
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.
What change caused this test to start working? #Resolved
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.
What change caused this test to start working?
There was a bug in the test scenario
| internal sealed override bool IsExternal => false; | ||
| public sealed override bool IsExtern => _originalMethod.IsExtern; | ||
| public sealed override DllImportData? GetDllImportData() => _originalMethod.GetDllImportData(); | ||
| internal sealed override bool IsExternal => _originalMethod.IsExternal; | 
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.
Should we just delete these since the base class WrappedMethodSymbol already has this implementation? #Resolved
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.
We've been leaning toward abstract+sealed design (pushing implementations down into leaves) so I intentionally left those despite the base/virtual implementation being sufficient
| } | ||
| """; | ||
| var comp = CreateCompilation(source); | ||
| comp.VerifyEmitDiagnostics( | 
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.
| } | ||
|  | ||
| [Fact] | ||
| public void Extern_02() | 
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.
| } | ||
|  | ||
| [Fact] | ||
| public void Extern_04() | 
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.
| Done with review pass (commit 3) #Closed | 
| // extern void M(); | ||
| Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M").WithArguments("C.M()").WithLocation(3, 17)); | ||
|  | ||
| // Error: Method marked Abstract, Runtime, InternalCall or Imported must have zero RVA, and vice versa. | 
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.
Consider using Verification.FailsPEVerify with { PEVerifyMessage = "..." } instead of just the comment. #Resolved
| """; | ||
| var comp = CreateCompilation(source); | ||
| comp.VerifyEmitDiagnostics( | ||
| // (13,14): error CS0601: The DllImport attribute must be specified on a method marked 'static' and 'extern' | 
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.
// (13,14): error CS0601: The DllImport attribute must be specified on a method marked 'static' and 'extern'
It looks like this error breaks our portability story. No error for classic extension method:
using System.Runtime.InteropServices;
static class E
{
    [DllImport("something.dll")]
    extern static void M(this int p);
}
``` #Closed
| } | ||
| """; | ||
| var comp = CreateCompilation(source); | ||
| comp.VerifyEmitDiagnostics( | 
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.
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.
I prefer this
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.
I prefer this
This makes the test compile and emit the code twice, which slows the run
| extension(int i) | ||
| { | ||
| extern void M(); | ||
| extern int P { get; set; } | 
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.
| } | ||
| """; | ||
| comp = CreateCompilation(source); | ||
| comp.VerifyEmitDiagnostics( | 
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.
| } | ||
| """; | ||
| comp = CreateCompilation(source); | ||
| comp.VerifyEmitDiagnostics( | 
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.
| } | ||
| """; | ||
| var comp = CreateCompilation(source); | ||
| comp.VerifyEmitDiagnostics(); | 
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.
| } | ||
|  | ||
| [Fact] | ||
| public void Extern_08() | 
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.
| Done with review pass (commit 5) #Closed | 
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.
LGTM (commit 9)
Addresses some follow-ups from #78968
Relates to test plan #76130