diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index fa2521d431ee6..598dcb8a7b32c 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -1799,6 +1799,9 @@ If such a class is used as a base class and if the deriving class defines a dest
The DllImport attribute must be specified on a method marked 'extern' that is either 'static' or an extension member
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
Cannot emit update; {0} '{1}' is missing.
diff --git a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/PEDeltaAssemblyBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/PEDeltaAssemblyBuilder.cs
index ffbf411f38694..eae8747777f09 100644
--- a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/PEDeltaAssemblyBuilder.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/PEDeltaAssemblyBuilder.cs
@@ -78,6 +78,7 @@ public PEDeltaAssemblyBuilder(
public override SymbolChanges? EncSymbolChanges => _changes;
public override EmitBaseline PreviousGeneration => _changes.DefinitionMap.Baseline;
public override bool FieldRvaSupported => _options.EmitFieldRva;
+ public override bool MethodImplSupported => !_options.DisallowExplicitMethodImplementations;
internal override Cci.ITypeReference EncTranslateLocalVariableType(TypeSymbol type, DiagnosticBag diagnostics)
{
diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs
index 6dc02ea27b561..7caddab400db0 100644
--- a/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEAssemblyBuilder.cs
@@ -693,6 +693,7 @@ internal sealed class PEAssemblyBuilder(
public override EmitBaseline? PreviousGeneration => null;
public override SymbolChanges? EncSymbolChanges => null;
public override bool FieldRvaSupported => true;
+ public override bool MethodImplSupported => true;
public override INamedTypeSymbolInternal? TryGetOrCreateSynthesizedHotReloadExceptionType()
=> null;
diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs
index f8889a0a0bee7..8d640781946d9 100644
--- a/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/Model/PENetModuleBuilder.cs
@@ -40,6 +40,7 @@ protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder null;
public override SymbolChanges? EncSymbolChanges => null;
public override bool FieldRvaSupported => true;
+ public override bool MethodImplSupported => true;
public override INamedTypeSymbolInternal? TryGetOrCreateSynthesizedHotReloadExceptionType()
=> null;
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 912ef255ec070..231a7747b0190 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -2441,6 +2441,7 @@ internal enum ErrorCode
ERR_AmbigOperator = 9342,
ERR_UnexpectedArgumentListInBaseTypeWithoutParameterList = 9343,
+ ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime = 9344,
// Note: you will need to do the following after adding errors:
// 1) Update ErrorFacts.IsBuildOnlyDiagnostic (src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs)
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
index 34d8db1fcba80..7d40a4ad1702e 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
@@ -2548,6 +2548,7 @@ or ErrorCode.ERR_SingleInapplicableBinaryOperator
or ErrorCode.ERR_SingleInapplicableUnaryOperator
or ErrorCode.ERR_AmbigOperator
or ErrorCode.ERR_UnexpectedArgumentListInBaseTypeWithoutParameterList
+ or ErrorCode.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime
=> false,
};
#pragma warning restore CS8524 // The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value.
diff --git a/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs b/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs
index ce041f56e38ee..215fb0a98bb60 100644
--- a/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs
+++ b/src/Compilers/CSharp/Portable/Errors/MessageProvider.cs
@@ -253,6 +253,7 @@ public override void ReportDuplicateMetadataReferenceWeak(DiagnosticBag diagnost
public override int ERR_InvalidDebugInfo => (int)ErrorCode.ERR_InvalidDebugInfo;
public override int ERR_FunctionPointerTypesInAttributeNotSupported => (int)ErrorCode.ERR_FunctionPointerTypesInAttributeNotSupported;
public override int ERR_DataSectionStringLiteralHashCollision => (int)ErrorCode.ERR_DataSectionStringLiteralHashCollision;
+ public override int ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime => (int)ErrorCode.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime;
// Generators:
public override int WRN_GeneratorFailedDuringInitialization => (int)ErrorCode.WRN_GeneratorFailedDuringInitialization;
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index 6e3206add1745..4850edca7cebb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -702,6 +702,11 @@
Nelze vygenerovat aktualizaci; chybí {0} '{1}' .
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Vstupní body aplikací nemůžou mít atribut UnmanagedCallersOnly.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index 19913bcd83e31..44fe6e383fb0f 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -702,6 +702,11 @@
Update kann nicht ausgeben; {0} '{1}' fehlt.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Anwendungseinstiegspunkte können nicht mit dem Attribut "UnmanagedCallersOnly" versehen werden.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 4cba477613dba..d914082040410 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -702,6 +702,11 @@
No se puede emitir la actualización; falta {0} '{1}' .
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Los puntos de entrada de la aplicación no se pueden atribuir con "UnmanagedCallersOnly".
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 0a04a8104c850..d535798312927 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -702,6 +702,11 @@
Impossible d’émettre la mise à jour ; {0} '{1}' est manquant.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Les points d'entrée d'application ne peuvent pas être attribués avec 'UnmanagedCallersOnly'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index dbd05f1a07054..2dd101f42192b 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -702,6 +702,11 @@
Non è possibile creare l'aggiornamento. {0} '{1}' mancante.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Non è possibile aggiungere ai punti di ingresso dell'applicazione l'attributo 'UnmanagedCallersOnly'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index 57c7a27226d02..573379e388dcb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -702,6 +702,11 @@
更新プログラムを生成できません。 {0} '{1}' がありません。
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.アプリケーションのエントリ ポイントに 'UnmanagedCallersOnly' 属性を設定することはできません。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 3026822368c23..7f28cf4dab3c8 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -702,6 +702,11 @@
업데이트를 내보낼 수 없습니다. {0} '{1}' 없습니다.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.애플리케이션 진입점에는 'UnmanagedCallersOnly' 특성을 지정할 수 없습니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index be802bdf233e1..a6431065a96c2 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -702,6 +702,11 @@
Nie można wyemitować aktualizacji;brak {0} '{1}' .
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Punkty wejścia aplikacji nie mogą mieć atrybutu „UnmanagedCallersOnly”.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 222dc8837f38c..cc1cddf88b57b 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -702,6 +702,11 @@
Não é possível emitir a atualização; {0} '{1}' está ausente.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Os pontos de entrada do aplicativo não podem ser atribuídos com 'UnmanagedCallersOnly'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 1d55b42621a1e..f19398b92e0bd 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -702,6 +702,11 @@
Не удается создать обновление; {0} '{1}' отсутствует.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Точки входа приложения не могут иметь атрибут "UnmanagedCallersOnly".
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index ad43d6f21d747..3450ef862b19d 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -702,6 +702,11 @@
Güncelleştirme gönderilemiyor; {0} '{1}' eksik.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.Uygulama giriş noktaları 'UnmanagedCallersOnly' ile ilişkilendirilemez.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 91633b41243bc..4bae4c9b3eb86 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -702,6 +702,11 @@
无法发出更新;缺少 {0} '{1}' 。
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.无法使用 "UnmanagedCallersOnly" 对应用程序入口点进行特性化。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 110e11b109d7e..68f5c3e8446eb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -702,6 +702,11 @@
無法發出更新;遺漏 {0} '{1}' 。
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ Application entry points cannot be attributed with 'UnmanagedCallersOnly'.無法使用 'UnmanagedCallersOnly' 將應用程式進入點屬性化。
diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueTests.cs
index 10a89ee7e81b6..75e77acc77024 100644
--- a/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueTests.cs
+++ b/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueTests.cs
@@ -21913,8 +21913,8 @@ class C
.Verify();
}
- [ConditionalFact(typeof(CoreClrOnly))]
- public void PrivateImplDetails_CollectionExpressions_ReadOnlyListTypes()
+ [Fact]
+ public void PrivateImplDetails_CollectionExpressions_ReadOnlyListTypes_MethodImplSupported()
{
using var _ = new EditAndContinueTest(targetFramework: TargetFramework.Net80, verification: Verification.Skipped)
.AddBaseline(
@@ -22076,5 +22076,81 @@ class C
})
.Verify();
}
+
+ [Fact]
+ [WorkItem("https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/2631743")]
+ public void PrivateImplDetails_CollectionExpressions_ReadOnlyListTypes_MethodImplNotSupported()
+ {
+ using var _ = new EditAndContinueTest(targetFramework: TargetFramework.NetFramework, verification: Verification.Skipped)
+ .AddBaseline(
+ source: """
+ using System.Collections.Generic;
+ class C
+ {
+ static IEnumerable F(int x, int y, IEnumerable e) => [x, y];
+ }
+ """)
+
+ .AddGeneration(
+ """
+ using System.Collections.Generic;
+ class C
+ {
+ static IEnumerable F(int x, int y, IEnumerable e) => [x, y, default];
+ }
+ """,
+ edits:
+ [
+ Edit(SemanticEditKind.Update, symbolProvider: c => c.GetMember("C.F")),
+ ],
+ options: new EmitDifferenceOptions()
+ {
+ DisallowExplicitMethodImplementations = true
+ },
+ expectedErrors:
+ [
+ Diagnostic(ErrorCode.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime)
+ ])
+ .Verify();
+ }
+
+ [Fact]
+ [WorkItem("https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/2631743")]
+ public void ExplicitInterfaceImplementation_MethodImplNotSupported()
+ {
+ using var _ = new EditAndContinueTest(targetFramework: TargetFramework.NetFramework, verification: Verification.Skipped)
+ .AddBaseline(
+ source: """
+ interface I
+ {
+ void M();
+ }
+ """)
+
+ .AddGeneration(
+ """
+ interface I
+ {
+ void M();
+ }
+ class C : I
+ {
+ void I.M() { }
+ }
+ """,
+ edits:
+ [
+ Edit(SemanticEditKind.Insert, symbolProvider: c => c.GetMember("C")),
+ ],
+ options: new EmitDifferenceOptions()
+ {
+ DisallowExplicitMethodImplementations = true
+ },
+ expectedErrors:
+ [
+ Diagnostic(ErrorCode.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime)
+ ])
+ .Verify();
+ }
}
}
diff --git a/src/Compilers/Core/Portable/Compilation/EmitDifferenceOptions.cs b/src/Compilers/Core/Portable/Compilation/EmitDifferenceOptions.cs
index b793f7cad973c..fb996f204b2e4 100644
--- a/src/Compilers/Core/Portable/Compilation/EmitDifferenceOptions.cs
+++ b/src/Compilers/Core/Portable/Compilation/EmitDifferenceOptions.cs
@@ -12,4 +12,10 @@ public readonly struct EmitDifferenceOptions()
/// True to emit FieldRva table entries. The runtime must support this feature.
///
public bool EmitFieldRva { get; init; }
+
+ ///
+ /// True to disallow explicit method implementations in the delta.
+ /// Some runtimes (.NET Framework) do not support this feature.
+ ///
+ public bool DisallowExplicitMethodImplementations { get; init; }
}
diff --git a/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs b/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs
index 17ba2c0ea880b..73be957d6b984 100644
--- a/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs
+++ b/src/Compilers/Core/Portable/Diagnostic/CommonMessageProvider.cs
@@ -247,6 +247,7 @@ public string GetIdForErrorCode(int errorCode)
public abstract int ERR_InvalidDebugInfo { get; }
public abstract int ERR_FunctionPointerTypesInAttributeNotSupported { get; }
public abstract int ERR_DataSectionStringLiteralHashCollision { get; }
+ public abstract int ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime { get; }
// Generators:
public abstract int WRN_GeneratorFailedDuringInitialization { get; }
diff --git a/src/Compilers/Core/Portable/Emit/CommonPEModuleBuilder.cs b/src/Compilers/Core/Portable/Emit/CommonPEModuleBuilder.cs
index e91b243645a75..d02d17f77c314 100644
--- a/src/Compilers/Core/Portable/Emit/CommonPEModuleBuilder.cs
+++ b/src/Compilers/Core/Portable/Emit/CommonPEModuleBuilder.cs
@@ -87,6 +87,11 @@ protected CommonPEModuleBuilder(
///
public abstract bool FieldRvaSupported { get; }
+ ///
+ /// True if MethodImpl table is supported by the runtime.
+ ///
+ public abstract bool MethodImplSupported { get; }
+
///
/// Previous EnC generation baseline, or null if this is not EnC delta.
///
diff --git a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
index 262b4ab7ffca1..20a9e8210867c 100644
--- a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
+++ b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
@@ -2592,9 +2592,21 @@ private void PopulateMemberRefTableRows()
private void PopulateMethodImplTableRows()
{
+ if (methodImplList.Count == 0)
+ {
+ return;
+ }
+
+ if (!Module.MethodImplSupported)
+ {
+ // .NET Framework incorrectly handles MethodImpl table in the second generation, which causes AV.
+ // https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/2631743
+ Context.Diagnostics.Add(messageProvider.CreateDiagnostic(messageProvider.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime, NoLocation.Singleton));
+ }
+
metadata.SetCapacity(TableIndex.MethodImpl, methodImplList.Count);
- foreach (MethodImplementation methodImplementation in this.methodImplList)
+ foreach (MethodImplementation methodImplementation in methodImplList)
{
metadata.AddMethodImplementation(
type: GetTypeDefinitionHandle(methodImplementation.ContainingType),
diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt
index fc5b0a225448b..c61a7af354ac1 100644
--- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt
+++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt
@@ -10,6 +10,8 @@ Microsoft.CodeAnalysis.CommandLineResource.ResourceName.get -> string!
Microsoft.CodeAnalysis.Compilation.EmitDifference(Microsoft.CodeAnalysis.Emit.EmitBaseline! baseline, System.Collections.Generic.IEnumerable! edits, System.Func! isAddedSymbol, System.IO.Stream! metadataStream, System.IO.Stream! ilStream, System.IO.Stream! pdbStream, Microsoft.CodeAnalysis.Emit.EmitDifferenceOptions options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.Emit.EmitDifferenceResult!
Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzersOptions.CompilationWithAnalyzersOptions(Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions? options, System.Action? onAnalyzerException, bool concurrentAnalysis, bool logAnalyzerExecutionTime, bool reportSuppressedDiagnostics, System.Func? analyzerExceptionFilter, System.Func? getAnalyzerConfigOptionsProvider) -> void
Microsoft.CodeAnalysis.Emit.EmitDifferenceOptions
+Microsoft.CodeAnalysis.Emit.EmitDifferenceOptions.DisallowExplicitMethodImplementations.get -> bool
+Microsoft.CodeAnalysis.Emit.EmitDifferenceOptions.DisallowExplicitMethodImplementations.init -> void
Microsoft.CodeAnalysis.Emit.EmitDifferenceOptions.EmitDifferenceOptions() -> void
Microsoft.CodeAnalysis.Emit.EmitDifferenceOptions.EmitFieldRva.get -> bool
Microsoft.CodeAnalysis.Emit.EmitDifferenceOptions.EmitFieldRva.init -> void
diff --git a/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs b/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs
index 83094186aa8a8..be6f0d43abcba 100644
--- a/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs
+++ b/src/Compilers/Test/Core/Mocks/TestMessageProvider.cs
@@ -486,5 +486,7 @@ public override int ERR_InvalidDebugInfo
public override int ERR_DataSectionStringLiteralHashCollision => throw new NotImplementedException();
public override int? WRN_ByValArraySizeConstRequired => throw new NotImplementedException();
+
+ public override int ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime => throw new NotImplementedException();
}
}
diff --git a/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/PEDeltaAssemblyBuilder.vb b/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/PEDeltaAssemblyBuilder.vb
index 7e08b71b2dc46..5f6ec5fb0543b 100644
--- a/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/PEDeltaAssemblyBuilder.vb
+++ b/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/PEDeltaAssemblyBuilder.vb
@@ -101,6 +101,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End Get
End Property
+ Public Overrides ReadOnly Property MethodImplSupported As Boolean
+ Get
+ Return Not _options.DisallowExplicitMethodImplementations
+ End Get
+ End Property
+
Friend Shared Function GetOrCreateMetadataSymbols(initialBaseline As EmitBaseline, compilation As VisualBasicCompilation) As EmitBaseline.MetadataSymbols
If initialBaseline.LazyMetadataSymbols IsNot Nothing Then
Return initialBaseline.LazyMetadataSymbols
diff --git a/src/Compilers/VisualBasic/Portable/Emit/PEAssemblyBuilder.vb b/src/Compilers/VisualBasic/Portable/Emit/PEAssemblyBuilder.vb
index 5164604a5ec0d..6fb6831d7da68 100644
--- a/src/Compilers/VisualBasic/Portable/Emit/PEAssemblyBuilder.vb
+++ b/src/Compilers/VisualBasic/Portable/Emit/PEAssemblyBuilder.vb
@@ -204,6 +204,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End Get
End Property
+ Public Overrides ReadOnly Property MethodImplSupported As Boolean
+ Get
+ Return True
+ End Get
+ End Property
+
Public Overrides Function TryGetOrCreateSynthesizedHotReloadExceptionType() As INamedTypeSymbolInternal
Return Nothing
End Function
diff --git a/src/Compilers/VisualBasic/Portable/Emit/PENetModuleBuilder.vb b/src/Compilers/VisualBasic/Portable/Emit/PENetModuleBuilder.vb
index 5627931e3ab4c..c756cb1e5c6a2 100644
--- a/src/Compilers/VisualBasic/Portable/Emit/PENetModuleBuilder.vb
+++ b/src/Compilers/VisualBasic/Portable/Emit/PENetModuleBuilder.vb
@@ -52,6 +52,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End Get
End Property
+ Public Overrides ReadOnly Property MethodImplSupported As Boolean
+ Get
+ Return True
+ End Get
+ End Property
+
Public Overrides Function TryGetOrCreateSynthesizedHotReloadExceptionType() As INamedTypeSymbolInternal
Return Nothing
End Function
diff --git a/src/Compilers/VisualBasic/Portable/Errors/ErrorFacts.vb b/src/Compilers/VisualBasic/Portable/Errors/ErrorFacts.vb
index d89461d23f6b0..cd6329069aec0 100644
--- a/src/Compilers/VisualBasic/Portable/Errors/ErrorFacts.vb
+++ b/src/Compilers/VisualBasic/Portable/Errors/ErrorFacts.vb
@@ -1371,6 +1371,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ERRID.ERR_CannotApplyOverloadResolutionPriorityToOverride,
ERRID.ERR_CannotApplyOverloadResolutionPriorityToMember,
ERRID.ERR_NextAvailable,
+ ERRID.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime,
ERRID.WRN_UseOfObsoleteSymbol2,
ERRID.WRN_InvalidOverrideDueToTupleNames2,
ERRID.WRN_MustOverloadBase4,
diff --git a/src/Compilers/VisualBasic/Portable/Errors/Errors.vb b/src/Compilers/VisualBasic/Portable/Errors/Errors.vb
index fa2a1c865110f..8b0b4974c4bdb 100644
--- a/src/Compilers/VisualBasic/Portable/Errors/Errors.vb
+++ b/src/Compilers/VisualBasic/Portable/Errors/Errors.vb
@@ -1791,8 +1791,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ERR_MethodImplAttributeAsyncCannotBeUsed = 37337
ERR_AttributeCannotBeAppliedManually = 37338
+ ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime = 37339
- ERR_NextAvailable = 37339
+ ERR_NextAvailable = 37340
'// WARNINGS BEGIN HERE
WRN_UseOfObsoleteSymbol2 = 40000
diff --git a/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb b/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb
index 14c6ebeee3080..e62b350f5791a 100644
--- a/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb
+++ b/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb
@@ -612,6 +612,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
+ Public Overrides ReadOnly Property ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime As Integer
+ Get
+ Return ERRID.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime
+ End Get
+ End Property
+
' Generators
Public Overrides ReadOnly Property WRN_GeneratorFailedDuringInitialization As Integer
Get
diff --git a/src/Compilers/VisualBasic/Portable/VBResources.resx b/src/Compilers/VisualBasic/Portable/VBResources.resx
index a3a4f839359dc..b9954e15d44d3 100644
--- a/src/Compilers/VisualBasic/Portable/VBResources.resx
+++ b/src/Compilers/VisualBasic/Portable/VBResources.resx
@@ -4937,6 +4937,9 @@
'{0}' is an unsupported event.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
Properties can not have type arguments
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.cs.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.cs.xlf
index 204a097343bb8..a72d38ac25611 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.cs.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.cs.xlf
@@ -62,6 +62,11 @@
Nelze aktualizovat {0}; chybí atribut {1}.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifierArgument diagnosticId atributu Experimental musí být platný identifikátor
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.de.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.de.xlf
index f630804356c66..098a47bf26172 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.de.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.de.xlf
@@ -62,6 +62,11 @@
"{0}" kann nicht aktualisiert werden. Das Attribut "{1}" fehlt.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifierDas diagnosticId-Argument für das Experimental-Attribut muss ein gültiger Bezeichner sein.
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.es.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.es.xlf
index 4413d88e2c8a1..16bd126360cd6 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.es.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.es.xlf
@@ -62,6 +62,11 @@
No se puede actualizar '{0}'; falta el atributo '{1}'.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifierEl argumento diagnosticId del atributo "Experimental" debe ser un identificador válido.
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.fr.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.fr.xlf
index ca88df8a4faca..f193c3562d4e1 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.fr.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.fr.xlf
@@ -62,6 +62,11 @@
Impossible de mettre à jour '{0}' ; l'attribut '{1}' est manquant.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifierL’argument diagnosticId de l’attribut « Experimental » doit être un identificateur valide
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.it.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.it.xlf
index acd15f59152eb..c94b6fd9f40d6 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.it.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.it.xlf
@@ -62,6 +62,11 @@
Non è possibile aggiornare '{0}'. Manca l'attributo '{1}'.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifierL'argomento diagnosticId dell'attributo 'Experimental' deve essere un identificatore valido
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ja.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ja.xlf
index c8c448adfe008..de76874e45056 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ja.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ja.xlf
@@ -62,6 +62,11 @@
'{0}' を更新できません。属性 '{1}' がありません。
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifier'Experimental' 属性への diagnosticId 引数は有効な識別子である必要があります
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ko.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ko.xlf
index 8be9cada314a7..44cb5caa12465 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ko.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ko.xlf
@@ -62,6 +62,11 @@
'{0}'을(를) 업데이트할 수 없습니다. 특성 '{1}'이(가) 없습니다.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifier'Experimental' 특성에 대한 diagnosticId 인수는 유효한 식별자여야 합니다.
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.pl.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.pl.xlf
index de29a64e076ac..6bf422c0d5bde 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.pl.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.pl.xlf
@@ -62,6 +62,11 @@
Nie można zaktualizować elementu „{0}”. Brak atrybutu „{1}”.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifierArgument diagnosticId atrybutu „Experimental” musi być prawidłowym identyfikatorem
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.pt-BR.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.pt-BR.xlf
index 0433c70d82121..06d5a53c6c16d 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.pt-BR.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.pt-BR.xlf
@@ -62,6 +62,11 @@
Não é possível atualizar '{0}'; o atributo '{1}' está ausente.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifierO argumento diagnosticId para o atributo 'Experimental' deve ser um identificador válido
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ru.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ru.xlf
index b662760770fe4..251a98f4bc8b7 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ru.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ru.xlf
@@ -62,6 +62,11 @@
Невозможно обновить "{0}"; нет атрибута "{1}".
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifierАргумент diagnosticId атрибута "Experimental" должен быть допустимым идентификатором
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf
index 0c7e86198cbdf..8378b1344827f 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf
@@ -62,6 +62,11 @@
'{0}' güncelleştirilemiyor; '{1}' özniteliği eksik.
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifier'Experimental' özniteliğinin diagnosticId bağımsız değişkeni geçerli bir tanımlayıcı olmalıdır
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hans.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hans.xlf
index e49313c141ce4..6ea832088fd45 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hans.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hans.xlf
@@ -62,6 +62,11 @@
无法更新“{0}”;特性“{1}”缺失。
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifier“Experimental” 属性的 diagnosticId 参数必须是有效的标识符
diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hant.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hant.xlf
index aa5cf0b0b842b..8e9c1e35e8ad4 100644
--- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hant.xlf
+++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hant.xlf
@@ -62,6 +62,11 @@
無法更新 '{0}'; 缺少屬性 '{1}'。
+
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+ Update requires emitting explicit interface implementation, which is not supported by the runtime without restarting the application.
+
+ The diagnosticId argument to the 'Experimental' attribute must be a valid identifier'Experimental' 屬性的 diagnosticId 引數必須是有效的識別碼
diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.vb
index 148998283d491..62d6737dc36cf 100644
--- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.vb
+++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.vb
@@ -8075,5 +8075,44 @@ End Class
Verify()
End Using
End Sub
+
+
+
+ Public Sub ExplicitInterfaceImplementation_MethodImplNotSupported()
+ Using New EditAndContinueTest(targetFramework:=TargetFramework.NetFramework, verification:=Verification.Skipped).
+ AddBaseline(
+ source:="
+Interface I
+ Sub M()
+End Interface
+").
+ AddGeneration(
+ source:="
+Interface I
+ Sub M()
+End Interface
+Class C
+ Implements I
+
+ Sub M() Implements I.M
+ End Sub
+End Class
+",
+ edits:=
+ {
+ Edit(SemanticEditKind.Insert, symbolProvider:=Function(c) c.GetMember("C"))
+ },
+ options:=
+ New EmitDifferenceOptions() With
+ {
+ .DisallowExplicitMethodImplementations = True
+ },
+ expectedErrors:=
+ {
+ Diagnostic(ERRID.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime)
+ }).
+ Verify()
+ End Using
+ End Sub
End Class
End Namespace
diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EEAssemblyBuilder.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EEAssemblyBuilder.cs
index fa0b0b9cff9c0..99223132875e8 100644
--- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EEAssemblyBuilder.cs
+++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EEAssemblyBuilder.cs
@@ -66,6 +66,7 @@ protected override Cci.IModuleReference TranslateModule(ModuleSymbol symbol, Dia
public override EmitBaseline? PreviousGeneration => null;
public override SymbolChanges? EncSymbolChanges => null;
public override bool FieldRvaSupported => true;
+ public override bool MethodImplSupported => true;
public override INamedTypeSymbolInternal? TryGetOrCreateSynthesizedHotReloadExceptionType()
=> null;
diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs
index 107315318114b..07a755a390037 100644
--- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs
+++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ReferencedModulesTests.cs
@@ -1544,6 +1544,7 @@ public override IEnumerable GetTopLevelSourceTypeDefin
public override SymbolChanges EncSymbolChanges => _builder.EncSymbolChanges;
public override EmitBaseline PreviousGeneration => _builder.PreviousGeneration;
public override bool FieldRvaSupported => _builder.FieldRvaSupported;
+ public override bool MethodImplSupported => _builder.MethodImplSupported;
public override ISourceAssemblySymbolInternal SourceAssemblyOpt => _builder.SourceAssemblyOpt;
diff --git a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/EEAssemblyBuilder.vb b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/EEAssemblyBuilder.vb
index 6ee1727e54ffb..54d5bd86ae4ea 100644
--- a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/EEAssemblyBuilder.vb
+++ b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/EEAssemblyBuilder.vb
@@ -86,6 +86,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Get
End Property
+ Public Overrides ReadOnly Property MethodImplSupported As Boolean
+ Get
+ Return True
+ End Get
+ End Property
+
Public Overrides Function TryGetOrCreateSynthesizedHotReloadExceptionType() As INamedTypeSymbolInternal
Return Nothing
End Function
diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb
index 2cb5012e8d339..18f5c9dffa62b 100644
--- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb
+++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb
@@ -978,6 +978,12 @@ End Class"
End Get
End Property
+ Public Overrides ReadOnly Property MethodImplSupported As Boolean
+ Get
+ Return _builder.MethodImplSupported
+ End Get
+ End Property
+
Public Overrides ReadOnly Property SourceAssemblyOpt As ISourceAssemblySymbolInternal
Get
Return _builder.SourceAssemblyOpt
diff --git a/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs b/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs
index 5666e53e55810..9b1ac211638bf 100644
--- a/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs
+++ b/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs
@@ -67,7 +67,7 @@ internal enum EditAndContinueCapabilities
GenericAddFieldToExistingType = 1 << 9,
///
- /// The runtime supports adding to InterfaceImpl table.
+ /// The runtime supports adding to MethodImpl table.
///
AddExplicitInterfaceImplementation = 1 << 10,
diff --git a/src/Features/Core/Portable/EditAndContinue/EditSession.cs b/src/Features/Core/Portable/EditAndContinue/EditSession.cs
index 5a3ccbdd1f6e3..bf291893669b2 100644
--- a/src/Features/Core/Portable/EditAndContinue/EditSession.cs
+++ b/src/Features/Core/Portable/EditAndContinue/EditSession.cs
@@ -1343,7 +1343,11 @@ void UpdateChangedDocumentsStaleness(bool isStale)
metadataStream,
ilStream,
pdbStream,
- new EmitDifferenceOptions() { EmitFieldRva = capabilities.HasFlag(EditAndContinueCapabilities.AddFieldRva) },
+ new EmitDifferenceOptions()
+ {
+ EmitFieldRva = capabilities.HasFlag(EditAndContinueCapabilities.AddFieldRva),
+ DisallowExplicitMethodImplementations = !capabilities.HasFlag(EditAndContinueCapabilities.AddExplicitInterfaceImplementation)
+ },
cancellationToken);
Telemetry.LogEmitDifferenceTime(emitDifferenceTimer.Elapsed);
diff --git a/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs b/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs
index f8135e912d4a4..95e394c425c72 100644
--- a/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs
+++ b/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs
@@ -2864,6 +2864,44 @@ public async Task Capabilities_SynthesizedNewType()
EndDebuggingSession(debuggingSession);
}
+ [Fact]
+ [WorkItem("https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/2631743")]
+ public async Task Capabilities_ExplicitInterfaceImplementation()
+ {
+ var source1 = "class C { System.Collections.Generic.IEnumerable M() => [1]; }";
+ var source2 = "class C { System.Collections.Generic.IEnumerable M() => [2]; }";
+
+ using var _ = CreateWorkspace(out var solution, out var service);
+ solution = AddDefaultTestProject(solution, [source1]);
+ var project = solution.Projects.Single();
+ var documentId = solution.Projects.Single().Documents.Single().Id;
+
+ EmitAndLoadLibraryToDebuggee(project.Id, source1);
+
+ // attached to processes that doesn't allow creating new types
+ _debuggerService.GetCapabilitiesImpl = () => EditAndContinueTestVerifier.NetFrameworkCapabilities.ToStringArray();
+
+ // F5
+ var debuggingSession = StartDebuggingSession(service, solution);
+
+ // update document:
+ solution = solution.WithDocumentText(documentId, CreateText(source2));
+ var document2 = solution.Projects.Single().Documents.Single();
+
+ // The error isn't reported as document diagnostic:
+ var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetDocument(documentId), s_noActiveSpans, CancellationToken.None);
+ AssertEx.Empty(diagnostics);
+
+ // The error is reported as emit diagnostic:
+ var results = await EmitSolutionUpdateAsync(debuggingSession, solution);
+ AssertEx.Equal([$"proj: : Error CS9344: {CSharpResources.ERR_EncUpdateRequiresEmittingExplicitInterfaceImplementationNotSupportedByTheRuntime}"], InspectDiagnostics(results.Diagnostics));
+
+ // no emitted delta:
+ Assert.Empty(results.ModuleUpdates.Updates);
+
+ EndDebuggingSession(debuggingSession);
+ }
+
[Fact]
public async Task ValidSignificantChange_EmitError()
{
diff --git a/src/Features/TestUtilities/EditAndContinue/EditAndContinueTestVerifier.cs b/src/Features/TestUtilities/EditAndContinue/EditAndContinueTestVerifier.cs
index 7108dfe1a8da1..f24a9bf9a33ba 100644
--- a/src/Features/TestUtilities/EditAndContinue/EditAndContinueTestVerifier.cs
+++ b/src/Features/TestUtilities/EditAndContinue/EditAndContinueTestVerifier.cs
@@ -27,6 +27,15 @@ internal abstract class EditAndContinueTestVerifier
{
public const EditAndContinueCapabilities BaselineCapabilities = EditAndContinueCapabilities.Baseline;
+ public const EditAndContinueCapabilities NetFrameworkCapabilities =
+ EditAndContinueCapabilities.Baseline |
+ EditAndContinueCapabilities.AddInstanceFieldToExistingType |
+ EditAndContinueCapabilities.AddStaticFieldToExistingType |
+ EditAndContinueCapabilities.AddMethodToExistingType |
+ EditAndContinueCapabilities.NewTypeDefinition |
+ EditAndContinueCapabilities.ChangeCustomAttributes |
+ EditAndContinueCapabilities.UpdateParameters;
+
public const EditAndContinueCapabilities Net5RuntimeCapabilities =
EditAndContinueCapabilities.Baseline |
EditAndContinueCapabilities.AddInstanceFieldToExistingType |