Repository: dotnet/roslyn
File: src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs (C#)

Code before:
                canDigThroughNullable: canDigThroughNullable,
                visitCustomModifiers: visitCustomModifiers);
        }

        /// <summary>
        /// Visit the given type and, in the case of compound types, visit all "sub type".
        /// One of the predicates will be invoked at each type. If the type is a
        /// TypeWithAnnotations, <paramref name="typeWithAnnotationsPredicate"/>
        /// will be invoked; otherwise <paramref name="typePredicate"/> will be invoked.
        /// If the corresponding predicate returns true for any type,
        /// traversal stops and that type is returned from this method. Otherwise if traversal
        /// completes without the predicate returning true for any type, this method returns null.
        /// </summary>
        /// <param name="useDefaultType">If true, use <see cref="TypeWithAnnotations.DefaultType"/>
        /// instead of <see cref="TypeWithAnnotations.Type"/> to avoid early resolution of nullable types</param>
        public static TypeSymbol? VisitType<T>(
            this TypeWithAnnotations typeWithAnnotationsOpt,
            TypeSymbol? type,
            Func<TypeWithAnnotations, T, bool, bool>? typeWithAnnotationsPredicate,
            Func<TypeSymbol, T, bool, bool>? typePredicate,
            T arg,
            bool canDigThroughNullable = false,
            bool useDefaultType = false,
            bool visitCustomModifiers = false)
        {
            var matchigSymbols = VisitType(
                typeWithAnnotationsOpt: typeWithAnnotationsOpt,
                type: type,
                typeWithAnnotationsPredicate: typeWithAnnotationsPredicate,
                typePredicate: typePredicate,
                arg: arg,
                returnOnMatch: true,
                canDigThroughNullable: canDigThroughNullable,
                useDefaultType: useDefaultType,
                visitCustomModifiers: visitCustomModifiers);
            return matchigSymbols.FirstOrDefault();
        }

        public static List<TypeSymbol> VisitType<T>(
            this TypeWithAnnotations typeWithAnnotationsOpt,
            TypeSymbol? type,
            Func<TypeWithAnnotations, T, bool, bool>? typeWithAnnotationsPredicate,
            Func<TypeSymbol, T, bool, bool>? typePredicate,
            T arg,
            bool returnOnMatch,
            bool canDigThroughNullable = false,
            bool useDefaultType = false,
            bool visitCustomModifiers = false)
        {
            RoslynDebug.Assert(typeWithAnnotationsOpt.HasType == (type is null));
            RoslynDebug.Assert(canDigThroughNullable == false || useDefaultType == false, "digging through nullable will cause early resolution of nullable types");

Review comment (suggestion):
```suggestion
            var matchingSymbols = VisitType(
```

Code after:
                // Visit containing types from outer-most to inner-most.
                switch (current.TypeKind)
                {
                    case TypeKind.Class:
                    case TypeKind.Struct:
                    case TypeKind.Interface:
                    case TypeKind.Enum:
                    case TypeKind.Delegate:
                        {
                            var containingType = current.ContainingType;
                            if ((object)containingType != null)
                            {
                                isNestedNamedType = true;
                                var result = VisitType(default, containingType, typeWithAnnotationsPredicate, typePredicate, arg, canDigThroughNullable, useDefaultType, visitCustomModifiers);
                                if (result is object)
                                {
                                    return result;
                                }
                            }
                        }
                        break;

                    case TypeKind.Submission:
                        RoslynDebug.Assert((object)current.ContainingType == null);
                        break;
                }

                if (typeWithAnnotationsOpt.HasType && typeWithAnnotationsPredicate != null)
                {
                    if (typeWithAnnotationsPredicate(typeWithAnnotationsOpt, arg, isNestedNamedType))
                    {
                        return current;
                    }
                }
                else if (typePredicate != null)
                {
                    if (typePredicate(current, arg, isNestedNamedType))
                    {
                        return current;
                    }
                }

                if (visitCustomModifiers && typeWithAnnotationsOpt.HasType)
                {
                    foreach (var customModifier in typeWithAnnotationsOpt.CustomModifiers)
                    {
                        var result = VisitType(
                            typeWithAnnotationsOpt: default, type: ((CSharpCustomModifier)customModifier).ModifierSymbol,
                            typeWithAnnotationsPredicate, typePredicate, arg,
                            canDigThroughNullable, useDefaultType, visitCustomModifiers);
                        if (result is object)