Correct InheritedTheme.captureAll() for multiple theme ancestors of the same type (#39089)

diff --git a/packages/flutter/lib/src/widgets/inherited_theme.dart b/packages/flutter/lib/src/widgets/inherited_theme.dart
index 75d07d4..0704f3d 100644
--- a/packages/flutter/lib/src/widgets/inherited_theme.dart
+++ b/packages/flutter/lib/src/widgets/inherited_theme.dart
@@ -114,10 +114,18 @@
     assert(context != null);
 
     final List<InheritedTheme> themes = <InheritedTheme>[];
+    final Set<Type> themeTypes = <Type>{};
     context.visitAncestorElements((Element ancestor) {
       if (ancestor is InheritedElement && ancestor.widget is InheritedTheme) {
         final InheritedTheme theme = ancestor.widget;
-        themes.add(theme);
+        final Type themeType = theme.runtimeType;
+        // Only remember the first theme of any type. This assumes
+        // that inherited themes completely shadow ancestors of the
+        // the same type.
+        if (!themeTypes.contains(themeType)) {
+          themeTypes.add(themeType);
+          themes.add(theme);
+        }
       }
       return true;
     });
diff --git a/packages/flutter/test/widgets/inherited_theme_test.dart b/packages/flutter/test/widgets/inherited_theme_test.dart
index 1a56cfa..e18b2ac 100644
--- a/packages/flutter/test/widgets/inherited_theme_test.dart
+++ b/packages/flutter/test/widgets/inherited_theme_test.dart
@@ -144,6 +144,111 @@
     expect(getTextStyle('Hello').fontSize, fontSize);
     expect(getIconStyle().color, iconColor);
     expect(getIconStyle().fontSize, iconSize);
+  });
 
+  testWidgets('InheritedTheme.captureAll() multiple IconTheme ancestors', (WidgetTester tester) async {
+    // This is a regression test for https://github.com/flutter/flutter/issues/39087
+
+    const Color outerColor = Color(0xFF0000FF);
+    const Color innerColor = Color(0xFF00FF00);
+    const double iconSize = 48;
+    final Key icon1 = UniqueKey();
+    final Key icon2 = UniqueKey();
+
+    await tester.pumpWidget(
+      WidgetsApp(
+        color: const Color(0xFFFFFFFF),
+        onGenerateRoute: (RouteSettings settings) {
+          return TestRoute(
+            IconTheme(
+              data: const IconThemeData(color: outerColor),
+              child: IconTheme(
+                data: const IconThemeData(size: iconSize, color: innerColor),
+                child: Center(
+                  child: Row(
+                    mainAxisSize: MainAxisSize.min,
+                    children: <Widget>[
+                      Icon(const IconData(0x41, fontFamily: 'Roboto'), key: icon1),
+                      Builder(
+                        builder: (BuildContext context) {
+                          // The same IconThemes are visible from this context
+                          // and the context that the widget returned by captureAll()
+                          // is built in. So only the inner green IconTheme should
+                          // apply to the icon, i.e. both icons will be big and green.
+                          return InheritedTheme.captureAll(
+                            context,
+                            Icon(const IconData(0x41, fontFamily: 'Roboto'), key: icon2),
+                          );
+                        },
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+            ),
+          );
+        },
+      )
+    );
+
+    TextStyle getIconStyle(Key key) {
+      return tester.widget<RichText>(
+        find.descendant(
+          of: find.byKey(key),
+          matching: find.byType(RichText),
+        ),
+      ).text.style;
+    }
+
+    expect(getIconStyle(icon1).color, innerColor);
+    expect(getIconStyle(icon1).fontSize, iconSize);
+    expect(getIconStyle(icon2).color, innerColor);
+    expect(getIconStyle(icon2).fontSize, iconSize);
+  });
+
+  testWidgets('InheritedTheme.captureAll() multiple DefaultTextStyle ancestors', (WidgetTester tester) async {
+    // This is a regression test for https://github.com/flutter/flutter/issues/39087
+
+    const Color textColor = Color(0xFF00FF00);
+
+    await tester.pumpWidget(
+      WidgetsApp(
+        color: const Color(0xFFFFFFFF),
+        onGenerateRoute: (RouteSettings settings) {
+          return TestRoute(
+            DefaultTextStyle(
+              style: const TextStyle(fontSize: 48),
+              child: DefaultTextStyle(
+                style: const TextStyle(color: textColor),
+                child: Row(
+                  children: <Widget>[
+                    const Text('Hello'),
+                    Builder(
+                      builder: (BuildContext context) {
+                        return InheritedTheme.captureAll(context, const Text('World'));
+                      },
+                    ),
+                  ],
+                ),
+              ),
+            ),
+          );
+        },
+      ),
+    );
+
+    TextStyle getTextStyle(String text) {
+      return tester.widget<RichText>(
+        find.descendant(
+          of: find.text(text),
+          matching: find.byType(RichText),
+        ),
+      ).text.style;
+    }
+
+    expect(getTextStyle('Hello').fontSize, null);
+    expect(getTextStyle('Hello').color, textColor);
+    expect(getTextStyle('World').fontSize, null);
+    expect(getTextStyle('World').color, textColor);
   });
 }