Skip to content

Commit

Permalink
Merge pull request dotnet#49154 from huoyaoyuan/issue-48742
Browse files Browse the repository at this point in the history
Don't generate nullable type when applying value type with unconstrained nullable generic
  • Loading branch information
CyrusNajmabadi authored May 17, 2021
2 parents 6c46bd0 + 3638c73 commit ac43b83
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1911,5 +1911,134 @@ public override void AbstractMethod()
}
}", parseOptions: TestOptions.RegularPreview);
}

[WorkItem(48742, "https://github.com/dotnet/roslyn/issues/48742")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)]
public async Task TestUnconstrainedGenericNullable()
{
await TestAllOptionsOffAsync(
@"#nullable enable
abstract class B<T>
{
public abstract T? M();
}
class [|D|] : B<int>
{
}",
@"#nullable enable
abstract class B<T>
{
public abstract T? M();
}
class D : B<int>
{
public override int M()
{
throw new System.NotImplementedException();
}
}");
}

[WorkItem(48742, "https://github.com/dotnet/roslyn/issues/48742")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)]
public async Task TestUnconstrainedGenericNullable2()
{
await TestAllOptionsOffAsync(
@"#nullable enable
abstract class B<T>
{
public abstract T? M();
}
class [|D<T>|] : B<T> where T : struct
{
}",
@"#nullable enable
abstract class B<T>
{
public abstract T? M();
}
class D<T> : B<T> where T : struct
{
public override T M()
{
throw new System.NotImplementedException();
}
}");
}

[WorkItem(48742, "https://github.com/dotnet/roslyn/issues/48742")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)]
public async Task TestUnconstrainedGenericNullable_Tuple()
{
await TestAllOptionsOffAsync(
@"#nullable enable
abstract class B<T>
{
public abstract T? M();
}
class [|D<T>|] : B<(T, T)>
{
}",
@"#nullable enable
abstract class B<T>
{
public abstract T? M();
}
class D<T> : B<(T, T)>
{
public override (T, T) M()
{
throw new System.NotImplementedException();
}
}");
}

[WorkItem(48742, "https://github.com/dotnet/roslyn/issues/48742")]
[Theory, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)]
[InlineData("", "T")]
[InlineData(" where T : class", "T")]
[InlineData("", "T?")]
[InlineData(" where T : class", "T?")]
[InlineData(" where T : struct", "T?")]
public async Task TestUnconstrainedGenericNullable_NoRegression(string constraint, string passToBase)
{
await TestAllOptionsOffAsync(
$@"#nullable enable
abstract class B<T>
{{
public abstract T? M();
}}
class [|D<T>|] : B<{passToBase}>{constraint}
{{
}}",
$@"#nullable enable
abstract class B<T>
{{
public abstract T? M();
}}
class D<T> : B<{passToBase}>{constraint}
{{
public override T? M()
{{
throw new System.NotImplementedException();
}}
}}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,10 @@ public override TypeSyntax VisitNamedType(INamedTypeSymbol symbol)
}
}

if (symbol.NullableAnnotation == NullableAnnotation.Annotated &&
!symbol.IsValueType)
if (symbol is { IsValueType: false, NullableAnnotation: NullableAnnotation.Annotated })
{
// value type with nullable annotation may be composed from unconstrained nullable generic
// doesn't mean nullable value type in this case
typeSyntax = AddInformationTo(SyntaxFactory.NullableType(typeSyntax), symbol);
}

Expand Down Expand Up @@ -355,8 +356,12 @@ public override TypeSyntax VisitPointerType(IPointerTypeSymbol symbol)
public override TypeSyntax VisitTypeParameter(ITypeParameterSymbol symbol)
{
TypeSyntax typeSyntax = AddInformationTo(symbol.Name.ToIdentifierName(), symbol);
if (symbol.NullableAnnotation == NullableAnnotation.Annotated)
if (symbol is { IsValueType: false, NullableAnnotation: NullableAnnotation.Annotated })
{
// value type with nullable annotation may be composed from unconstrained nullable generic
// doesn't mean nullable value type in this case
typeSyntax = AddInformationTo(SyntaxFactory.NullableType(typeSyntax), symbol);
}

return typeSyntax;
}
Expand Down

0 comments on commit ac43b83

Please sign in to comment.