Skip to content

Erase nullability from base and interfaces for types from unannotated assemblies#28028

Merged
cston merged 11 commits intodotnet:features/NullableReferenceTypesfrom
cston:27967
Jun 30, 2018
Merged

Erase nullability from base and interfaces for types from unannotated assemblies#28028
cston merged 11 commits intodotnet:features/NullableReferenceTypesfrom
cston:27967

Conversation

@cston
Copy link
Contributor

@cston cston commented Jun 20, 2018

Erase nullability from base and interfaces for types from unannotated assemblies.

Fixes #27967.

@cston cston requested a review from a team as a code owner June 20, 2018 19:56
@cston cston changed the title Add ignoreNullability parameter to GetDeclaredBaseType() Erase nullability from base and interfaces for types from unannotated assemblies Jun 20, 2018
if (a.QuestionToken.IsKind(SyntaxKind.QuestionToken))
{
type = TypeSymbolWithAnnotations.CreateNullableReferenceType(array);
type = TypeSymbolWithAnnotations.Create(array, isNullableIfReferenceType: true);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Inlined the one instance of CreateNullableReferenceType().

return new NonLazyType(typeSymbol, isNullable, customModifiers);
}

public TypeSymbolWithAnnotations AsNullableReferenceOrValueType(CSharpCompilation compilation, SyntaxReference nullableTypeSyntax)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

nullableTypeSyntax was not needed.

@cston
Copy link
Contributor Author

cston commented Jun 21, 2018

@dotnet/roslyn-compiler please review.

@jcouv
Copy link
Member

jcouv commented Jun 21, 2018

Please tag with Area-Compiler so it shows up in review queue. Thanks #Resolved

@cston
Copy link
Contributor Author

cston commented Jun 26, 2018

@dotnet/roslyn-compiler please review.

{
static void F(object? x, B b)
{
var y = b.F;
Copy link
Member

@jcouv jcouv Jun 26, 2018

Choose a reason for hiding this comment

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

; [](start = 19, length = 1)

Maybe add a VerifyTypes comment on b.F? Expecting object~ #Closed

(new[] { x!, x! })[0].ToString();
(new[] { y, y! })[0].ToString();
(new[] { y!, y })[0].ToString();
}
Copy link
Member

@jcouv jcouv Jun 26, 2018

Choose a reason for hiding this comment

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

} [](start = 4, length = 1)

If it's not tested elsewhere, I'd also include permutations mixing x and y. Also, mixing z and w below. #Closed

D<A> d;
d = Create(x).F;
x = y;
d = Create(x).F; // warning
Copy link
Member

@jcouv jcouv Jun 26, 2018

Choose a reason for hiding this comment

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

x [](start = 19, length = 1)

Consider Create(y).F directly (rather than assigning x = y first). #Closed

F(y, x)/*T:A?*/.ToString(); // 4
F(y, y)/*T:A!*/.ToString();
F(y, z)/*T:A!*/.ToString();
F(z, x)/*T:A*/.ToString(); // 5
Copy link
Member

@jcouv jcouv Jun 26, 2018

Choose a reason for hiding this comment

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

// 5 [](start = 35, length = 4)

There is no warning for 5. I think this comment can be removed. Never mind. There should be a warning (one the ordering issue is fixed) #Closed

private ImmutableArray<NamedTypeSymbol> _lazyInterfaces = default(ImmutableArray<NamedTypeSymbol>);
private NamedTypeSymbol _lazyDeclaredBaseType = ErrorTypeSymbol.UnknownResultType;
private NamedTypeSymbol _lazyDeclaredBaseType1 = ErrorTypeSymbol.UnknownResultType;
private NamedTypeSymbol _lazyDeclaredBaseType2 = ErrorTypeSymbol.UnknownResultType;
Copy link
Member

@jcouv jcouv Jun 26, 2018

Choose a reason for hiding this comment

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

_lazyDeclaredBaseType2 [](start = 32, length = 22)

A comment would be useful (why do we need two?). Or maybe rename by adding "WithNullability" #Closed

}

// PROTOTYPE(NullableReferenceTypes): Combine with other GetDeclaredBaseType overload and make abstract.
internal virtual NamedTypeSymbol GetDeclaredBaseType(ConsList<Symbol> basesBeingResolved, bool ignoreNullability)
Copy link
Member

@jcouv jcouv Jun 26, 2018

Choose a reason for hiding this comment

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

GetDeclaredBaseType [](start = 41, length = 19)

Where is this method called from? It seems that only the overload in PENamedTypeSymbol is called from PENamedTypeSymbol itself. #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed method from base type, thanks.


In reply to: 198267943 [](ancestors = 198267943)

if (ignoreNullability)
{
Interlocked.CompareExchange(ref _lazyDeclaredBaseType, MakeDeclaredBaseType(), ErrorTypeSymbol.UnknownResultType);
return _lazyDeclaredBaseType1;
Copy link
Member

@jcouv jcouv Jun 26, 2018

Choose a reason for hiding this comment

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

Let's use a descriptive name, rather than "1" and "2". #Resolved

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Done with review pass (iteration 5).

@jcouv jcouv self-assigned this Jun 26, 2018
return GetDeclaredBaseType(basesBeingResolved, ignoreNullability: false);
}

private NamedTypeSymbol GetDeclaredBaseType(ConsList<Symbol> basesBeingResolved, bool ignoreNullability)
Copy link
Member

Choose a reason for hiding this comment

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

basesBeingResolved [](start = 69, length = 18)

Why do we even have this parameter if it's never used?

Copy link
Contributor Author

@cston cston Jun 28, 2018

Choose a reason for hiding this comment

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

Good catch. Removed.


In reply to: 198643234 [](ancestors = 198643234)

i1.F(x);
i1.F(y);
i2.F(x);
i2.F(y); // warn
Copy link
Member

Choose a reason for hiding this comment

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

This one is interesting. Perhaps more of a nullable design question, but is there going to be a way for a user to specify that I2.F takes a T?? Seems like a user would want to be able to override this behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

An implicit implementation of I.F could be defined as F(T?) since the interface method is null-oblivious, but interface I2 could not redefine I.F.


In reply to: 198655729 [](ancestors = 198655729)

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

LGTM (commit 7) with a more general question on implementation strategy.

@cston
Copy link
Contributor Author

cston commented Jun 28, 2018

@jcouv, @333fred, all feedback addressed.

@jcouv
Copy link
Member

jcouv commented Jun 29, 2018

I know that rebasing causes other problems, but merging also makes the review difficult. Now a number of changes showing up in CodeFlow are not new changes... :-(

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM

@cston cston merged commit fffa9be into dotnet:features/NullableReferenceTypes Jun 30, 2018
@cston cston deleted the 27967 branch June 30, 2018 06:51
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.

3 participants