Skip to content

Comments

Logging source generator: support generic methods (lift SYSLIB1011)#124638

Open
Copilot wants to merge 16 commits intomainfrom
copilot/support-generic-logging-methods
Open

Logging source generator: support generic methods (lift SYSLIB1011)#124638
Copilot wants to merge 16 commits intomainfrom
copilot/support-generic-logging-methods

Conversation

Copy link
Contributor

Copilot AI commented Feb 20, 2026

Generic [LoggerMessage] methods were unconditionally rejected with SYSLIB1011. Methods with type parameters are fully supportable via the struct-based code generation path. The only remaining restriction is allows ref struct (C# 13), since the generated struct stores params in fields and cannot hold ref-struct type arguments.

Description

Parser (LoggerMessageGenerator.Parser.cs)

  • Removed the method.Arity > 0SYSLIB1011 check
  • Added LoggerMethodTypeParameter / LoggerMethodTypeParameterSpec record types to carry type parameter names + constraints through the pipeline
  • GetTypeParameterConstraints serializes all constraint kinds: class/class?, struct, unmanaged, notnull, base/interface types (incl. nullable), new()
  • Preserves all FullyQualifiedFormat.MiscellaneousOptions (EscapeKeywordIdentifiers | UseSpecialTypes) when adding IncludeNullableReferenceTypeModifier — fixes a pre-existing bug on the same call for parameter types
  • Skips IErrorTypeSymbol constraint types (unresolvable in generated code)
  • allows ref struct detected via Func<ITypeParameterSymbol, bool> delegate compiled from ITypeParameterSymbol.AllowsRefLikeType via Delegate.CreateDelegate (compiles against all supported Roslyn versions; no per-call boxing) — emits SYSLIB1011
  • Renamed DiagnosticDescriptors.LoggingMethodIsGenericLoggingMethodHasAllowsRefStructConstraint; updated message + all XLF files (only changed entry marked needs-translation)

Emitter (LoggerMessageGenerator.Emitter.cs)

  • UseLoggerMessageDefine excludes generic methods — the Define path caches a static delegate and cannot capture method type parameters
  • GenStruct emits the state struct as generic (__M1Struct<T>) with matching where constraints
  • GenLogMethod emits <T, U> and where clauses on the partial method signature
  • GenHolder/Format references parameterized with concrete type arguments
  • Replaced GetTypeParameterList/GetTypeConstraints (string-returning, allocating) with GenTypeParameterList/GenTypeConstraints writing directly to _builder
  • Removed using System.Linq; IndexOf('{') replaces Contains('{') (no allocating LINQ path on netstandard2.0)

Incremental cache (LoggerMessageGenerator.Roslyn4.0.cs)

  • FromSpec round-trips TypeParameters through the incremental cache

Docs

  • docs/project/list-of-diagnostics.md updated: SYSLIB1011 now describes the allows ref struct restriction
  • External learn.microsoft.com docs tracked in dotnet/docs#51840

Example

// Previously: SYSLIB1011. Now: works, no boxing of TCode.
[LoggerMessage(0, LogLevel.Trace, "Received {Code} ({Length} bytes)")]
public static partial void PacketReceived<TCode>(ILogger logger, TCode code, int length)
    where TCode : struct, Enum;

All constraint forms supported: class, class?, struct, unmanaged, notnull, base type, interface, nullable interface, new(). allows ref struct emits SYSLIB1011.

Original prompt

This section details on the original issue you should resolve

<issue_title>Logging source generator should support generic methods (SYSLIB1011 should be lifted)</issue_title>
<issue_description>From this section:

Logging methods cannot be generic.

This seems to be an unnecessary restriction that also works against the whole notion of high-performance logging.

I would like to be able to write a logging method like so:

[LoggerMessage(0, LogLevel.Trace, "C -> S {EndPoint}: {Channel}:{Code} ({Length} bytes)")]
public static partial void PacketReceived<TCode>(ILogger logger, IPEndPoint endPoint, ConnectionChannel channel, TCode code, int length)
    where TCode : struct, Enum;

Here, the type argument for TCode depends on the value of Channel. Of course, I could make the logging method non-generic and accept an Enum-typed value, but then I get unconditional boxing... certainly not what I want when logging in a fairly hot path. Alternatively, I could duplicate the method for as many TCodes as I have (which is what I'll do for now), but this is not great either, for all the expected maintenance reasons.

I think this restriction should just be lifted. Maybe there's a good reason for it, but if there is, it's not obvious to me.</issue_description>

<agent_instructions>Implement and test this. Make sure that all of these are supported: multiple type parameters, multiple constraints, various kinds of constraints.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@ Tagging subscribers to this area: @dotnet/area-extensions-logging See info in [area-owners.md](https://github.com/dotnet/runtime/blob/main/docs/area-owners.md) if you want to be subscribed.
Issue Details

From this section:

Logging methods cannot be generic.

This seems to be an unnecessary restriction that also works against the whole notion of high-performance logging.

I would like to be able to write a logging method like so:

[LoggerMessage(0, LogLevel.Trace, "C -> S {EndPoint}: {Channel}:{Code} ({Length} bytes)")]
public static partial void PacketReceived<TCode>(ILogger logger, IPEndPoint endPoint, ConnectionChannel channel, TCode code, int length)
    where TCode : struct, Enum;

Here, the type argument for TCode depends on the value of Channel. Of course, I could make the logging method non-generic and accept an Enum-typed value, but then I get unconditional boxing... certainly not what I want when logging in a fairly hot path. Alternatively, I could duplicate the method for as many TCodes as I have (which is what I'll do for now), but this is not great either, for all the expected maintenance reasons.

I think this restriction should just be lifted. Maybe there's a good reason for it, but if there is, it's not obvious to me.

Author: alexrp
Assignees: -
Labels:

untriaged, area-Extensions-Logging

Milestone: -
@cincuranet Triage: Niche scenario, but would be nice to have it one day.

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 20, 2026
…restriction)

Co-authored-by: svick <287848+svick@users.noreply.github.com>
Copilot AI changed the title [WIP] Lift restriction on generic methods for logging Logging source generator: support generic methods (lift SYSLIB1011) Feb 20, 2026
Copilot AI requested a review from svick February 20, 2026 13:57
Co-authored-by: svick <287848+svick@users.noreply.github.com>
…struct; handle nullable constraints

Co-authored-by: svick <287848+svick@users.noreply.github.com>
…; fix XLF states

Co-authored-by: svick <287848+svick@users.noreply.github.com>
Co-authored-by: svick <287848+svick@users.noreply.github.com>
…arameter type name display call

Co-authored-by: svick <287848+svick@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Enables the LoggerMessage source generator to support generic logging methods by carrying method type parameters/constraints through parsing, caching, and emission, while narrowing SYSLIB1011 to only forbid the C# 13 allows ref struct anti-constraint.

Changes:

  • Lifted the blanket rejection of generic logging methods; added parsing/serialization of method type parameters + constraint rendering (including nullable constraints).
  • Updated emitter to generate generic state structs and generic partial method signatures (and to exclude generic methods from the LoggerMessage.Define fast-path).
  • Updated SYSLIB1011 descriptor/message/resources/docs and added/updated parser + emitter baseline tests.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs Parses method type parameters/constraints; diagnoses allows ref struct; preserves display format options.
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs Emits generic structs/methods/constraints; avoids Define path for generic methods; small perf cleanup.
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Roslyn4.0.cs Round-trips method type parameter data through the incremental cache.
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/DiagnosticDescriptors.cs Renames/narrows SYSLIB1011 descriptor to the allows ref struct restriction.
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/Strings.resx Updates SYSLIB1011 message text and resource key.
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.cs.xlf Updates localized resource key/message for SYSLIB1011 (marked needs-translation).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.de.xlf Same as above (German).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.es.xlf Same as above (Spanish).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.fr.xlf Same as above (French).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.it.xlf Same as above (Italian).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ja.xlf Same as above (Japanese).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ko.xlf Same as above (Korean).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pl.xlf Same as above (Polish).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.pt-BR.xlf Same as above (Portuguese - Brazil).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.ru.xlf Same as above (Russian).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.tr.xlf Same as above (Turkish).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hans.xlf Same as above (Chinese - Simplified).
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/Resources/xlf/Strings.zh-Hant.xlf Same as above (Chinese - Traditional).
src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs Adds/updates tests for generic methods, constraints, nullable constraints, and allows ref struct diagnostic.
src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs Adds emitter baseline test covering generic methods.
src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithGenericMethods.generated.txt New baseline output verifying correct generic codegen.
docs/project/list-of-diagnostics.md Updates SYSLIB1011 documentation to reflect the narrowed restriction.

…d instead of hard-coded string

Co-authored-by: svick <287848+svick@users.noreply.github.com>
@svick
Copy link
Member

svick commented Feb 23, 2026

The equivalent PR in the telemetry logging source generator is at dotnet/extensions#7331.

Co-authored-by: svick <287848+svick@users.noreply.github.com>
Copilot AI requested a review from svick February 23, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logging source generator should support generic methods (SYSLIB1011 should be lifted)

4 participants