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

Xmldoc with <see cref="Foo{T}(T?)"/> or similar fails to compile #33782

Open
cyanite opened this issue Mar 1, 2019 · 17 comments
Open

Xmldoc with <see cref="Foo{T}(T?)"/> or similar fails to compile #33782

cyanite opened this issue Mar 1, 2019 · 17 comments
Assignees
Labels
Area-Compilers Bug Feature - Nullable Reference Types Nullable Reference Types Regression Tenet-Compatibility Violation of forwards/backwards compatibility in a design-time piece. Urgency-Soon
Milestone

Comments

@cyanite
Copy link
Contributor

cyanite commented Mar 1, 2019

Visual Studio 2019 RC (csc.exe version 3.0.19.12206 (ec36668)):

Steps to Reproduce:

Write this code. Note that Visual Studio helps you complete the <see cref...>. Enable XML documentation file and enable all warnings as errors.

using System;
namespace Repro2
{
    /// <summary/>
    public class Class1
    {
        void Foo<T>(T t) where T : class { }
        void Foo<T>(T? t) where T : struct { }

        /// <summary>
        /// See <see cref="Foo{T}(T?)"/>
        /// </summary>
        void Bar() { }
    }
}

Expected Behavior:
It works.

Actual Behavior:
It fails with CS1580 Invalid type for parameter T? in XML comment cref attribute: 'Foo{T}(T?)'

If you change it to <see cref="Foo{T}(Nullable{T})"/> it works, but Visual Studio will now nag you to change it back to the version that doesn't :p.

This is a regression; both syntaxes worked in Visual Studio 2017. The old compiler produced the following in the document file:

<see cref="M:Repro2.Class1.Foo``1(System.Nullable{``0})"/>

The new one produces:

<see cref="M:Repro2.Class1.Foo``1(``0)"/>

(and warns/fails if warnings as errors is enabled.)

@gafter gafter added Bug Area-Compilers Tenet-Compatibility Violation of forwards/backwards compatibility in a design-time piece. Feature - Nullable Reference Types Nullable Reference Types labels Mar 4, 2019
@gafter gafter added this to the 16.1.P1 milestone Mar 4, 2019
@gafter
Copy link
Member

gafter commented Mar 4, 2019

It appears the addition of the nullable ref types feature may have introduced a regression here.

@jcouv jcouv self-assigned this Mar 11, 2019
@jcouv
Copy link
Member

jcouv commented Mar 11, 2019

Confirmed this is a regression (15.9 accepts this xml doc). Investigating....

@jcouv jcouv modified the milestones: 16.1.P1, 16.0.P4 Mar 11, 2019
@jcouv jcouv added 4 - In Review A fix for the issue is submitted for review. Regression Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented and removed 4 - In Review A fix for the issue is submitted for review. labels Mar 11, 2019
@jcouv
Copy link
Member

jcouv commented Mar 15, 2019

Fixed for dev16 (rc4)

@jcouv jcouv closed this as completed Mar 15, 2019
@jcouv
Copy link
Member

jcouv commented Mar 15, 2019

Thanks @cyanite for reporting this!

@branko-d
Copy link

branko-d commented Apr 4, 2019

Fixed for dev16 (rc4)

Not fixed in Visual Studio 2019 Professional RTM (version 16.0.0).

@jcouv jcouv reopened this Apr 5, 2019
@jcouv
Copy link
Member

jcouv commented Apr 5, 2019

@branko-d I've tried the code in OP in 16.0 preview 5 (which is very close to RTM) just now, and it compiled fine.

@jaredpar Could someone try to repro on dev16.0 RTM bits while I'm away?

@jcouv
Copy link
Member

jcouv commented Apr 5, 2019

My bad. It does repro on 16.0 preview 5. I forgot to enable XML documentation in the project.
That said, the test I had added seems correct. Needs some investigation.

@jcouv jcouv modified the milestones: 16.0.P4, 16.1, 16.2 Apr 18, 2019
@jcouv jcouv modified the milestones: 16.2, 16.3 Jun 25, 2019
@jcouv jcouv modified the milestones: 16.3, 16.4 Aug 28, 2019
@jaredpar jaredpar removed the Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented label Sep 10, 2019
@RikkiGibson
Copy link
Contributor

I can't repro this in 16.3 preview 3.

@jaredpar
Copy link
Member

@RikkiGibson great. Can we change the test @jcouv originally added so that it forces XML doc creation? That should close the gap.

@branko-d
Copy link

Sorry for nagging but...

I'm still seeing the issue in Visual Studio Professional 2019 16.3.1.

@jcouv jcouv modified the milestones: 16.4, 16.5 Oct 29, 2019
@jcouv jcouv modified the milestones: 16.5, 16.6 Feb 14, 2020
@jaredpar
Copy link
Member

jaredpar commented Apr 2, 2020

This does not repro with latest

@jaredpar jaredpar closed this as completed Apr 2, 2020
@daiplusplus
Copy link

@jaredpar I can reproduce this in a .NET Framework 4.7.2 project with C# 7.3 in Visual Studio 2019 16.7.2. Code and screenshot below.

The difference seems to be my use of a nullable generic enum type parameter. Should I file a new bug or will you reopen this issue?

Relevant code:

		/// <summary>Combines <see cref="CleanPagingParams(int, string, int?, int?, out IReadOnlyList{string}, out int, out int)"/> and <see cref="CleanOrderByParams{TOrderByEnum}(TOrderByEnum?, bool?, out TOrderByEnum, out bool)"/>.</summary>
		public static ActualPagingParams<TOrderByEnum> CleanAllParams<TOrderByEnum>( Int32 defaultPageSize, IHasPagingParams<TOrderByEnum> paras, out IReadOnlyList<String> terms, out Int32 pageIndex, out Int32 pageSize, out TOrderByEnum orderBy, out Boolean asc )
			where TOrderByEnum : struct, Enum
		{
			CleanPagingParams(
				defaultPageSize: defaultPageSize,
				search         : paras.Search,
				pageNumber     : paras.PageNumber,
				count          : paras.PageSize,
				terms          : out terms,
				pageIndex      : out pageIndex,
				pageSize       : out pageSize 
			);

			CleanOrderByParams<TOrderByEnum>(
				inputOrderBy   : paras.OrderBy,
				inputOrderByAsc: paras.OrderByAsc,
				orderBy        : out orderBy,
				asc            : out asc
			);

			return new ActualPagingParams<TOrderByEnum>( terms: terms, orderBy: orderBy, defaultPageSize: defaultPageSize, pageIndex: pageIndex, pageSize: pageSize, orderByAsc: asc );
		}

		public static void CleanOrderByParams<TOrderByEnum>( TOrderByEnum? inputOrderBy, String inputDir, out TOrderByEnum orderBy, out Boolean asc )
			where TOrderByEnum : struct, Enum
		{
			if( inputOrderBy.HasValue && EnumTraits<TOrderByEnum>.IsDefined( inputOrderBy.Value ) )
			{
				orderBy = inputOrderBy.Value;
			}
			else
			{
				orderBy = EnumOrderBy<TOrderByEnum>.DefaultOrderBy;
			}

			CleanOrderByAscParams( orderBy, inputDir, out asc );
		}

Screenshot:

image

@RikkiGibson
Copy link
Contributor

It would be really helpful to have a more minimal reproducer. I wasn't able to come up with one in a few minutes of trying. I defer to @jaredpar on whether this issue should be reopened or a new issue should be opened.

@jaredpar
Copy link
Member

I agree we'd need more info in order to make progress here. The code samples we have no longer reproduce this behavior hence there really isn't a way to make progress without a new one that demonstrates the negative behavior.

@RikkiGibson
Copy link
Contributor

I found a minimal reproducer. It seems that having a LangVersion < 8 is key.

Project.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>library</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <LangVersion>7.3</LangVersion>
    <DocumentationFile>ConsoleApp11.xml</DocumentationFile>
  </PropertyGroup>
</Project>

Program.cs

/// <summary>
/// Something about C
/// </summary>
public class C
{
    // warning CS1580: Invalid type for parameter T? in XML comment cref attribute: 'M{T}(T?)'
    /// <summary>Something about <see cref="M{T}(T?)" /></summary>
    public static void M<T>(T? t) where T : struct
    {
    }
}

@daiplusplus
Copy link

daiplusplus commented Oct 10, 2020

BTW, there exists a workaround: manually change T? to Nullable{T} and then the warnings go away.

So if you have:

public static String Foo<TValue>(this TValue? value)
    where TValue : struct, IConvertible
{
}

/// <summary>Alias for <see cref="Foo{TValue}(TValue?)"/>.</summary>
public static String Bar<TValue>(this TValue? value)
    where TValue : struct, IConvertible
{
}

Change it to this:

/// <summary>Alias for <see cref="Foo{TValue}(Nullable{TValue})"/>.</summary>
public static String Bar<TValue>(this TValue? value)
    where TValue : struct, IConvertible
{
}

and the warning is solved. No need for suppression. Phew!

@RikkiGibson
Copy link
Contributor

It's good to hear you were able to work around the issue. Apparently I found a reproducer that works with old LangVersion, but I neglected to reopen the issue. Sorry about that--it does feel like we should address this problem.

@RikkiGibson RikkiGibson reopened this Oct 10, 2020
@arunchndr arunchndr modified the milestones: 16.6, Backlog Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Bug Feature - Nullable Reference Types Nullable Reference Types Regression Tenet-Compatibility Violation of forwards/backwards compatibility in a design-time piece. Urgency-Soon
Projects
None yet
Development

No branches or pull requests

8 participants