From 285be96f0ff1001d03fbd97a430c5de8dacafcc7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 19:34:54 +0000 Subject: [PATCH 1/7] Initial plan From 690b0fc8ebe238d048702fe227c42abe7045f6f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 19:54:06 +0000 Subject: [PATCH 2/7] Fix introduce local for function pointer types Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com> --- .../IntroduceVariableTests.cs | 29 +++++++++++++++++++ .../Symbols/ITypeSymbolExtensions.cs | 4 +++ 2 files changed, 33 insertions(+) diff --git a/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs b/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs index 930f6ade210a5..053696f332cb1 100644 --- a/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs +++ b/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs @@ -8497,4 +8497,33 @@ void M(object[] p) } """, new(parseOptions: TestOptions.Regular)); + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76851")] + public Task TestFunctionPointerType() + => TestInRegularAndScriptAsync( + """ + unsafe class C + { + public delegate* managed D + { + get + { + return [|field|]; + } + } + } + """, + """ + unsafe class C + { + public delegate* managed D + { + get + { + delegate* {|Rename:value|} = field; + return value; + } + } + } + """); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs index a94a2942727db..27e0909068930 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs @@ -343,6 +343,10 @@ public static string CreateParameterName(this ITypeSymbol type, bool capitalize case IPointerTypeSymbol pointerType: type = pointerType.PointedAtType; continue; + case IFunctionPointerTypeSymbol: + // Function pointer types like "delegate*" don't have meaningful names, + // so use the default parameter name + return capitalize ? DefaultParameterName.ToPascalCase() : DefaultParameterName; } break; From d860c92e5269f15cb30ea23d096b32b01d2b41de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 20:02:44 +0000 Subject: [PATCH 3/7] Handle normal pointer types same as function pointers Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com> --- .../IntroduceVariableTests.cs | 29 +++++++++++++++++++ .../Symbols/ITypeSymbolExtensions.cs | 8 ++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs b/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs index 053696f332cb1..0679bc58df02b 100644 --- a/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs +++ b/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs @@ -8526,4 +8526,33 @@ public delegate* managed D } } """); + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76851")] + public Task TestPointerType() + => TestInRegularAndScriptAsync( + """ + unsafe class C + { + public void* D + { + get + { + return [|field|]; + } + } + } + """, + """ + unsafe class C + { + public void* D + { + get + { + void* {|Rename:value|} = field; + return value; + } + } + } + """); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs index 27e0909068930..ca898fe4de220 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs @@ -340,12 +340,10 @@ public static string CreateParameterName(this ITypeSymbol type, bool capitalize case IArrayTypeSymbol arrayType: type = arrayType.ElementType; continue; - case IPointerTypeSymbol pointerType: - type = pointerType.PointedAtType; - continue; + case IPointerTypeSymbol: case IFunctionPointerTypeSymbol: - // Function pointer types like "delegate*" don't have meaningful names, - // so use the default parameter name + // Pointer types like "void*" and function pointer types like "delegate*" + // don't have meaningful names, so use the default parameter name return capitalize ? DefaultParameterName.ToPascalCase() : DefaultParameterName; } From c4269b6a4102b218028c251e13a15c629147cd9b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 20:15:21 +0000 Subject: [PATCH 4/7] Update WorkItem to reference issue 80982 Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com> --- .../CSharpTest/IntroduceVariable/IntroduceVariableTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs b/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs index 0679bc58df02b..f684299922d73 100644 --- a/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs +++ b/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs @@ -8498,7 +8498,7 @@ void M(object[] p) """, new(parseOptions: TestOptions.Regular)); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76851")] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/80982")] public Task TestFunctionPointerType() => TestInRegularAndScriptAsync( """ @@ -8527,7 +8527,7 @@ public delegate* managed D } """); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76851")] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/80982")] public Task TestPointerType() => TestInRegularAndScriptAsync( """ From b81b0692f1548482dbe6627aaeb3a0aaf59a7dda Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 22:03:46 +0000 Subject: [PATCH 5/7] Restore pointer unwrapping for custom types, keep function pointer fix Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com> --- .../IntroduceVariable/IntroduceVariableTests.cs | 12 ++++++++---- .../Extensions/Symbols/ITypeSymbolExtensions.cs | 10 +++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs b/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs index f684299922d73..6fa85ff50ad71 100644 --- a/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs +++ b/src/Features/CSharpTest/IntroduceVariable/IntroduceVariableTests.cs @@ -8533,7 +8533,9 @@ public Task TestPointerType() """ unsafe class C { - public void* D + class Customer { } + + public Customer* D { get { @@ -8545,12 +8547,14 @@ public void* D """ unsafe class C { - public void* D + class Customer { } + + public Customer* D { get { - void* {|Rename:value|} = field; - return value; + Customer* {|Rename:customer|} = field; + return customer; } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs index ca898fe4de220..a5115ac45592b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs @@ -340,10 +340,14 @@ public static string CreateParameterName(this ITypeSymbol type, bool capitalize case IArrayTypeSymbol arrayType: type = arrayType.ElementType; continue; - case IPointerTypeSymbol: + case IPointerTypeSymbol pointerType: + // For normal pointers like Customer*, unwrap to get a meaningful name (customer) + // rather than using a generic default + type = pointerType.PointedAtType; + continue; case IFunctionPointerTypeSymbol: - // Pointer types like "void*" and function pointer types like "delegate*" - // don't have meaningful names, so use the default parameter name + // Function pointer types like "delegate*" don't have a meaningful underlying type + // to generate a name from, so use the default parameter name return capitalize ? DefaultParameterName.ToPascalCase() : DefaultParameterName; } From a25aa2990f7c2b767be08ea853ce5b865e944cc4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 3 Nov 2025 10:11:22 -0800 Subject: [PATCH 6/7] Handle pointer types --- .../Core/Extensions/SemanticModelExtensions.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SemanticModelExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SemanticModelExtensions.cs index 731ad29aec5bb..0628aabf1c8f1 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SemanticModelExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SemanticModelExtensions.cs @@ -141,21 +141,19 @@ public static string GenerateNameFromType(this SemanticModel semanticModel, ITyp // We may be able to use the type's arguments to generate a name if we're working with an enumerable type. if (pluralize && TryGeneratePluralizedNameFromTypeArgument(syntaxFacts, typeArguments, capitalize, out var typeArgumentParameterName)) - { return typeArgumentParameterName; - } // If there's no type argument and we have an array type, we should pluralize, e.g. using 'frogs' for 'new Frog[]' instead of 'frog' if (type.TypeKind == TypeKind.Array && typeArguments.IsEmpty) - { return Pluralize(type.CreateParameterName(capitalize)); - } + + if (type is IPointerTypeSymbol pointerType) + return GenerateNameFromType(semanticModel, pointerType.PointedAtType, syntaxFacts, capitalize); // Otherwise assume no pluralization, e.g. using 'immutableArray', 'list', etc. instead of their // plural forms if (type.IsSpecialType() || - type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T || - type.TypeKind == TypeKind.Pointer) + type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { return capitalize ? DefaultBuiltInParameterName.ToUpper() : DefaultBuiltInParameterName; } From 7d5c78ad1d2bf20423dfe10135e005adf6c640e4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 3 Nov 2025 10:13:34 -0800 Subject: [PATCH 7/7] Handle types consistently --- .../Core/Extensions/SemanticModelExtensions.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SemanticModelExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SemanticModelExtensions.cs index 0628aabf1c8f1..a145ef76c95d9 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SemanticModelExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SemanticModelExtensions.cs @@ -150,17 +150,14 @@ public static string GenerateNameFromType(this SemanticModel semanticModel, ITyp if (type is IPointerTypeSymbol pointerType) return GenerateNameFromType(semanticModel, pointerType.PointedAtType, syntaxFacts, capitalize); + if (type.IsNullable(out var underlyingType)) + return GenerateNameFromType(semanticModel, underlyingType, syntaxFacts, capitalize); + // Otherwise assume no pluralization, e.g. using 'immutableArray', 'list', etc. instead of their // plural forms - if (type.IsSpecialType() || - type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) - { - return capitalize ? DefaultBuiltInParameterName.ToUpper() : DefaultBuiltInParameterName; - } - else - { - return type.CreateParameterName(capitalize); - } + return type.IsSpecialType() + ? capitalize ? DefaultBuiltInParameterName.ToUpper() : DefaultBuiltInParameterName + : type.CreateParameterName(capitalize); } private static bool ShouldPluralize(this SemanticModel semanticModel, ITypeSymbol type)