private static (bool definitelyManaged, bool hasGenerics) DependsOnDefinitelyManagedType( NamedTypeSymbol type, HashSet <Symbol> partialClosure, ref CompoundUseSiteInfo <AssemblySymbol> useSiteInfo ) { Debug.Assert((object)type != null); var hasGenerics = false; if (partialClosure.Add(type)) { foreach (var member in type.GetInstanceFieldsAndEvents()) { // Only instance fields (including field-like events) affect the outcome. FieldSymbol field; switch (member.Kind) { case SymbolKind.Field: field = (FieldSymbol)member; Debug.Assert( (object)(field.AssociatedSymbol as EventSymbol) == null, "Didn't expect to find a field-like event backing field in the member list." ); break; case SymbolKind.Event: field = ((EventSymbol)member).AssociatedField; break; default: throw ExceptionUtilities.UnexpectedValue(member.Kind); } if ((object)field == null) { continue; } TypeSymbol fieldType = field.NonPointerType(); if (fieldType is null) { // pointers are unmanaged continue; } fieldType.AddUseSiteInfo(ref useSiteInfo); NamedTypeSymbol fieldNamedType = fieldType as NamedTypeSymbol; if ((object)fieldNamedType == null) { if (fieldType.IsManagedType(ref useSiteInfo)) { return(true, hasGenerics); } } else { var result = IsManagedTypeHelper(fieldNamedType); hasGenerics = hasGenerics || result.hasGenerics; // NOTE: don't use ManagedKind.get on a NamedTypeSymbol - that could lead // to infinite recursion. switch (result.isManaged) { case ThreeState.True: return(true, hasGenerics); case ThreeState.False: continue; case ThreeState.Unknown: if (!fieldNamedType.OriginalDefinition.KnownCircularStruct) { var(definitelyManaged, childHasGenerics) = DependsOnDefinitelyManagedType( fieldNamedType, partialClosure, ref useSiteInfo ); hasGenerics = hasGenerics || childHasGenerics; if (definitelyManaged) { return(true, hasGenerics); } } continue; } } } } return(false, hasGenerics); }