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 identifier Argument 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 identifier Das 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 identifier El 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 identifier L’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 identifier L'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 identifier Argument 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 identifier O 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 |