Skip to content

Conversation

@jcouv
Copy link
Member

@jcouv jcouv commented Jun 17, 2025

Addresses some follow-ups from #78968
Relates to test plan #76130

@jcouv jcouv self-assigned this Jun 17, 2025
@jcouv jcouv added Area-Compilers Feature - Extension Everything The extension everything feature labels Jun 17, 2025
@jcouv jcouv force-pushed the extensions-extern branch from cd4613b to c24df97 Compare June 18, 2025 05:44
@jcouv jcouv marked this pull request as ready for review June 18, 2025 06:35
@jcouv jcouv requested a review from a team as a code owner June 18, 2025 06:35
<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>
Copy link
Member

@jjonescz jjonescz Jun 18, 2025

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();
Copy link
Member

@jjonescz jjonescz Jun 18, 2025

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")]
Copy link
Member

@jjonescz jjonescz Jun 18, 2025

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:

#Resolved

Copy link
Member Author

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();
Copy link
Member

@jjonescz jjonescz Jun 18, 2025

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

Copy link
Contributor

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;
Copy link
Member

@jjonescz jjonescz Jun 18, 2025

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

Copy link
Member Author

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(
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 18, 2025

Choose a reason for hiding this comment

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

VerifyEmitDiagnostics

These are warnings, let's verify IL like in the previous test #Closed

}

[Fact]
public void Extern_02()
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 18, 2025

Choose a reason for hiding this comment

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

Extern_02

Do we test instance members? #Closed

}

[Fact]
public void Extern_04()
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 18, 2025

Choose a reason for hiding this comment

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

Extern_04

Do we test instance members? #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jun 18, 2025

Done with review pass (commit 3) #Closed

@jcouv jcouv requested a review from jjonescz June 18, 2025 19:56
// 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.
Copy link
Member

@jjonescz jjonescz Jun 19, 2025

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'
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 19, 2025

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(
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 19, 2025

Choose a reason for hiding this comment

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

VerifyEmitDiagnostics

Consider folding this check into CompileAndVerify below. #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I prefer this

Copy link
Contributor

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; }
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 19, 2025

Choose a reason for hiding this comment

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

extern

This modifier doesn't have any effect on its own in metadata? #Closed

}
""";
comp = CreateCompilation(source);
comp.VerifyEmitDiagnostics(
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 19, 2025

Choose a reason for hiding this comment

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

VerifyEmitDiagnostics

Consider folding this check into CompileAndVerify below. #Closed

}
""";
comp = CreateCompilation(source);
comp.VerifyEmitDiagnostics(
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 19, 2025

Choose a reason for hiding this comment

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

VerifyEmitDiagnostics

Same suggestion. #Closed

}
""";
var comp = CreateCompilation(source);
comp.VerifyEmitDiagnostics();
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 19, 2025

Choose a reason for hiding this comment

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

VerifyEmitDiagnostics

Same suggestion and for other similar places. #Closed

}

[Fact]
public void Extern_08()
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 19, 2025

Choose a reason for hiding this comment

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

Extern_08

Do we have a similar test for instance extensions? #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jun 19, 2025

Done with review pass (commit 5) #Closed

@jcouv jcouv requested a review from AlekseyTs June 19, 2025 19:05
Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

LGTM (commit 9)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Feature - Extension Everything The extension everything feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants