Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeLoadException resulted by using interpolated string in PowerShell #55609

Closed
daxian-dbw opened this issue Aug 13, 2021 · 5 comments · Fixed by #55642
Closed

TypeLoadException resulted by using interpolated string in PowerShell #55609

daxian-dbw opened this issue Aug 13, 2021 · 5 comments · Fixed by #55642
Assignees
Milestone

Comments

@daxian-dbw
Copy link

Description

After building PowerShell against .NET 6 Preview 7 SDK, tab completion in PowerShell throws TypeLoadException:

PS:4> $er.Exception.InnerException

Message        : The generic type '<>A{00000002}`3' was used with an invalid instantiation in assembly 'System.Management.Automation,
                 Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
TypeName       : <>A{00000002}`3
TargetSite     : Void NativeCompletionProcessCommands(System.Management.Automation.CompletionContext, System.String,
                 System.Collections.Generic.List`1[System.Management.Automation.CompletionResult])
Data           : {}
InnerException :
HelpLink       :
Source         : System.Management.Automation
HResult        : -2146233054
StackTrace     :    at System.Management.Automation.CompletionCompleters.NativeCompletionProcessCommands(CompletionContext context, String
                 paramName, List`1 result)
                    at System.Management.Automation.CompletionCompleters.NativeCommandArgumentCompletion(String commandName,
                 CompiledCommandParameter parameter, List`1 result, CommandAst commandAst, CompletionContext context, Dictionary`2
                 boundArguments) in
                 C:\arena\source\PowerShell\src\System.Management.Automation\engine\CommandCompletion\CompletionCompleters.cs:line 2187
                    at System.Management.Automation.CompletionCompleters.ProcessParameter(String commandName, CommandAst commandAst,
                 CompletionContext context, List`1 result, MergedCompiledCommandParameter parameter, Dictionary`2 boundArguments) in
                 C:\arena\source\PowerShell\src\System.Management.Automation\engine\CommandCompletion\CompletionCompleters.cs:line 1807
                    at System.Management.Automation.CompletionCompleters.GetArgumentCompletionResultsWithSuccessfulPseudoBinding(Completion
                 Context context, ArgumentLocation argLocation, CommandAst commandAst) in
                 C:\arena\source\PowerShell\src\System.Management.Automation\engine\CommandCompletion\CompletionCompleters.cs:line 1550
                    at System.Management.Automation.CompletionCompleters.CompleteCommandArgument(CompletionContext context) in
                 C:\arena\source\PowerShell\src\System.Management.Automation\engine\CommandCompletion\CompletionCompleters.cs:line 1061
                    at System.Management.Automation.CompletionAnalysis.GetResultHelper(CompletionContext completionContext, Int32&
                 replacementIndex, Int32& replacementLength, Boolean isQuotedString) in
                 C:\arena\source\PowerShell\src\System.Management.Automation\engine\CommandCompletion\CompletionAnalysis.cs:line 768
                    at System.Management.Automation.CompletionAnalysis.GetResults(PowerShell powerShell, Int32& replacementIndex, Int32&
                 replacementLength) in
                 C:\arena\source\PowerShell\src\System.Management.Automation\engine\CommandCompletion\CompletionAnalysis.cs:line 380
                    at System.Management.Automation.CommandCompletion.CompleteInputImpl(Ast ast, Token[] tokens, IScriptPosition
                 positionOfCursor, Hashtable options) in
                 C:\arena\source\PowerShell\src\System.Management.Automation\engine\CommandCompletion\CommandCompletion.cs:line 579
                    at System.Management.Automation.CommandCompletion.CompleteInput(String input, Int32 cursorIndex, Hashtable options) in
                 C:\arena\source\PowerShell\src\System.Management.Automation\engine\CommandCompletion\CommandCompletion.cs:line 102
                    at CallSite.Target(Closure , CallSite , Type , String , Int32 , Hashtable )

Configuration

.NET 6 Preview 7 SDK on Windows 10 x64.

Regression?

Yes, from all prior versions of .NET Core.

Other information

Repro steps:

On PowerShell built against .NET 6 preview 7 SDK run the following steps:

PS:7> $cmd = 'Get-Process -Id '
PS:8> TabExpansion2 -inputScript $cmd  -cursorColumn $cmd.Length
MethodInvocationException:
Line |
  38 |  …      return [System.Management.Automation.CommandCompletion]::Complet …
     |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Exception calling "CompleteInput" with "3" argument(s): "The generic type '<>A{00000002}`3' was used with an invalid instantiation in assembly 'System.Management.Automation, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'."

I looked more into the issue and found that this exception is triggered by the use of a interpolated string: var idAndName = $"{processId} - {processName}". The exception goes away after I replace it with var idAndName = processId + " - " + processName;.

The interesting part is that both processId and processName in the code are of the dynamic type. The exception may be related to that.

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@stephentoub
Copy link
Member

I believe this is a Roslyn issue. The new support for interpolated strings shouldn't enable the new lowering when arguments are dynamic (or at least not when the handler type is a ref struct). This will produce the same error:

var handler = new Handler(0, 0);
handler.AppendFormatted((dynamic)5);

ref struct Handler
{
    public Handler(int literalLength, int formattedCount) { }
    public void AppendFormatted<T>(T value) { }
}

@stephentoub stephentoub transferred this issue from dotnet/runtime Aug 13, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Aug 13, 2021
@stephentoub
Copy link
Member

cc: @333fred, @jaredpar, @jcouv

@jaredpar jaredpar added Bug Feature - Interpolated String Improvements Interpolated string improvements and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Aug 13, 2021
@jaredpar jaredpar added this to the 17.0 milestone Aug 13, 2021
@jaredpar
Copy link
Member

The way that interpolation is designed is that we effectively do standard overload resolution to find the "best" AppendFormatted method on the handler. For dynamic that means that we will do standard dynamic lookup which goes through the binder. As noted that is always going to fail when the handler is a ref struct.

That will work when the handler is a simple class or struct. Hence we could choose to avoid this only when the handler is a ref struct. My off the cuff reaction though is to just use the existing string.Format lowering when any of the arguments are dynamic. The intent of the new lowering is primarily aimed at performance and if you're using dynamic you're likely not concerned with that low level performance.

More generally I wonder if we should be warning / erroring when you attempt to mix dynamic and ref struct receivers at all. Consider this code which will have similar throwing behavior all the way back to 7.2

using System;
var span = "hello".AsSpan();
dynamic index = 0;
Console.WriteLine(span[index]);

333fred added a commit to 333fred/roslyn that referenced this issue Aug 16, 2021
Fixes dotnet#55609. Note that we don't attempt to warn/error for custom handlers, as we never warn/error when mixing dynamic and ref structs today. If that ever changes, we'll naturally start producing warnings here as well.
333fred added a commit that referenced this issue Aug 18, 2021
* Use string.Format when an interpolated string part is dynamic

Fixes #55609. Note that we don't attempt to warn/error for custom handlers, as we never warn/error when mixing dynamic and ref structs today. If that ever changes, we'll naturally start producing warnings here as well.
@perason
Copy link

perason commented Oct 21, 2021

I got similar/same exception when using interpolation in a partial view.

VS 2022 (both in RC and RC2), NET 6 RC2

Code part in layout:
<partial name="/Pages/Partial/Menu/Header.cshtml" />

Code part in partial view:
<span>@($"User: {Model.AppRequest.UserName}")</span>


Error message/exception/trace:

"Message": "The generic type '<>A{00000004} 3' was used with an invalid instantiation in assembly 'whjnthmb.rov, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.",

"Exception": "TypeLoadException",

"Trace": "
at Asons.Pages.Partial.Menu.Pages_Partial_Menu__Header.ExecuteAsync()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at Asons.Pages.Partial.Menu.Pages_Partial_Menu__Header.ExecuteAsync()
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.TagHelpers.PartialTagHelper.RenderPartialViewAsync(TextWriter writer, Object model, IView view)
at Microsoft.AspNetCore.Mvc.TagHelpers.PartialTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, Int32 i, Int32 count)
at Asons.Pages.Shared.Pages_Shared__Layout_Base_Default.ExecuteAsync() in \Pages\Shared\_Layout_Base_Default.cshtml:line 12
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderLayoutAsync(ViewContext context, ViewBufferTextWriter bodyWriter)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable1 statusCode) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable1 statusCode)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)"

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

Successfully merging a pull request may close this issue.

5 participants