Skip to content

Bind NonNullTypes for types#28491

Merged
jcouv merged 18 commits intodotnet:features/NullableReferenceTypesfrom
jcouv:urtann-type
Jul 25, 2018
Merged

Bind NonNullTypes for types#28491
jcouv merged 18 commits intodotnet:features/NullableReferenceTypesfrom
jcouv:urtann-type

Conversation

@jcouv
Copy link
Member

@jcouv jcouv commented Jul 12, 2018

In a previous PR on [NonNullTypes] I used a syntax-based check to recognize the attribute, rather than use proper binding. This allowed for avoiding a number of cycles.

The current PR removes the use of syntax-based check for deciding if a source named type symbol has NonNullTypes. Other symbols will be address in follow-up PRs.

Even with the NonNullTypesContext design, there were a cycles left to fix, because we're pulling on NonNullTypes too early.

  • Symbol display is easy to fix. But the impact on GetDebuggerDisplay is unfortunate.
  • MakeDefaultExpression has a check that needs to be delayed. Currently commented out.
  • SetUnknownNullabilityForReferenceTypesIfNecessary was removed. But it was hiding a bunch of missing contexts.
  • CopyTypeModifiers has an assert with Equals, which pulls on NonNullTypes. Currently commented out.
  • TypeSymbolWithAnnotation.Update (used in SourcePropertySymbol and other places) was conditional. Made it unconditional.

CheckNullableReferenceTypeMismatchOnImplementingMember:
This was fixed by calling CheckNullableReferenceTypeMismatchOnImplementingMember later.

Symbols.SourcePropertySymbol.NonNullTypes.get() Line 1519
Symbols.TypeSymbolWithAnnotations.IsAnnotatedWithNonNullTypesContext.get() Line 190
Symbols.TypeSymbolWithAnnotations.Equals(Symbols.TypeSymbolWithAnnotations other, TypeCompareKind comparison) Line 281
Symbols.TypeSymbol.CheckNullableReferenceTypeMismatchOnImplementingMember(Symbol implementingMember, Symbol interfaceMember, bool isExplicit, DiagnosticBag diagnostics) Line 1147
Symbols.SourcePropertySymbol.SourcePropertySymbol(Symbols.SourceMemberContainerTypeSymbol containingType, Binder bodyBinder, Syntax.BasePropertyDeclarationSyntax syntax, string name, Location location, DiagnosticBag diagnostics) Line 284
Symbols.SourcePropertySymbol.Create(Symbols.SourceMemberContainerTypeSymbol containingType, Binder bodyBinder, Syntax.PropertyDeclarationSyntax syntax, DiagnosticBag diagnostics) Line 458

SetUnknownNullabilityForReferenceTypesIfNecessary cycle via SourceMemberFieldSymbol.GetFieldType:
Fixed by removing the call to SetUnknownNullabilityForReferenceTypesIfNecessary. But caused other issues to become visible. Still working on those.

Symbols.FieldSymbolWithAttributesAndModifiers.NonNullTypes.get() Line 344
Symbols.TypeSymbolWithAnnotations.NonLazyType.IsNullable.get() Line 614
Symbols.TypeSymbolWithAnnotations.SetUnknownNullabilityForReferenceTypes() Line 510
Symbols.TypeSymbolWithAnnotations.SetUnknownNullabilityForReferenceTypesIfNecessary(Symbols.ModuleSymbol module) Line 490
Symbols.SourceMemberFieldSymbolFromDeclarator.GetFieldType(Roslyn.Utilities.ConsList<Symbols.FieldSymbol> fieldsBeingBound) Line 515
Symbols.FieldSymbol.Type.get() Line 55
Symbols.FieldSymbol.IsMetadataConstant.get() Line 119
Symbols.SourceMemberContainerTypeSymbol.AddInitializer(ref PooledObjects.ArrayBuilder<Symbols.FieldOrPropertyInitializer> initializers, ref int aggregateSyntaxLength, Symbols.FieldSymbol fieldOpt, CSharpSyntaxNode node) Line 2749

Cycle with SymbolDisplay:
Fixed by making symbol display as lazy as possible.
I also had to change the display options used for debugger display, so that the debugger would not pull on NonNullTypes accidentally. It's better to only see ? and blank, rather than no be able to see the type at all, while debugging.

Symbols.TypeSymbolWithAnnotations.NonLazyType.IsNullable.get() Line 614
SymbolDisplayVisitor.VisitTypeSymbolWithAnnotations(Symbols.TypeSymbolWithAnnotations type, SymbolDisplay.AbstractSymbolDisplayVisitor visitorOpt) Line 18
SymbolDisplayVisitor.AddTypeArguments(ISymbol owner, System.Collections.Immutable.ImmutableArray<System.Collections.Immutable.ImmutableArray<CustomModifier>> modifiers) Line 749
SymbolDisplayVisitor.AddNameAndTypeArgumentsOrParameters(INamedTypeSymbol symbol) Line 403
SymbolDisplayVisitor.VisitNamedType(INamedTypeSymbol symbol) Line 293
Symbols.NamedTypeSymbol.Accept(SymbolVisitor visitor) Line 1592
SymbolDisplay.ToDisplayParts(ISymbol symbol, SemanticModel semanticModelOpt, int positionOpt, SymbolDisplayFormat format, bool minimal) Line 129
SymbolDisplay.ToDisplayParts(ISymbol symbol, SymbolDisplayFormat format) Line 72
SymbolDisplay.ToDisplayString(ISymbol symbol, SymbolDisplayFormat format) Line 31
Symbol.ToDisplayString(SymbolDisplayFormat format) Line 1117
Symbols.ExplicitInterfaceHelpers.GetMemberName(string name, Symbols.TypeSymbol explicitInterfaceTypeOpt, string aliasQualifierOpt) Line 65
Symbols.ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(Binder binder, Syntax.ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifierOpt, string name, DiagnosticBag diagnostics, out Symbols.TypeSymbol explicitInterfaceTypeOpt, out string aliasQualifierOpt) Line 52
Symbols.SourceOrdinaryMethodSymbol.CreateMethodSymbol(Symbols.NamedTypeSymbol containingType, Binder bodyBinder, Syntax.MethodDeclarationSyntax syntax, DiagnosticBag diagnostics) Line 57
Symbols.SourceMemberContainerTypeSymbol.AddNonTypeMembers(Symbols.SourceMemberContainerTypeSymbol.MembersAndInitializersBuilder builder, SyntaxList<Syntax.MemberDeclarationSyntax> members, DiagnosticBag diagnostics) Line 3012
Symbols.SourceMemberContainerTypeSymbol.AddDeclaredNontypeMembers(Symbols.SourceMemberContainerTypeSymbol.MembersAndInitializersBuilder builder, DiagnosticBag diagnostics) Line 2428
Symbols.SourceMemberContainerTypeSymbol.BuildMembersAndInitializers(DiagnosticBag diagnostics) Line 2343
Symbols.SourceMemberContainerTypeSymbol.GetMembersAndInitializers() Line 1339
Symbols.SourceMemberContainerTypeSymbol.MakeAllMembers(DiagnosticBag diagnostics) Line 2204

MakeDefaultExpression:
I temporarily temporarily commented out this check. We should execute this check later.

Symbols.SourceNamedTypeSymbol.NonNullTypes.get() Line 931
Symbols.MethodSymbol.NonNullTypes.get() Line 981
Symbols.SourceMemberMethodSymbol.NonNullTypes.get() Line 189
Symbols.TypeSymbolWithAnnotations.NonLazyType.IsNullable.get() Line 614
Symbols.SourceComplexParameterSymbol.MakeDefaultExpression(DiagnosticBag diagnostics, Binder binder) Line 237
Symbols.SourceComplexParameterSymbol.DefaultSyntaxValue.get() Line 160
Symbols.SourceComplexParameterSymbol.ExplicitDefaultConstantValue.get() Line 94
Binder.GetDefaultValueArgument(Symbols.ParameterSymbol parameter, Syntax.AttributeSyntax syntax, DiagnosticBag diagnostics) Line 720
Binder.GetRewrittenAttributeConstructorArguments(out System.Collections.Immutable.ImmutableArray<int> constructorArgumentsSourceIndices, Symbols.MethodSymbol attributeConstructor, System.Collections.Immutable.ImmutableArray<TypedConstant> constructorArgsArray, System.Collections.Immutable.ImmutableArray<string> constructorArgumentNamesOpt, Syntax.AttributeSyntax syntax, DiagnosticBag diagnostics, ref bool hasErrors) Line 615
Binder.GetAttribute(BoundAttribute boundAttribute, DiagnosticBag diagnostics) Line 213
Binder.GetAttribute(Syntax.AttributeSyntax node, Symbols.NamedTypeSymbol boundAttributeType, DiagnosticBag diagnostics) Line 100
Binder.GetAttributes(System.Collections.Immutable.ImmutableArray<Binder> binders, System.Collections.Immutable.ImmutableArray<Syntax.AttributeSyntax> attributesToBind, System.Collections.Immutable.ImmutableArray<Symbols.NamedTypeSymbol> boundAttributeTypes, Symbols.CSharpAttributeData[] attributesBuilder, DiagnosticBag diagnostics) Line 74
Symbol.LoadAndValidateAttributes(Roslyn.Utilities.OneOrMany<SyntaxList<Syntax.AttributeListSyntax>> attributesSyntaxLists, ref CustomAttributesBag<Symbols.CSharpAttributeData> lazyCustomAttributesBag, Symbols.AttributeLocation symbolPart, bool earlyDecodingOnly, Binder binderOpt, System.Func<Syntax.AttributeSyntax, bool> attributeMatchesOpt) Line 317
Symbols.SourceNamedTypeSymbol.GetAttributesBag() Line 460
Symbols.SourceNamedTypeSymbol.GetDecodedWellKnownAttributeData() Line 490
Symbols.SourceNamedTypeSymbol.NonNullTypes.get() Line 931
Symbols.MethodSymbol.NonNullTypes.get() Line 981
Symbols.SourceMemberMethodSymbol.NonNullTypes.get() Line 189

The cycles below are no longer relevant. They were all solved by the NonNullTypesContext design :-)

For context, here are the stack traces for the various cycles:
Cycle 11

Symbols.SourceNamedTypeSymbol.NonNullTypes.get() Line 942
Binder.NonNullTypes.get() Line 228
Binder.BindNamespaceOrTypeOrAliasSymbol(Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, bool suppressUseSiteDiagnostics) Line 381
Binder.BindTypeOrAlias(Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved) Line 271
Binder.BindType(Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved) Line 251
Binder.BindAttributeTypes(System.Collections.Immutable.ImmutableArray<Binder> binders, System.Collections.Immutable.ImmutableArray<Syntax.AttributeSyntax> attributesToBind, Symbol ownerSymbol, Symbols.NamedTypeSymbol[] boundAttributeTypes, DiagnosticBag diagnostics) Line 45
Symbol.LoadAndValidateAttributes(Roslyn.Utilities.OneOrMany<SyntaxList<Syntax.AttributeListSyntax>> attributesSyntaxLists, ref CustomAttributesBag<Symbols.CSharpAttributeData> lazyCustomAttributesBag, Symbols.AttributeLocation symbolPart, bool earlyDecodingOnly, Binder binderOpt, System.Func<Syntax.AttributeSyntax, bool> attributeMatchesOpt) Line 293
Symbols.SourceNamedTypeSymbol.GetAttributesBag() Line 460
Symbols.SourceNamedTypeSymbol.GetEarlyDecodedWellKnownAttributeData() Line 507
Symbols.SourceNamedTypeSymbol.NonNullTypes.get() Line 942

Cycle 12 (hit in bootstrap build, fixed in GetNextBaseTypeNoUseSiteDiagnostics passing the ignoreNonNullTypesAttribute for the enum case as well):

Symbols.SourceNamedTypeSymbol.GetAttributesBag() Line 460
Symbols.SourceNamedTypeSymbol.GetEarlyDecodedWellKnownAttributeData() Line 507
Symbols.SourceNamedTypeSymbol.NonNullTypes.get() Line 942
Symbols.SourceNamedTypeSymbol.GetDeclaredBases(Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, bool ignoreNonNullTypesAttribute) Line 229
Symbols.SourceNamedTypeSymbol.GetDeclaredBaseType(Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, bool ignoreNonNullTypesAttribute) Line 243
Symbols.SourceNamedTypeSymbol.MakeAcyclicBaseType(DiagnosticBag diagnostics, bool ignoreNonNullTypesAttribute) Line 626
Symbols.SourceNamedTypeSymbol.GetBaseTypeNoUseSiteDiagnostics(bool ignoreNonNullTypesAttribute) Line 44
Symbols.TypeSymbol.BaseTypeNoUseSiteDiagnostics.get() Line 158
Symbols.TypeSymbolExtensions.GetNextBaseTypeNoUseSiteDiagnostics(Symbols.TypeSymbol type, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, CSharpCompilation compilation, ref PooledObjects.PooledHashSet<Symbols.NamedTypeSymbol> visited, bool ignoreNonNullTypesAttribute) Line 182
Binder.LookupMembersInClass(LookupResult result, Symbols.TypeSymbol type, string name, int arity, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 737
Binder.LookupMembersInType(LookupResult result, Symbols.TypeSymbol type, string name, int arity, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 187
Binder.LookupMembersInternal(LookupResult result, Symbols.NamespaceOrTypeSymbol nsOrType, string name, int arity, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 164
InContainerBinder.LookupSymbolsInSingleBinder(LookupResult result, string name, int arity, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 237
Binder.LookupSymbolsInternal(LookupResult result, string name, int arity, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 94
Binder.LookupSymbolsOrMembersInternal(LookupResult result, Symbols.NamespaceOrTypeSymbol qualifierOpt, string name, int arity, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 126
Binder.LookupAttributeType(LookupResult result, Symbols.NamespaceOrTypeSymbol qualifierOpt, string name, int arity, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 436
Binder.LookupSymbolsSimpleName(LookupResult result, Symbols.NamespaceOrTypeSymbol qualifierOpt, string plainName, int arity, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 34
Binder.BindNonGenericSimpleNamespaceOrTypeOrAliasSymbol(Syntax.IdentifierNameSyntax node, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, bool suppressUseSiteDiagnostics, Symbols.NamespaceOrTypeSymbol qualifierOpt) Line 716
Binder.BindNamespaceOrTypeOrAliasSymbol(Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved, bool suppressUseSiteDiagnostics) Line 381
Binder.BindTypeOrAlias(Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved) Line 271
Binder.BindType(Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<Symbol> basesBeingResolved) Line 251
Binder.BindAttributeTypes(System.Collections.Immutable.ImmutableArray<Binder> binders, System.Collections.Immutable.ImmutableArray<Syntax.AttributeSyntax> attributesToBind, Symbol ownerSymbol, Symbols.NamedTypeSymbol[] boundAttributeTypes, DiagnosticBag diagnostics) Line 45
Symbol.LoadAndValidateAttributes(Roslyn.Utilities.OneOrMany<SyntaxList<Syntax.AttributeListSyntax>> attributesSyntaxLists, ref CustomAttributesBag<Symbols.CSharpAttributeData> lazyCustomAttributesBag, Symbols.AttributeLocation symbolPart, bool earlyDecodingOnly, Binder binderOpt, System.Func<Syntax.AttributeSyntax, bool> attributeMatchesOpt) Line 293
Symbols.SourceNamedTypeSymbol.GetAttributesBag() Line 460

Cycle 13 (and 14 is very closely related):

SourceNamedTypeSymbol.NonNullTypes.get() Line 942
SourceNamedTypeSymbol.GetDeclaredBases(Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, bool ignoreNonNullTypesAttribute) Line 229
SourceNamedTypeSymbol.GetDeclaredInterfaces(Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved) Line 248
SourceNamedTypeSymbol.MakeAcyclicInterfaces(Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, DiagnosticBag diagnostics) Line 575
SourceNamedTypeSymbol.InterfacesNoUseSiteDiagnostics(Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved) Line 69
TypeSymbol.GetInterfaceInfo() Line 90
TypeSymbol.GetAllInterfaces() Line 342
TypeSymbol.AllInterfacesNoUseSiteDiagnostics.get() Line 208
TypeSymbol.AllInterfacesWithDefinitionUseSiteDiagnostics(ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 214
CSharp.Binder.LookupMembersInInterfaceOnly(CSharp.LookupResult current, NamedTypeSymbol type, string name, int arity, CSharp.LookupOptions options, CSharp.Binder originalBinder, TypeSymbol accessThroughType, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 915
CSharp.Binder.LookupMembersInInterface(CSharp.LookupResult current, NamedTypeSymbol type, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, CSharp.LookupOptions options, CSharp.Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 949
CSharp.Binder.LookupMembersInType(CSharp.LookupResult result, TypeSymbol type, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, CSharp.LookupOptions options, CSharp.Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 178
CSharp.Binder.LookupMembersInternal(CSharp.LookupResult result, NamespaceOrTypeSymbol nsOrType, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, CSharp.LookupOptions options, CSharp.Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 164
CSharp.InContainerBinder.LookupSymbolsInSingleBinder(CSharp.LookupResult result, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, CSharp.LookupOptions options, CSharp.Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 237
CSharp.Binder.LookupSymbolsInternal(CSharp.LookupResult result, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, CSharp.LookupOptions options, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 94
CSharp.Binder.LookupSymbolsWithFallback(CSharp.LookupResult result, string name, int arity, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, CSharp.LookupOptions options) Line 61
CSharp.Binder.InvocableNameofInScope() Line 1638
CSharp.Binder.TryBindNameofOperator(CSharp.Syntax.InvocationExpressionSyntax node, DiagnosticBag diagnostics, out CSharp.BoundExpression result) Line 1520
CSharp.Binder.BindInvocationExpression(CSharp.Syntax.InvocationExpressionSyntax node, DiagnosticBag diagnostics) Line 148
CSharp.Binder.BindExpressionInternal(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics, bool invoked, bool indexed) Line 384
CSharp.Binder.BindExpression(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics, bool invoked, bool indexed) Line 329
CSharp.Binder.BindExpression(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics) Line 324
CSharp.Binder.BindSimpleBinaryOperator(CSharp.Syntax.BinaryExpressionSyntax node, DiagnosticBag diagnostics) Line 416
CSharp.Binder.BindExpressionInternal(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics, bool invoked, bool indexed) Line 425
CSharp.Binder.BindExpression(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics, bool invoked, bool indexed) Line 329
CSharp.Binder.BindValue(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics, CSharp.Binder.BindValueKind valueKind) Line 228
CSharp.Binder.BindArgumentExpression(DiagnosticBag diagnostics, CSharp.Syntax.ExpressionSyntax argumentExpression, RefKind refKind, bool allowArglist) Line 2517
CSharp.Binder.BindAttributeArguments(CSharp.Syntax.AttributeArgumentListSyntax attributeArgumentList, NamedTypeSymbol attributeType, DiagnosticBag diagnostics) Line 303
CSharp.Binder.BindAttributeCore(CSharp.Syntax.AttributeSyntax node, NamedTypeSymbol attributeType, DiagnosticBag diagnostics) Line 147
CSharp.Binder.BindAttribute(CSharp.Syntax.AttributeSyntax node, NamedTypeSymbol attributeType, DiagnosticBag diagnostics) Line 105
CSharp.Binder.GetAttribute(CSharp.Syntax.AttributeSyntax node, NamedTypeSymbol boundAttributeType, DiagnosticBag diagnostics) Line 98
CSharp.EarlyWellKnownAttributeBinder.GetAttribute(CSharp.Syntax.AttributeSyntax node, NamedTypeSymbol boundAttributeType, out bool generatedDiagnostics) Line 25
CSharp.Symbol.EarlyDecodeDeprecatedOrExperimentalOrObsoleteAttribute(ref EarlyDecodeWellKnownAttributeArguments<CSharp.EarlyWellKnownAttributeBinder, NamedTypeSymbol, CSharp.Syntax.AttributeSyntax, AttributeLocation> arguments, out CSharpAttributeData attributeData, out ObsoleteAttributeData obsoleteData) Line 170
SourceNamedTypeSymbol.EarlyDecodeWellKnownAttribute(ref EarlyDecodeWellKnownAttributeArguments<CSharp.EarlyWellKnownAttributeBinder, NamedTypeSymbol, CSharp.Syntax.AttributeSyntax, AttributeLocation> arguments) Line 565
CSharp.Symbol.EarlyDecodeWellKnownAttributes(System.Collections.Immutable.ImmutableArray<CSharp.Binder> binders, System.Collections.Immutable.ImmutableArray<NamedTypeSymbol> boundAttributeTypes, System.Collections.Immutable.ImmutableArray<CSharp.Syntax.AttributeSyntax> attributesToBind, AttributeLocation symbolPart, CSharpAttributeData[] boundAttributesBuilder) Line 577
CSharp.Symbol.LoadAndValidateAttributes(Roslyn.Utilities.OneOrMany<SyntaxList<CSharp.Syntax.AttributeListSyntax>> attributesSyntaxLists, ref CustomAttributesBag<CSharpAttributeData> lazyCustomAttributesBag, AttributeLocation symbolPart, bool earlyDecodingOnly, CSharp.Binder binderOpt, System.Func<CSharp.Syntax.AttributeSyntax, bool> attributeMatchesOpt) Line 303
SourceNamedTypeSymbol.GetAttributesBag() Line 460
SourceNamedTypeSymbol.GetEarlyDecodedWellKnownAttributeData() Line 507
SourceNamedTypeSymbol.NonNullTypes.get() Line 942
SourceNamedTypeSymbol.GetDeclaredBases(Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, bool ignoreNonNullTypesAttribute) Line 229

Cycle 15 is when there was in MakeAcyclicBaseType, which would call FindBaseRefSyntax (which calls BindType) to report use-site diagnostics on bases.

Cycle 16 isn't solved yet:



CSharp.Binder.NonNullTypes.get() Line 228
CSharp.Binder.BindNamespaceOrTypeOrAliasSymbol(CSharp.Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved, bool suppressUseSiteDiagnostics) Line 376
CSharp.Binder.BindTypeOrAlias(CSharp.Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved) Line 271
CSharp.Binder.BindType(CSharp.Syntax.ExpressionSyntax syntax, DiagnosticBag diagnostics, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved) Line 251
CSharp.Symbols.SourcePropertySymbol.ComputeType(CSharp.Binder binder,Syntax.BasePropertyDeclarationSyntax syntax, DiagnosticBag diagnostics) Line 1441
CSharp.Symbols.SourcePropertySymbol.SourcePropertySymbol(CSharp.Symbols.SourceMemberContainerTypeSymbol containingType,Binder bodyBinder,Syntax.BasePropertyDeclarationSyntax syntax, string name, Location location, DiagnosticBag diagnostics) Line 241
CSharp.Symbols.SourcePropertySymbol.Create(CSharp.Symbols.SourceMemberContainerTypeSymbol containingType,Binder bodyBinder,Syntax.PropertyDeclarationSyntax syntax, DiagnosticBag diagnostics) Line 458
CSharp.Symbols.SourceMemberContainerTypeSymbol.AddNonTypeMembers(CSharp.Symbols.SourceMemberContainerTypeSymbol.MembersAndInitializersBuilder builder, SyntaxList<CSharp.Syntax.MemberDeclarationSyntax> members, DiagnosticBag diagnostics) Line 3058
CSharp.Symbols.SourceMemberContainerTypeSymbol.AddDeclaredNontypeMembers(CSharp.Symbols.SourceMemberContainerTypeSymbol.MembersAndInitializersBuilder builder, DiagnosticBag diagnostics) Line 2419
CSharp.Symbols.SourceMemberContainerTypeSymbol.BuildMembersAndInitializers(DiagnosticBag diagnostics) Line 2343
CSharp.Symbols.SourceMemberContainerTypeSymbol.GetMembersAndInitializers() Line 1339
CSharp.Symbols.SourceMemberContainerTypeSymbol.GetEarlyAttributeDecodingMembersDictionary() Line 1312
CSharp.Symbols.SourceMemberContainerTypeSymbol.GetEarlyAttributeDecodingMembers(string name) Line 1305
CSharp.Binder.GetCandidateMembers(CSharp.Symbols.NamespaceOrTypeSymbol nsOrType, string name,LookupOptions options,Binder originalBinder) Line 1075
CSharp.Binder.LookupMembersWithoutInheritance(CSharp.LookupResult result,Symbols.TypeSymbol type, string name, int arity,LookupOptions options,Binder originalBinder,Symbols.TypeSymbol accessThroughType, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved) Line 664
CSharp.Binder.LookupMembersInClass(CSharp.LookupResult result,Symbols.TypeSymbol type, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved,LookupOptions options,Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 697
CSharp.Binder.LookupMembersInType(CSharp.LookupResult result,Symbols.TypeSymbol type, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved,LookupOptions options,Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 187
CSharp.Binder.LookupMembersInternal(CSharp.LookupResult result,Symbols.NamespaceOrTypeSymbol nsOrType, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved,LookupOptions options,Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 164
CSharp.InContainerBinder.LookupSymbolsInSingleBinder(CSharp.LookupResult result, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved,LookupOptions options,Binder originalBinder, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 237
CSharp.Binder.LookupSymbolsInternal(CSharp.LookupResult result, string name, int arity, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved,LookupOptions options, bool diagnose, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics) Line 94
CSharp.Binder.LookupSymbolsWithFallback(CSharp.LookupResult result, string name, int arity, ref System.Collections.Generic.HashSet<DiagnosticInfo> useSiteDiagnostics, Roslyn.Utilities.ConsList<CSharp.Symbol> basesBeingResolved,LookupOptions options) Line 61
CSharp.Binder.BindIdentifier(CSharp.Syntax.SimpleNameSyntax node, bool invoked, bool indexed, DiagnosticBag diagnostics) Line 1216
CSharp.Binder.BindLeftOfPotentialColorColorMemberAccess(CSharp.Syntax.ExpressionSyntax left, DiagnosticBag diagnostics) Line 5224
CSharp.Binder.BindMemberAccess(CSharp.Syntax.MemberAccessExpressionSyntax node, bool invoked, bool indexed, DiagnosticBag diagnostics) Line 5172
CSharp.Binder.BindExpressionInternal(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics, bool invoked, bool indexed) Line 402
CSharp.Binder.BindExpression(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics, bool invoked, bool indexed) Line 329
CSharp.Binder.BindValue(CSharp.Syntax.ExpressionSyntax node, DiagnosticBag diagnostics,Binder.BindValueKind valueKind) Line 228
CSharp.Binder.BindArgumentExpression(DiagnosticBag diagnostics,Syntax.ExpressionSyntax argumentExpression, RefKind refKind, bool allowArglist) Line 2517
CSharp.Binder.BindAttributeArguments(CSharp.Syntax.AttributeArgumentListSyntax attributeArgumentList,Symbols.NamedTypeSymbol attributeType, DiagnosticBag diagnostics) Line 303
CSharp.Binder.BindAttributeCore(CSharp.Syntax.AttributeSyntax node,Symbols.NamedTypeSymbol attributeType, DiagnosticBag diagnostics) Line 147
CSharp.Binder.BindAttribute(CSharp.Syntax.AttributeSyntax node,Symbols.NamedTypeSymbol attributeType, DiagnosticBag diagnostics) Line 105
CSharp.Binder.GetAttribute(CSharp.Syntax.AttributeSyntax node,Symbols.NamedTypeSymbol boundAttributeType, DiagnosticBag diagnostics) Line 98
CSharp.EarlyWellKnownAttributeBinder.GetAttribute(CSharp.Syntax.AttributeSyntax node,Symbols.NamedTypeSymbol boundAttributeType, out bool generatedDiagnostics) Line 25
CSharp.Symbols.SourceNamedTypeSymbol.EarlyDecodeWellKnownAttribute(ref EarlyDecodeWellKnownAttributeArguments<CSharp.EarlyWellKnownAttributeBinder,Symbols.NamedTypeSymbol,Syntax.AttributeSyntax,Symbols.AttributeLocation> arguments) Line 577
CSharp.Symbol.EarlyDecodeWellKnownAttributes(System.Collections.Immutable.ImmutableArray<CSharp.Binder> binders, System.Collections.Immutable.ImmutableArray<CSharp.Symbols.NamedTypeSymbol> boundAttributeTypes, System.Collections.Immutable.ImmutableArray<CSharp.Syntax.AttributeSyntax> attributesToBind,Symbols.AttributeLocation symbolPart,Symbols.CSharpAttributeData[] boundAttributesBuilder) Line 577
CSharp.Symbol.LoadAndValidateAttributes(Roslyn.Utilities.OneOrMany<SyntaxList<CSharp.Syntax.AttributeListSyntax>> attributesSyntaxLists, ref CustomAttributesBag<CSharp.Symbols.CSharpAttributeData> lazyCustomAttributesBag,Symbols.AttributeLocation symbolPart, bool earlyDecodingOnly,Binder binderOpt, System.Func<CSharp.Syntax.AttributeSyntax, bool> attributeMatchesOpt) Line 303
CSharp.Symbols.SourceNamedTypeSymbol.GetAttributesBag() Line 460
CSharp.Symbols.SourceNamedTypeSymbol.GetEarlyDecodedWellKnownAttributeData() Line 507
CSharp.Symbols.SourceNamedTypeSymbol.NonNullTypes.get() Line 942
CSharp.Symbols.PropertySymbol.NonNullTypes.get() Line 177
CSharp.Symbols.SourcePropertySymbol.NonNullTypes.get() Line 1519
CSharp.Binder.NonNullTypes.get() Line 228

There was another cycle, but I lost my notes for it. I'll gather the information and add here.

@jcouv jcouv added Area-Compilers PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. Feature - Nullable Reference Types Nullable Reference Types labels Jul 12, 2018
@jcouv jcouv added this to the 16.0 milestone Jul 12, 2018
@jcouv jcouv self-assigned this Jul 12, 2018
@jcouv jcouv requested a review from a team as a code owner July 12, 2018 23:33
Copy link
Contributor

Choose a reason for hiding this comment

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

// Note: we set the BinderFlags.NonNullTypesTrue to break a cycle [](start = 12, length = 65)

Perhaps move the comment to the base() call.

Copy link
Contributor

Choose a reason for hiding this comment

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

Consider removing, or add a placeholder for new parameter.

Copy link
Contributor

Choose a reason for hiding this comment

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

= false [](start = 220, length = 8)

Does not need to be optional.

Copy link
Member

@333fred 333fred Jul 13, 2018

Choose a reason for hiding this comment

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

` [](start = 12, length = 1)

` [](start = 12, length = 1)

Consider using <code> tags instead of markdown. #ByDesign

Copy link
Member

Choose a reason for hiding this comment

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

` [](start = 12, length = 1)

Consider using <code> tags instead of markdown.

@333fred
Copy link
Member

333fred commented Jul 13, 2018

Done review pass (commit 1) #Resolved

@jcouv
Copy link
Member Author

jcouv commented Jul 16, 2018

@cston Bootstrapping build caught a few more cycles for this PR. I'll stop by to discuss the last one (we bind some types in the SourcePropertySymbol constructor). #Resolved

@jcouv
Copy link
Member Author

jcouv commented Jul 21, 2018

I'm going to reset this PR with a simpler change on top of the lazy NonNullTypes.
(For the record, the last commit in this PR before reset is 8934af0)

I'm scrapping this PR a second time. The PR is now built on top of the test changes to related to the default context (#28769).
(For the record, the last commit was 91ab457) #Resolved

Copy link
Contributor

@cston cston Jul 23, 2018

Choose a reason for hiding this comment

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

if (includeNullability && …)? #Resolved

Copy link
Member Author

@jcouv jcouv Jul 23, 2018

Choose a reason for hiding this comment

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

Thanks. Hold off on detailed review. I'm going to rebase this shortly. Also still working on some failing tests.
I'll stop by tomorrow to sync on this PR (solved problems, remaining problems). #Closed

Copy link
Contributor

@cston cston Jul 23, 2018

Choose a reason for hiding this comment

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

if (includeNullability && ...)? #Resolved

@jcouv jcouv removed the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Jul 24, 2018
@jcouv
Copy link
Member Author

jcouv commented Jul 24, 2018

@cston I'm down to 3 compiler tests and a few IDE tests (for some reason). This PR is ready for review :-) #Resolved

@jcouv jcouv requested a review from a team as a code owner July 24, 2018 02:12
@jcouv
Copy link
Member Author

jcouv commented Jul 24, 2018

FYI, I updated OP's description of the various cycles and fixes included in this PR. #Resolved

if (typeSymbol.TypeKind == TypeKind.Array && isNullable.HasValue)


if (typeSymbol.TypeKind == TypeKind.Array)
Copy link
Contributor

@cston cston Jul 24, 2018

Choose a reason for hiding this comment

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

Extra blank line. #Resolved

}


var arrayType = symbol;
Copy link
Contributor

@cston cston Jul 24, 2018

Choose a reason for hiding this comment

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

Extra blank line. #Resolved

}

private void VisitArrayType(IArrayTypeSymbol symbol, bool? isNullable)
private void VisitArrayType(IArrayTypeSymbol symbol, TypeSymbolWithAnnotations isNullable)
Copy link
Contributor

@cston cston Jul 24, 2018

Choose a reason for hiding this comment

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

isNullable [](start = 87, length = 10)

Consider renaming here and in method below. Perhaps typeOpt. #Resolved

private void AddNullableAnnotations(TypeSymbolWithAnnotations isNullable)
{
if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier) &&
!ReferenceEquals(isNullable, null) &&
Copy link
Contributor

@cston cston Jul 24, 2018

Choose a reason for hiding this comment

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

ReferenceEquals(isNullable, null) [](start = 17, length = 33)

Perhaps return early if arg is null. #Resolved

/// <summary>
/// Returns a constructed type given its type arguments.
/// </summary>
/// <param name="nonNullTypesContext">This context indicates how to interprete un-annotated types.</param>
Copy link
Contributor

@cston cston Jul 24, 2018

Choose a reason for hiding this comment

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

interprete [](start = 76, length = 10)

Typo. #Resolved

/// </summary>
[WorkItem(26626, "https://github.com/dotnet/roslyn/issues/26626")]
[Fact]
[Fact(Skip = "PROTOTYPE(NullalbeReferenceTypes): null check on default value temporarily skipped")]
Copy link
Contributor

@cston cston Jul 24, 2018

Choose a reason for hiding this comment

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

Nullalbe [](start = 32, length = 8)

Typo, here and in other tests below. #Resolved

//Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(8, 12));
}

private const string NonNullTypesAttributesDefinition = @"
Copy link
Contributor

@cston cston Jul 24, 2018

Choose a reason for hiding this comment

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

private const [](start = 8, length = 13)

Please move these constants to the top. #Resolved

";


[Fact]
Copy link
Contributor

@cston cston Jul 24, 2018

Choose a reason for hiding this comment

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

Extra blank line. #Resolved

@jcouv
Copy link
Member Author

jcouv commented Jul 24, 2018

@333fred This is ready for another review when you get a chance. Thanks #Resolved

IgnoreDynamicAndTupleNames = IgnoreDynamic | IgnoreTupleNames,
// PROTOTYPE(NullableReferenceTypes): Consider renaming the Nullable options,
// perhaps CompareNullableAnnotations and IgnoreUnknownNullableAnnotations.
// Note: comparisons with nullability-related options pull on NonNullTypes, which can cause cycles.
Copy link
Member

@333fred 333fred Jul 24, 2018

Choose a reason for hiding this comment

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

Consider making this a doc comment #Closed

/// <summary>
/// Append '!' to non-nullable reference types.
/// Note this causes SymbolDisplay to pull on IsNullable and therefore NonNullTypes,
/// so don't use this option in binding, in order to avoid cycles.
Copy link
Member

@333fred 333fred Jul 24, 2018

Choose a reason for hiding this comment

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

Can we add an assert in the binder to verify this? #Resolved

Copy link
Member Author

@jcouv jcouv Jul 24, 2018

Choose a reason for hiding this comment

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

I'm not sure how we could prevent this flag from being used in binder code. #Resolved

var typeSymbol = DynamicTypeDecoder.TransformType(originalEventType, targetSymbolCustomModifierCount, handle, moduleSymbol);
var type = TypeSymbolWithAnnotations.Create(typeSymbol);

// We start without annotations
Copy link
Member

@333fred 333fred Jul 24, 2018

Choose a reason for hiding this comment

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

Might be good to elaborate a bit as to why we start without annotations #Closed

Copy link
Member

Choose a reason for hiding this comment

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

Same for the other similar comments.


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

Debug.Assert(resultType.Equals(destinationType,
TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | // Same object/dynamic and tuple names as destination type.
TypeCompareKind.CompareNullableModifiersForReferenceTypes)); // Same nullability as destination type.
TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds)); // Same object/dynamic and tuple names as destination type.
Copy link
Member

@333fred 333fred Jul 24, 2018

Choose a reason for hiding this comment

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

[](start = 12, length = 3)

Indentation is off. #Resolved

if (!_underlying.TypeSymbol.IsValueType)
{
Debug.Assert(_underlying.IsNullable == false);
//Debug.Assert(_underlying.IsNullable == false);
Copy link
Member

@333fred 333fred Jul 24, 2018

Choose a reason for hiding this comment

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

Are these causing a cycle? If so, consider adding a prototype comment so we don't forget about them #Closed

Copy link
Member Author

@jcouv jcouv Jul 24, 2018

Choose a reason for hiding this comment

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

Yes. We shouldn't call IsNullable (which pulls on NonNullTypes) during binding, which this method is.
I'll remove the commented out code. #Closed

public class NullableReferenceTypesTests : CSharpTestBase
{
private const string NullableAttributeDefinition = @"
private const string NullableAttributeDefinition = @"
Copy link
Member

@333fred 333fred Jul 24, 2018

Choose a reason for hiding this comment

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

[](start = 8, length = 1)

Indentation is off #Closed

@333fred
Copy link
Member

333fred commented Jul 24, 2018

Done review pass (commit 17) #Resolved

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 18)

@jcouv jcouv merged commit 8619362 into dotnet:features/NullableReferenceTypes Jul 25, 2018
@jcouv jcouv deleted the urtann-type branch July 25, 2018 00:05
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