diff --git a/examples/api/lib/widgets/slotted_render_object_widget/slotted_multi_child_render_object_widget_mixin.0.dart b/examples/api/lib/widgets/slotted_render_object_widget/slotted_multi_child_render_object_widget_mixin.0.dart
deleted file mode 100644
index 217544b..0000000
--- a/examples/api/lib/widgets/slotted_render_object_widget/slotted_multi_child_render_object_widget_mixin.0.dart
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-
-/// Slots used for the children of [Diagonal] and [RenderDiagonal].
-enum DiagonalSlot {
-  topLeft,
-  bottomRight,
-}
-
-/// A widget that demonstrates the usage of [SlottedMultiChildRenderObjectWidgetMixin]
-/// by providing slots for two children that will be arranged diagonally.
-class Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<DiagonalSlot> {
-  const Diagonal({
-    Key? key,
-    this.topLeft,
-    this.bottomRight,
-    this.backgroundColor,
-  }) : super(key: key);
-
-  final Widget? topLeft;
-  final Widget? bottomRight;
-  final Color? backgroundColor;
-
-  @override
-  Iterable<DiagonalSlot> get slots => DiagonalSlot.values;
-
-  @override
-  Widget? childForSlot(DiagonalSlot slot) {
-    switch (slot) {
-      case DiagonalSlot.topLeft:
-        return topLeft;
-      case DiagonalSlot.bottomRight:
-        return bottomRight;
-    }
-  }
-
-  // The [createRenderObject] and [updateRenderObject] methods configure the
-  // [RenderObject] backing this widget with the configuration of the widget.
-  // They do not need to do anything with the children of the widget, though.
-  // The children of the widget are automatically configured on the
-  // [RenderObject] by [SlottedRenderObjectElement.mount] and
-  // [SlottedRenderObjectElement.update].
-
-  @override
-  SlottedContainerRenderObjectMixin<DiagonalSlot> createRenderObject(
-    BuildContext context,
-  ) {
-    return RenderDiagonal(
-      backgroundColor: backgroundColor,
-    );
-  }
-
-  @override
-  void updateRenderObject(
-    BuildContext context,
-    SlottedContainerRenderObjectMixin<DiagonalSlot> renderObject,
-  ) {
-    (renderObject as RenderDiagonal).backgroundColor = backgroundColor;
-  }
-}
-
-/// A render object that demonstrates the usage of [SlottedContainerRenderObjectMixin]
-/// by providing slots for two children that will be arranged diagonally.
-class RenderDiagonal extends RenderBox with SlottedContainerRenderObjectMixin<DiagonalSlot>, DebugOverflowIndicatorMixin {
-  RenderDiagonal({Color? backgroundColor}) : _backgroundColor = backgroundColor;
-
-  // Getters and setters to configure the [RenderObject] with the configuration
-  // of the [Widget]. These mostly contain boilerplate code, but depending on
-  // where the configuration value is used, the setter has to call
-  // [markNeedsLayout], [markNeedsPaint], or [markNeedsSemanticsUpdate].
-  Color? get backgroundColor => _backgroundColor;
-  Color? _backgroundColor;
-  set backgroundColor(Color? value) {
-    assert(value != null);
-    if (_backgroundColor == value) {
-      return;
-    }
-    _backgroundColor = value;
-    markNeedsPaint();
-  }
-
-  // Getters to simplify accessing the slotted children.
-  RenderBox? get _topLeft => childForSlot(DiagonalSlot.topLeft);
-  RenderBox? get _bottomRight => childForSlot(DiagonalSlot.bottomRight);
-
-  // The size this render object would have if the incoming constraints were
-  // unconstrained; calculated during performLayout used during paint for an
-  // assertion that checks for unintended overflow.
-  late Size _childrenSize;
-
-  // Returns children in hit test order.
-  @override
-  Iterable<RenderBox> get children sync* {
-    if (_topLeft != null) {
-      yield _topLeft!;
-    }
-    if (_bottomRight != null) {
-      yield _bottomRight!;
-    }
-  }
-
-  // LAYOUT
-
-  @override
-  void performLayout() {
-    // Children are allowed to be as big as they want (= unconstrained).
-    const BoxConstraints childConstraints = BoxConstraints();
-
-    // Lay out the top left child and position it at offset zero.
-    Size topLeftSize = Size.zero;
-    final RenderBox? topLeft = _topLeft;
-    if (topLeft != null) {
-      topLeft.layout(childConstraints, parentUsesSize: true);
-      _positionChild(topLeft, Offset.zero);
-      topLeftSize = topLeft.size;
-    }
-
-    // Lay out the bottom right child and position it at the bottom right corner
-    // of the top left child.
-    Size bottomRightSize = Size.zero;
-    final RenderBox? bottomRight = _bottomRight;
-    if (bottomRight != null) {
-      bottomRight.layout(childConstraints, parentUsesSize: true);
-      _positionChild(
-        bottomRight,
-        Offset(topLeftSize.width, topLeftSize.height),
-      );
-      bottomRightSize = bottomRight.size;
-    }
-
-    // Calculate the overall size and constrain it to the given constraints.
-    // Any overflow is marked (in debug mode) during paint.
-    _childrenSize = Size(
-      topLeftSize.width + bottomRightSize.width,
-      topLeftSize.height + bottomRightSize.height,
-    );
-    size = constraints.constrain(_childrenSize);
-  }
-
-  void _positionChild(RenderBox child, Offset offset) {
-    (child.parentData! as BoxParentData).offset = offset;
-  }
-
-  // PAINT
-
-  @override
-  void paint(PaintingContext context, Offset offset) {
-    // Paint the background.
-    if (backgroundColor != null) {
-      context.canvas.drawRect(
-        offset & size,
-        Paint()
-          ..color = backgroundColor!,
-      );
-    }
-
-    void paintChild(RenderBox child, PaintingContext context, Offset offset) {
-      final BoxParentData childParentData = child.parentData! as BoxParentData;
-      context.paintChild(child, childParentData.offset + offset);
-    }
-
-    // Paint the children at the offset calculated during layout.
-    final RenderBox? topLeft = _topLeft;
-    if (topLeft != null) {
-      paintChild(topLeft, context, offset);
-    }
-    final RenderBox? bottomRight = _bottomRight;
-    if (bottomRight != null) {
-      paintChild(bottomRight, context, offset);
-    }
-
-    // Paint an overflow indicator in debug mode if the children want to be
-    // larger than the incoming constraints allow.
-    assert(() {
-      paintOverflowIndicator(
-        context,
-        offset,
-        Offset.zero & size,
-        Offset.zero & _childrenSize,
-      );
-      return true;
-    }());
-  }
-
-  // HIT TEST
-
-  @override
-  bool hitTestChildren(BoxHitTestResult result, { required Offset position }) {
-    for (final RenderBox child in children) {
-      final BoxParentData parentData = child.parentData! as BoxParentData;
-      final bool isHit = result.addWithPaintOffset(
-        offset: parentData.offset,
-        position: position,
-        hitTest: (BoxHitTestResult result, Offset transformed) {
-          assert(transformed == position - parentData.offset);
-          return child.hitTest(result, position: transformed);
-        },
-      );
-      if (isHit) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  // INTRINSICS
-
-  // Incoming height/width are ignored as children are always laid out unconstrained.
-
-  @override
-  double computeMinIntrinsicWidth(double height) {
-    final double topLeftWidth = _topLeft?.getMinIntrinsicWidth(double.infinity) ?? 0;
-    final double bottomRightWith = _bottomRight?.getMinIntrinsicWidth(double.infinity) ?? 0;
-    return topLeftWidth + bottomRightWith;
-  }
-
-  @override
-  double computeMaxIntrinsicWidth(double height) {
-    final double topLeftWidth = _topLeft?.getMaxIntrinsicWidth(double.infinity) ?? 0;
-    final double bottomRightWith = _bottomRight?.getMaxIntrinsicWidth(double.infinity) ?? 0;
-    return topLeftWidth + bottomRightWith;  }
-
-  @override
-  double computeMinIntrinsicHeight(double width) {
-    final double topLeftHeight = _topLeft?.getMinIntrinsicHeight(double.infinity) ?? 0;
-    final double bottomRightHeight = _bottomRight?.getMinIntrinsicHeight(double.infinity) ?? 0;
-    return topLeftHeight + bottomRightHeight;
-  }
-
-  @override
-  double computeMaxIntrinsicHeight(double width) {
-    final double topLeftHeight = _topLeft?.getMaxIntrinsicHeight(double.infinity) ?? 0;
-    final double bottomRightHeight = _bottomRight?.getMaxIntrinsicHeight(double.infinity) ?? 0;
-    return topLeftHeight + bottomRightHeight;
-  }
-
-  @override
-  Size computeDryLayout(BoxConstraints constraints) {
-    const BoxConstraints childConstraints = BoxConstraints();
-    final Size topLeftSize = _topLeft?.computeDryLayout(childConstraints) ?? Size.zero;
-    final Size bottomRightSize = _bottomRight?.computeDryLayout(childConstraints) ?? Size.zero;
-    return constraints.constrain(Size(
-      topLeftSize.width + bottomRightSize.width,
-      topLeftSize.height + bottomRightSize.height,
-    ));
-  }
-}
-
-class ExampleWidget extends StatelessWidget {
-  const ExampleWidget({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return MaterialApp(
-      home: Scaffold(
-        appBar: AppBar(title: const Text('Slotted RenderObject Example')),
-        body: Center(
-          child: Diagonal(
-            topLeft: Container(
-              color: Colors.green,
-              height: 100,
-              width: 200,
-              child: const Center(
-                child: Text('topLeft'),
-              ),
-            ),
-            bottomRight: Container(
-              color: Colors.yellow,
-              height: 60,
-              width: 30,
-              child: const Center(
-                child: Text('bottomRight'),
-              ),
-            ),
-            backgroundColor: Colors.blue,
-          ),
-        ),
-      ),
-    );
-  }
-}
-
-void main() {
-  runApp(const ExampleWidget());
-}
diff --git a/examples/api/test/widgets/slotted_render_object_widget/slotted_multi_child_render_object_widget_mixin.0_test.dart b/examples/api/test/widgets/slotted_render_object_widget/slotted_multi_child_render_object_widget_mixin.0_test.dart
deleted file mode 100644
index 150d9e5..0000000
--- a/examples/api/test/widgets/slotted_render_object_widget/slotted_multi_child_render_object_widget_mixin.0_test.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:flutter/widgets.dart';
-import 'package:flutter_api_samples/widgets/slotted_render_object_widget/slotted_multi_child_render_object_widget_mixin.0.dart' as example;
-import 'package:flutter_test/flutter_test.dart';
-
-void main() {
-  testWidgets('shows two widgets arranged diagonally', (WidgetTester tester) async {
-    await tester.pumpWidget(
-      const example.ExampleWidget(),
-    );
-
-    expect(find.text('topLeft'), findsOneWidget);
-    expect(find.text('bottomRight'), findsOneWidget);
-
-    expect(
-      tester.getBottomRight(findContainerWithText('topLeft')),
-      tester.getTopLeft(findContainerWithText('bottomRight')),
-    );
-
-    expect(
-      tester.getSize(findContainerWithText('topLeft')),
-      const Size(200, 100),
-    );
-    expect(
-      tester.getSize(findContainerWithText('bottomRight')),
-      const Size(30, 60),
-    );
-
-    expect(
-      tester.getSize(find.byType(example.Diagonal)),
-      const Size(200 + 30, 100 + 60),
-    );
-  });
-}
-
-Finder findContainerWithText(String text) {
-  return find.ancestor(of: find.text(text), matching: find.byType(Container));
-}
diff --git a/packages/flutter/lib/src/material/chip.dart b/packages/flutter/lib/src/material/chip.dart
index b720b85..82ff6c2 100644
--- a/packages/flutter/lib/src/material/chip.dart
+++ b/packages/flutter/lib/src/material/chip.dart
@@ -2059,7 +2059,7 @@
   }
 }
 
-class _ChipRenderWidget extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_ChipSlot> {
+class _ChipRenderWidget extends RenderObjectWidget {
   const _ChipRenderWidget({
     Key? key,
     required this.theme,
@@ -2083,19 +2083,7 @@
   final ShapeBorder? avatarBorder;
 
   @override
-  Iterable<_ChipSlot> get slots => _ChipSlot.values;
-
-  @override
-  Widget? childForSlot(_ChipSlot slot) {
-    switch (slot) {
-      case _ChipSlot.label:
-        return theme.label;
-      case _ChipSlot.avatar:
-        return theme.avatar;
-      case _ChipSlot.deleteIcon:
-        return theme.deleteIcon;
-    }
-  }
+  _RenderChipElement createElement() => _RenderChipElement(this);
 
   @override
   void updateRenderObject(BuildContext context, _RenderChip renderObject) {
@@ -2112,7 +2100,7 @@
   }
 
   @override
-  SlottedContainerRenderObjectMixin<_ChipSlot> createRenderObject(BuildContext context) {
+  RenderObject createRenderObject(BuildContext context) {
     return _RenderChip(
       theme: theme,
       textDirection: Directionality.of(context),
@@ -2133,6 +2121,105 @@
   deleteIcon,
 }
 
+class _RenderChipElement extends RenderObjectElement {
+  _RenderChipElement(_ChipRenderWidget chip) : super(chip);
+
+  final Map<_ChipSlot, Element> slotToChild = <_ChipSlot, Element>{};
+
+  @override
+  _ChipRenderWidget get widget => super.widget as _ChipRenderWidget;
+
+  @override
+  _RenderChip get renderObject => super.renderObject as _RenderChip;
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    slotToChild.values.forEach(visitor);
+  }
+
+  @override
+  void forgetChild(Element child) {
+    assert(slotToChild.containsValue(child));
+    assert(child.slot is _ChipSlot);
+    assert(slotToChild.containsKey(child.slot));
+    slotToChild.remove(child.slot);
+    super.forgetChild(child);
+  }
+
+  void _mountChild(Widget widget, _ChipSlot slot) {
+    final Element? oldChild = slotToChild[slot];
+    final Element? newChild = updateChild(oldChild, widget, slot);
+    if (oldChild != null) {
+      slotToChild.remove(slot);
+    }
+    if (newChild != null) {
+      slotToChild[slot] = newChild;
+    }
+  }
+
+  @override
+  void mount(Element? parent, Object? newSlot) {
+    super.mount(parent, newSlot);
+    _mountChild(widget.theme.avatar, _ChipSlot.avatar);
+    _mountChild(widget.theme.deleteIcon, _ChipSlot.deleteIcon);
+    _mountChild(widget.theme.label, _ChipSlot.label);
+  }
+
+  void _updateChild(Widget widget, _ChipSlot slot) {
+    final Element? oldChild = slotToChild[slot];
+    final Element? newChild = updateChild(oldChild, widget, slot);
+    if (oldChild != null) {
+      slotToChild.remove(slot);
+    }
+    if (newChild != null) {
+      slotToChild[slot] = newChild;
+    }
+  }
+
+  @override
+  void update(_ChipRenderWidget newWidget) {
+    super.update(newWidget);
+    assert(widget == newWidget);
+    _updateChild(widget.theme.label, _ChipSlot.label);
+    _updateChild(widget.theme.avatar, _ChipSlot.avatar);
+    _updateChild(widget.theme.deleteIcon, _ChipSlot.deleteIcon);
+  }
+
+  void _updateRenderObject(RenderObject? child, _ChipSlot slot) {
+    switch (slot) {
+      case _ChipSlot.avatar:
+        renderObject.avatar = child as RenderBox?;
+        break;
+      case _ChipSlot.label:
+        renderObject.label = child as RenderBox?;
+        break;
+      case _ChipSlot.deleteIcon:
+        renderObject.deleteIcon = child as RenderBox?;
+        break;
+    }
+  }
+
+  @override
+  void insertRenderObjectChild(RenderObject child, _ChipSlot slot) {
+    assert(child is RenderBox);
+    _updateRenderObject(child, slot);
+    assert(renderObject.children.keys.contains(slot));
+  }
+
+  @override
+  void removeRenderObjectChild(RenderObject child, _ChipSlot slot) {
+    assert(child is RenderBox);
+    assert(renderObject.children[slot] == child);
+    _updateRenderObject(null, slot);
+    assert(!renderObject.children.keys.contains(slot));
+  }
+
+  @override
+  void moveRenderObjectChild(RenderObject child, Object? oldSlot, Object? newSlot) {
+    assert(false, 'not reachable');
+  }
+}
+
 @immutable
 class _ChipRenderTheme {
   const _ChipRenderTheme({
@@ -2199,7 +2286,7 @@
   }
 }
 
-class _RenderChip extends RenderBox with SlottedContainerRenderObjectMixin<_ChipSlot> {
+class _RenderChip extends RenderBox {
   _RenderChip({
     required _ChipRenderTheme theme,
     required TextDirection textDirection,
@@ -2220,6 +2307,8 @@
     enableAnimation.addListener(markNeedsPaint);
   }
 
+  final Map<_ChipSlot, RenderBox> children = <_ChipSlot, RenderBox>{};
+
   bool? value;
   bool? isEnabled;
   late Rect _deleteButtonRect;
@@ -2230,9 +2319,35 @@
   Animation<double> enableAnimation;
   ShapeBorder? avatarBorder;
 
-  RenderBox? get avatar => childForSlot(_ChipSlot.avatar);
-  RenderBox? get deleteIcon => childForSlot(_ChipSlot.deleteIcon);
-  RenderBox? get label => childForSlot(_ChipSlot.label);
+  RenderBox? _updateChild(RenderBox? oldChild, RenderBox? newChild, _ChipSlot slot) {
+    if (oldChild != null) {
+      dropChild(oldChild);
+      children.remove(slot);
+    }
+    if (newChild != null) {
+      children[slot] = newChild;
+      adoptChild(newChild);
+    }
+    return newChild;
+  }
+
+  RenderBox? _avatar;
+  RenderBox? get avatar => _avatar;
+  set avatar(RenderBox? value) {
+    _avatar = _updateChild(_avatar, value, _ChipSlot.avatar);
+  }
+
+  RenderBox? _deleteIcon;
+  RenderBox? get deleteIcon => _deleteIcon;
+  set deleteIcon(RenderBox? value) {
+    _deleteIcon = _updateChild(_deleteIcon, value, _ChipSlot.deleteIcon);
+  }
+
+  RenderBox? _label;
+  RenderBox? get label => _label;
+  set label(RenderBox? value) {
+    _label = _updateChild(_label, value, _ChipSlot.label);
+  }
 
   _ChipRenderTheme get theme => _theme;
   _ChipRenderTheme _theme;
@@ -2255,8 +2370,7 @@
   }
 
   // The returned list is ordered for hit testing.
-  @override
-  Iterable<RenderBox> get children sync* {
+  Iterable<RenderBox> get _children sync* {
     if (avatar != null) {
       yield avatar!;
     }
@@ -2272,6 +2386,47 @@
   bool get deleteIconShowing => !deleteDrawerAnimation.isDismissed;
 
   @override
+  void attach(PipelineOwner owner) {
+    super.attach(owner);
+    for (final RenderBox child in _children) {
+      child.attach(owner);
+    }
+  }
+
+  @override
+  void detach() {
+    super.detach();
+    for (final RenderBox child in _children) {
+      child.detach();
+    }
+  }
+
+  @override
+  void redepthChildren() {
+    _children.forEach(redepthChild);
+  }
+
+  @override
+  void visitChildren(RenderObjectVisitor visitor) {
+    _children.forEach(visitor);
+  }
+
+  @override
+  List<DiagnosticsNode> debugDescribeChildren() {
+    final List<DiagnosticsNode> value = <DiagnosticsNode>[];
+    void add(RenderBox? child, String name) {
+      if (child != null) {
+        value.add(child.toDiagnosticsNode(name: name));
+      }
+    }
+
+    add(avatar, 'avatar');
+    add(label, 'label');
+    add(deleteIcon, 'deleteIcon');
+    return value;
+  }
+
+  @override
   bool get sizedByParent => false;
 
   static double _minWidth(RenderBox? box, double height) {
diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart
index 7e9d5e9..ba9d7ec 100644
--- a/packages/flutter/lib/src/material/input_decorator.dart
+++ b/packages/flutter/lib/src/material/input_decorator.dart
@@ -682,7 +682,7 @@
 }
 
 // The workhorse: layout and paint a _Decorator widget's _Decoration.
-class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin<_DecorationSlot> {
+class _RenderDecoration extends RenderBox {
   _RenderDecoration({
     required _Decoration decoration,
     required TextDirection textDirection,
@@ -702,22 +702,88 @@
        _expands = expands;
 
   static const double subtextGap = 8.0;
+  final Map<_DecorationSlot, RenderBox> children = <_DecorationSlot, RenderBox>{};
 
-  RenderBox? get icon => childForSlot(_DecorationSlot.icon);
-  RenderBox? get input => childForSlot(_DecorationSlot.input);
-  RenderBox? get label => childForSlot(_DecorationSlot.label);
-  RenderBox? get hint => childForSlot(_DecorationSlot.hint);
-  RenderBox? get prefix => childForSlot(_DecorationSlot.prefix);
-  RenderBox? get suffix => childForSlot(_DecorationSlot.suffix);
-  RenderBox? get prefixIcon => childForSlot(_DecorationSlot.prefixIcon);
-  RenderBox? get suffixIcon => childForSlot(_DecorationSlot.suffixIcon);
-  RenderBox? get helperError => childForSlot(_DecorationSlot.helperError);
-  RenderBox? get counter => childForSlot(_DecorationSlot.counter);
-  RenderBox? get container => childForSlot(_DecorationSlot.container);
+  RenderBox? _updateChild(RenderBox? oldChild, RenderBox? newChild, _DecorationSlot slot) {
+    if (oldChild != null) {
+      dropChild(oldChild);
+      children.remove(slot);
+    }
+    if (newChild != null) {
+      children[slot] = newChild;
+      adoptChild(newChild);
+    }
+    return newChild;
+  }
+
+  RenderBox? _icon;
+  RenderBox? get icon => _icon;
+  set icon(RenderBox? value) {
+    _icon = _updateChild(_icon, value, _DecorationSlot.icon);
+  }
+
+  RenderBox? _input;
+  RenderBox? get input => _input;
+  set input(RenderBox? value) {
+    _input = _updateChild(_input, value, _DecorationSlot.input);
+  }
+
+  RenderBox? _label;
+  RenderBox? get label => _label;
+  set label(RenderBox? value) {
+    _label = _updateChild(_label, value, _DecorationSlot.label);
+  }
+
+  RenderBox? _hint;
+  RenderBox? get hint => _hint;
+  set hint(RenderBox? value) {
+    _hint = _updateChild(_hint, value, _DecorationSlot.hint);
+  }
+
+  RenderBox? _prefix;
+  RenderBox? get prefix => _prefix;
+  set prefix(RenderBox? value) {
+    _prefix = _updateChild(_prefix, value, _DecorationSlot.prefix);
+  }
+
+  RenderBox? _suffix;
+  RenderBox? get suffix => _suffix;
+  set suffix(RenderBox? value) {
+    _suffix = _updateChild(_suffix, value, _DecorationSlot.suffix);
+  }
+
+  RenderBox? _prefixIcon;
+  RenderBox? get prefixIcon => _prefixIcon;
+  set prefixIcon(RenderBox? value) {
+    _prefixIcon = _updateChild(_prefixIcon, value, _DecorationSlot.prefixIcon);
+  }
+
+  RenderBox? _suffixIcon;
+  RenderBox? get suffixIcon => _suffixIcon;
+  set suffixIcon(RenderBox? value) {
+    _suffixIcon = _updateChild(_suffixIcon, value, _DecorationSlot.suffixIcon);
+  }
+
+  RenderBox? _helperError;
+  RenderBox? get helperError => _helperError;
+  set helperError(RenderBox? value) {
+    _helperError = _updateChild(_helperError, value, _DecorationSlot.helperError);
+  }
+
+  RenderBox? _counter;
+  RenderBox? get counter => _counter;
+  set counter(RenderBox? value) {
+    _counter = _updateChild(_counter, value, _DecorationSlot.counter);
+  }
+
+  RenderBox? _container;
+  RenderBox? get container => _container;
+  set container(RenderBox? value) {
+    _container = _updateChild(_container, value, _DecorationSlot.container);
+  }
 
   // The returned list is ordered for hit testing.
-  @override
-  Iterable<RenderBox> get children sync* {
+  Iterable<RenderBox> get _children sync* {
     if (icon != null)
       yield icon!;
     if (input != null)
@@ -817,6 +883,30 @@
   }
 
   @override
+  void attach(PipelineOwner owner) {
+    super.attach(owner);
+    for (final RenderBox child in _children)
+      child.attach(owner);
+  }
+
+  @override
+  void detach() {
+    super.detach();
+    for (final RenderBox child in _children)
+      child.detach();
+  }
+
+  @override
+  void redepthChildren() {
+    _children.forEach(redepthChild);
+  }
+
+  @override
+  void visitChildren(RenderObjectVisitor visitor) {
+    _children.forEach(visitor);
+  }
+
+  @override
   void visitChildrenForSemantics(RenderObjectVisitor visitor) {
     if (icon != null)
       visitor(icon!);
@@ -851,6 +941,27 @@
   }
 
   @override
+  List<DiagnosticsNode> debugDescribeChildren() {
+    final List<DiagnosticsNode> value = <DiagnosticsNode>[];
+    void add(RenderBox? child, String name) {
+      if (child != null)
+        value.add(child.toDiagnosticsNode(name: name));
+    }
+    add(icon, 'icon');
+    add(input, 'input');
+    add(label, 'label');
+    add(hint, 'hint');
+    add(prefix, 'prefix');
+    add(suffix, 'suffix');
+    add(prefixIcon, 'prefixIcon');
+    add(suffixIcon, 'suffixIcon');
+    add(helperError, 'helperError');
+    add(counter, 'counter');
+    add(container, 'container');
+    return value;
+  }
+
+  @override
   bool get sizedByParent => false;
 
   static double _minWidth(RenderBox? box, double height) {
@@ -1527,7 +1638,7 @@
   @override
   bool hitTestChildren(BoxHitTestResult result, { required Offset position }) {
     assert(position != null);
-    for (final RenderBox child in children) {
+    for (final RenderBox child in _children) {
       // The label must be handled specially since we've transformed it.
       final Offset offset = _boxParentData(child).offset;
       final bool isHit = result.addWithPaintOffset(
@@ -1556,7 +1667,146 @@
   }
 }
 
-class _Decorator extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_DecorationSlot> {
+class _DecorationElement extends RenderObjectElement {
+  _DecorationElement(_Decorator widget) : super(widget);
+
+  final Map<_DecorationSlot, Element> slotToChild = <_DecorationSlot, Element>{};
+
+  @override
+  _Decorator get widget => super.widget as _Decorator;
+
+  @override
+  _RenderDecoration get renderObject => super.renderObject as _RenderDecoration;
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    slotToChild.values.forEach(visitor);
+  }
+
+  @override
+  void forgetChild(Element child) {
+    assert(slotToChild.containsValue(child));
+    assert(child.slot is _DecorationSlot);
+    assert(slotToChild.containsKey(child.slot));
+    slotToChild.remove(child.slot);
+    super.forgetChild(child);
+  }
+
+  void _mountChild(Widget? widget, _DecorationSlot slot) {
+    final Element? oldChild = slotToChild[slot];
+    final Element? newChild = updateChild(oldChild, widget, slot);
+    if (oldChild != null) {
+      slotToChild.remove(slot);
+    }
+    if (newChild != null) {
+      slotToChild[slot] = newChild;
+    }
+  }
+
+  @override
+  void mount(Element? parent, Object? newSlot) {
+    super.mount(parent, newSlot);
+    _mountChild(widget.decoration.icon, _DecorationSlot.icon);
+    _mountChild(widget.decoration.input, _DecorationSlot.input);
+    _mountChild(widget.decoration.label, _DecorationSlot.label);
+    _mountChild(widget.decoration.hint, _DecorationSlot.hint);
+    _mountChild(widget.decoration.prefix, _DecorationSlot.prefix);
+    _mountChild(widget.decoration.suffix, _DecorationSlot.suffix);
+    _mountChild(widget.decoration.prefixIcon, _DecorationSlot.prefixIcon);
+    _mountChild(widget.decoration.suffixIcon, _DecorationSlot.suffixIcon);
+    _mountChild(widget.decoration.helperError, _DecorationSlot.helperError);
+    _mountChild(widget.decoration.counter, _DecorationSlot.counter);
+    _mountChild(widget.decoration.container, _DecorationSlot.container);
+  }
+
+  void _updateChild(Widget? widget, _DecorationSlot slot) {
+    final Element? oldChild = slotToChild[slot];
+    final Element? newChild = updateChild(oldChild, widget, slot);
+    if (oldChild != null) {
+      slotToChild.remove(slot);
+    }
+    if (newChild != null) {
+      slotToChild[slot] = newChild;
+    }
+  }
+
+  @override
+  void update(_Decorator newWidget) {
+    super.update(newWidget);
+    assert(widget == newWidget);
+    _updateChild(widget.decoration.icon, _DecorationSlot.icon);
+    _updateChild(widget.decoration.input, _DecorationSlot.input);
+    _updateChild(widget.decoration.label, _DecorationSlot.label);
+    _updateChild(widget.decoration.hint, _DecorationSlot.hint);
+    _updateChild(widget.decoration.prefix, _DecorationSlot.prefix);
+    _updateChild(widget.decoration.suffix, _DecorationSlot.suffix);
+    _updateChild(widget.decoration.prefixIcon, _DecorationSlot.prefixIcon);
+    _updateChild(widget.decoration.suffixIcon, _DecorationSlot.suffixIcon);
+    _updateChild(widget.decoration.helperError, _DecorationSlot.helperError);
+    _updateChild(widget.decoration.counter, _DecorationSlot.counter);
+    _updateChild(widget.decoration.container, _DecorationSlot.container);
+  }
+
+  void _updateRenderObject(RenderBox? child, _DecorationSlot slot) {
+    switch (slot) {
+      case _DecorationSlot.icon:
+        renderObject.icon = child;
+        break;
+      case _DecorationSlot.input:
+        renderObject.input = child;
+        break;
+      case _DecorationSlot.label:
+        renderObject.label = child;
+        break;
+      case _DecorationSlot.hint:
+        renderObject.hint = child;
+        break;
+      case _DecorationSlot.prefix:
+        renderObject.prefix = child;
+        break;
+      case _DecorationSlot.suffix:
+        renderObject.suffix = child;
+        break;
+      case _DecorationSlot.prefixIcon:
+        renderObject.prefixIcon = child;
+        break;
+      case _DecorationSlot.suffixIcon:
+        renderObject.suffixIcon = child;
+        break;
+      case _DecorationSlot.helperError:
+        renderObject.helperError = child;
+        break;
+      case _DecorationSlot.counter:
+        renderObject.counter = child;
+        break;
+      case _DecorationSlot.container:
+        renderObject.container = child;
+        break;
+    }
+  }
+
+  @override
+  void insertRenderObjectChild(RenderObject child, _DecorationSlot slot) {
+    assert(child is RenderBox);
+    _updateRenderObject(child as RenderBox, slot);
+    assert(renderObject.children.keys.contains(slot));
+  }
+
+  @override
+  void removeRenderObjectChild(RenderObject child, _DecorationSlot slot) {
+    assert(child is RenderBox);
+    assert(renderObject.children[slot] == child);
+    _updateRenderObject(null, slot);
+    assert(!renderObject.children.keys.contains(slot));
+  }
+
+  @override
+  void moveRenderObjectChild(RenderObject child, Object? oldSlot, Object? newSlot) {
+    assert(false, 'not reachable');
+  }
+}
+
+class _Decorator extends RenderObjectWidget {
   const _Decorator({
     Key? key,
     required this.textAlignVertical,
@@ -1579,35 +1829,7 @@
   final bool expands;
 
   @override
-  Iterable<_DecorationSlot> get slots => _DecorationSlot.values;
-
-  @override
-  Widget? childForSlot(_DecorationSlot slot) {
-    switch (slot) {
-      case _DecorationSlot.icon:
-        return decoration.icon;
-      case _DecorationSlot.input:
-        return decoration.input;
-      case _DecorationSlot.label:
-        return decoration.label;
-      case _DecorationSlot.hint:
-        return decoration.hint;
-      case _DecorationSlot.prefix:
-        return decoration.prefix;
-      case _DecorationSlot.suffix:
-        return decoration.suffix;
-      case _DecorationSlot.prefixIcon:
-        return decoration.prefixIcon;
-      case _DecorationSlot.suffixIcon:
-        return decoration.suffixIcon;
-      case _DecorationSlot.helperError:
-        return decoration.helperError;
-      case _DecorationSlot.counter:
-        return decoration.counter;
-      case _DecorationSlot.container:
-        return decoration.container;
-    }
-  }
+  _DecorationElement createElement() => _DecorationElement(this);
 
   @override
   _RenderDecoration createRenderObject(BuildContext context) {
diff --git a/packages/flutter/lib/src/material/list_tile.dart b/packages/flutter/lib/src/material/list_tile.dart
index 87a3c11..1c68b55 100644
--- a/packages/flutter/lib/src/material/list_tile.dart
+++ b/packages/flutter/lib/src/material/list_tile.dart
@@ -1266,7 +1266,7 @@
   trailing,
 }
 
-class _ListTile extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_ListTileSlot> {
+class _ListTile extends RenderObjectWidget {
   const _ListTile({
     Key? key,
     this.leading,
@@ -1307,21 +1307,7 @@
   final double minLeadingWidth;
 
   @override
-  Iterable<_ListTileSlot> get slots => _ListTileSlot.values;
-
-  @override
-  Widget? childForSlot(_ListTileSlot slot) {
-    switch (slot) {
-      case _ListTileSlot.leading:
-        return leading;
-      case _ListTileSlot.title:
-        return title;
-      case _ListTileSlot.subtitle:
-        return subtitle;
-      case _ListTileSlot.trailing:
-        return trailing;
-    }
-  }
+  _ListTileElement createElement() => _ListTileElement(this);
 
   @override
   _RenderListTile createRenderObject(BuildContext context) {
@@ -1353,7 +1339,111 @@
   }
 }
 
-class _RenderListTile extends RenderBox with SlottedContainerRenderObjectMixin<_ListTileSlot> {
+class _ListTileElement extends RenderObjectElement {
+  _ListTileElement(_ListTile widget) : super(widget);
+
+  final Map<_ListTileSlot, Element> slotToChild = <_ListTileSlot, Element>{};
+
+  @override
+  _ListTile get widget => super.widget as _ListTile;
+
+  @override
+  _RenderListTile get renderObject => super.renderObject as _RenderListTile;
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    slotToChild.values.forEach(visitor);
+  }
+
+  @override
+  void forgetChild(Element child) {
+    assert(slotToChild.containsValue(child));
+    assert(child.slot is _ListTileSlot);
+    assert(slotToChild.containsKey(child.slot));
+    slotToChild.remove(child.slot);
+    super.forgetChild(child);
+  }
+
+  void _mountChild(Widget? widget, _ListTileSlot slot) {
+    final Element? oldChild = slotToChild[slot];
+    final Element? newChild = updateChild(oldChild, widget, slot);
+    if (oldChild != null) {
+      slotToChild.remove(slot);
+    }
+    if (newChild != null) {
+      slotToChild[slot] = newChild;
+    }
+  }
+
+  @override
+  void mount(Element? parent, Object? newSlot) {
+    super.mount(parent, newSlot);
+    _mountChild(widget.leading, _ListTileSlot.leading);
+    _mountChild(widget.title, _ListTileSlot.title);
+    _mountChild(widget.subtitle, _ListTileSlot.subtitle);
+    _mountChild(widget.trailing, _ListTileSlot.trailing);
+  }
+
+  void _updateChild(Widget? widget, _ListTileSlot slot) {
+    final Element? oldChild = slotToChild[slot];
+    final Element? newChild = updateChild(oldChild, widget, slot);
+    if (oldChild != null) {
+      slotToChild.remove(slot);
+    }
+    if (newChild != null) {
+      slotToChild[slot] = newChild;
+    }
+  }
+
+  @override
+  void update(_ListTile newWidget) {
+    super.update(newWidget);
+    assert(widget == newWidget);
+    _updateChild(widget.leading, _ListTileSlot.leading);
+    _updateChild(widget.title, _ListTileSlot.title);
+    _updateChild(widget.subtitle, _ListTileSlot.subtitle);
+    _updateChild(widget.trailing, _ListTileSlot.trailing);
+  }
+
+  void _updateRenderObject(RenderBox? child, _ListTileSlot slot) {
+    switch (slot) {
+      case _ListTileSlot.leading:
+        renderObject.leading = child;
+        break;
+      case _ListTileSlot.title:
+        renderObject.title = child;
+        break;
+      case _ListTileSlot.subtitle:
+        renderObject.subtitle = child;
+        break;
+      case _ListTileSlot.trailing:
+        renderObject.trailing = child;
+        break;
+    }
+  }
+
+  @override
+  void insertRenderObjectChild(RenderObject child, _ListTileSlot slot) {
+    assert(child is RenderBox);
+    _updateRenderObject(child as RenderBox, slot);
+    assert(renderObject.children.keys.contains(slot));
+  }
+
+  @override
+  void removeRenderObjectChild(RenderObject child, _ListTileSlot slot) {
+    assert(child is RenderBox);
+    assert(renderObject.children[slot] == child);
+    _updateRenderObject(null, slot);
+    assert(!renderObject.children.keys.contains(slot));
+  }
+
+  @override
+  void moveRenderObjectChild(RenderObject child, Object? oldSlot, Object? newSlot) {
+    assert(false, 'not reachable');
+  }
+}
+
+class _RenderListTile extends RenderBox {
   _RenderListTile({
     required bool isDense,
     required VisualDensity visualDensity,
@@ -1382,14 +1472,46 @@
        _minVerticalPadding = minVerticalPadding,
        _minLeadingWidth = minLeadingWidth;
 
-  RenderBox? get leading => childForSlot(_ListTileSlot.leading);
-  RenderBox? get title => childForSlot(_ListTileSlot.title);
-  RenderBox? get subtitle => childForSlot(_ListTileSlot.subtitle);
-  RenderBox? get trailing => childForSlot(_ListTileSlot.trailing);
+  final Map<_ListTileSlot, RenderBox> children = <_ListTileSlot, RenderBox>{};
+
+  RenderBox? _updateChild(RenderBox? oldChild, RenderBox? newChild, _ListTileSlot slot) {
+    if (oldChild != null) {
+      dropChild(oldChild);
+      children.remove(slot);
+    }
+    if (newChild != null) {
+      children[slot] = newChild;
+      adoptChild(newChild);
+    }
+    return newChild;
+  }
+
+  RenderBox? _leading;
+  RenderBox? get leading => _leading;
+  set leading(RenderBox? value) {
+    _leading = _updateChild(_leading, value, _ListTileSlot.leading);
+  }
+
+  RenderBox? _title;
+  RenderBox? get title => _title;
+  set title(RenderBox? value) {
+    _title = _updateChild(_title, value, _ListTileSlot.title);
+  }
+
+  RenderBox? _subtitle;
+  RenderBox? get subtitle => _subtitle;
+  set subtitle(RenderBox? value) {
+    _subtitle = _updateChild(_subtitle, value, _ListTileSlot.subtitle);
+  }
+
+  RenderBox? _trailing;
+  RenderBox? get trailing => _trailing;
+  set trailing(RenderBox? value) {
+    _trailing = _updateChild(_trailing, value, _ListTileSlot.trailing);
+  }
 
   // The returned list is ordered for hit testing.
-  @override
-  Iterable<RenderBox> get children sync* {
+  Iterable<RenderBox> get _children sync* {
     if (leading != null)
       yield leading!;
     if (title != null)
@@ -1494,6 +1616,44 @@
   }
 
   @override
+  void attach(PipelineOwner owner) {
+    super.attach(owner);
+    for (final RenderBox child in _children)
+      child.attach(owner);
+  }
+
+  @override
+  void detach() {
+    super.detach();
+    for (final RenderBox child in _children)
+      child.detach();
+  }
+
+  @override
+  void redepthChildren() {
+    _children.forEach(redepthChild);
+  }
+
+  @override
+  void visitChildren(RenderObjectVisitor visitor) {
+    _children.forEach(visitor);
+  }
+
+  @override
+  List<DiagnosticsNode> debugDescribeChildren() {
+    final List<DiagnosticsNode> value = <DiagnosticsNode>[];
+    void add(RenderBox? child, String name) {
+      if (child != null)
+        value.add(child.toDiagnosticsNode(name: name));
+    }
+    add(leading, 'leading');
+    add(title, 'title');
+    add(subtitle, 'subtitle');
+    add(trailing, 'trailing');
+    return value;
+  }
+
+  @override
   bool get sizedByParent => false;
 
   static double _minWidth(RenderBox? box, double height) {
@@ -1745,7 +1905,7 @@
   @override
   bool hitTestChildren(BoxHitTestResult result, { required Offset position }) {
     assert(position != null);
-    for (final RenderBox child in children) {
+    for (final RenderBox child in _children) {
       final BoxParentData parentData = child.parentData! as BoxParentData;
       final bool isHit = result.addWithPaintOffset(
         offset: parentData.offset,
diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart
index cf95c13..dd4248f 100644
--- a/packages/flutter/lib/src/rendering/object.dart
+++ b/packages/flutter/lib/src/rendering/object.dart
@@ -3167,11 +3167,6 @@
 /// parent data.
 ///
 /// Moreover, this is a required mixin for render objects returned to [MultiChildRenderObjectWidget].
-///
-/// See also:
-///
-///  * [SlottedContainerRenderObjectMixin], which organizes its children
-///    in different named slots.
 mixin ContainerRenderObjectMixin<ChildType extends RenderObject, ParentDataType extends ContainerParentDataMixin<ChildType>> on RenderObject {
   bool _debugUltimatePreviousSiblingOf(ChildType child, { ChildType? equals }) {
     ParentDataType childParentData = child.parentData! as ParentDataType;
diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart
index 31cf0d0..ed0424f 100644
--- a/packages/flutter/lib/src/widgets/framework.dart
+++ b/packages/flutter/lib/src/widgets/framework.dart
@@ -1677,13 +1677,6 @@
 /// RenderObjectWidgets provide the configuration for [RenderObjectElement]s,
 /// which wrap [RenderObject]s, which provide the actual rendering of the
 /// application.
-///
-/// See also:
-///
-///  * [MultiChildRenderObjectWidget], which configures a [RenderObject] with
-///    a single list of children.
-///  * [SlottedMultiChildRenderObjectWidgetMixin], which configures a
-///    [RenderObject] that organizes its children in different named slots.
 abstract class RenderObjectWidget extends Widget {
   /// Abstract const constructor. This constructor enables subclasses to provide
   /// const constructors so that they can be used in const expressions.
@@ -1774,11 +1767,7 @@
 /// See also:
 ///
 ///  * [Stack], which uses [MultiChildRenderObjectWidget].
-///  * [RenderStack], for an example implementation of the associated render
-///    object.
-///  * [SlottedMultiChildRenderObjectWidgetMixin], which configures a
-///    [RenderObject] that instead of having a single list of children organizes
-///    its children in named slots.
+///  * [RenderStack], for an example implementation of the associated render object.
 abstract class MultiChildRenderObjectWidget extends RenderObjectWidget {
   /// Initializes fields for subclasses.
   ///
diff --git a/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart b/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart
deleted file mode 100644
index 25ae7b4..0000000
--- a/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/rendering.dart';
-
-import 'framework.dart';
-
-/// A mixin for a [RenderObjectWidget] that configures a [RenderObject]
-/// subclass, which organizes its children in different slots.
-///
-/// Implementers of this mixin have to provide the list of available slots by
-/// overriding [slots]. The list of slots must never change for a given class
-/// implementing this mixin. In the common case, [Enum] values are used as slots
-/// and [slots] is typically implemented to return the value of the enum's
-/// `values` getter.
-///
-/// Furthermore, [childForSlot] must be implemented to return the current
-/// widget configuration for a given slot.
-///
-/// The [RenderObject] returned by [createRenderObject] and updated by
-/// [updateRenderObject] must implement the [SlottedContainerRenderObjectMixin].
-///
-/// The type parameter `S` is the type for the slots to be used by this
-/// [RenderObjectWidget] and the [RenderObject] it configures. In the typical
-/// case, `S` is an [Enum] type.
-///
-/// {@tool dartpad}
-/// This example uses the [SlottedMultiChildRenderObjectWidgetMixin] in
-/// combination with the [SlottedContainerRenderObjectMixin] to implement a
-/// widget that provides two slots: topLeft and bottomRight. The widget arranges
-/// the children in those slots diagonally.
-///
-/// ** See code in examples/api/lib/widgets/slotted_render_object_widget/slotted_multi_child_render_object_widget_mixin.0.dart **
-/// {@end-tool}
-///
-/// See also:
-///
-///   * [MultiChildRenderObjectWidget], which configures a [RenderObject]
-///     with a single list of children.
-///   * [ListTile], which uses [SlottedMultiChildRenderObjectWidgetMixin] in its
-///     internal (private) implementation.
-mixin SlottedMultiChildRenderObjectWidgetMixin<S> on RenderObjectWidget {
-  /// Returns a list of all available slots.
-  ///
-  /// The list of slots must be static and must never change for a given class
-  /// implementing this mixin.
-  ///
-  /// Typically, an [Enum] is used to identify the different slots. In that case
-  /// this getter can be implemented by returning what the `values` getter
-  /// of the enum used returns.
-  @protected
-  Iterable<S> get slots;
-
-  /// Returns the widget that is currently occupying the provided `slot`.
-  ///
-  /// The [RenderObject] configured by this class will be configured to have
-  /// the [RenderObject] produced by the returned [Widget] in the provided
-  /// `slot`.
-  @protected
-  Widget? childForSlot(S slot);
-
-  @override
-  SlottedContainerRenderObjectMixin<S> createRenderObject(BuildContext context);
-
-  @override
-  void updateRenderObject(BuildContext context, SlottedContainerRenderObjectMixin<S> renderObject);
-
-  @override
-  SlottedRenderObjectElement<S> createElement() => SlottedRenderObjectElement<S>(this);
-}
-
-/// Mixin for a [RenderBox] configured by a [SlottedMultiChildRenderObjectWidgetMixin].
-///
-/// The [RenderBox] child currently occupying a given slot can be obtained by
-/// calling [childForSlot].
-///
-/// Implementers may consider overriding [children] to return the children
-/// of this render object in a consistent order (e.g. hit test order).
-///
-/// The type parameter `S` is the type for the slots to be used by this
-/// [RenderObject] and the [SlottedMultiChildRenderObjectWidgetMixin] it was
-/// configured by. In the typical case, `S` is an [Enum] type.
-///
-/// See [SlottedMultiChildRenderObjectWidgetMixin] for example code showcasing
-/// how this mixin is used in combination with the
-/// [SlottedMultiChildRenderObjectWidgetMixin].
-///
-/// See also:
-///
-///  * [ContainerRenderObjectMixin], which organizes its children in a single
-///    list.
-mixin SlottedContainerRenderObjectMixin<S> on RenderBox {
-  /// Returns the [RenderBox] child that is currently occupying the provided
-  /// `slot`.
-  ///
-  /// Returns null if no [RenderBox] is configured for the given slot.
-  @protected
-  RenderBox? childForSlot(S slot) => _slotToChild[slot];
-
-  /// Returns an [Iterable] of all non-null children.
-  ///
-  /// This getter is used by the default implementation of [attach], [detach],
-  /// [redepthChildren], [visitChildren], and [debugDescribeChildren] to iterate
-  /// over the children of this [RenderBox]. The base implementation makes no
-  /// guarantee about the order in which the children are returned. Subclasses,
-  /// for which the child order is important should override this getter and
-  /// return the children in the desired order.
-  @protected
-  Iterable<RenderBox> get children => _slotToChild.values;
-
-  /// Returns the debug name for a given `slot`.
-  ///
-  /// This method is called by [debugDescribeChildren] for each slot that is
-  /// currently occupied by a child to obtain a name for that slot for debug
-  /// outputs.
-  ///
-  /// The default implementation calls [EnumName.name] on `slot` it it is an
-  /// [Enum] value and `toString` if it is not.
-  @protected
-  String debugNameForSlot(S slot) {
-    if (slot is Enum) {
-      return slot.name;
-    }
-    return slot.toString();
-  }
-
-  @override
-  void attach(PipelineOwner owner) {
-    super.attach(owner);
-    for (final RenderBox child in children) {
-      child.attach(owner);
-    }
-  }
-
-  @override
-  void detach() {
-    super.detach();
-    for (final RenderBox child in children) {
-      child.detach();
-    }
-  }
-
-  @override
-  void redepthChildren() {
-    children.forEach(redepthChild);
-  }
-
-  @override
-  void visitChildren(RenderObjectVisitor visitor) {
-    children.forEach(visitor);
-  }
-
-  @override
-  List<DiagnosticsNode> debugDescribeChildren() {
-    final List<DiagnosticsNode> value = <DiagnosticsNode>[];
-    final Map<RenderBox, S> childToSlot = Map<RenderBox, S>.fromIterables(
-      _slotToChild.values,
-      _slotToChild.keys,
-    );
-    for (final RenderBox child in children) {
-      _addDiagnostics(child, value, debugNameForSlot(childToSlot[child] as S));
-    }
-    return value;
-  }
-
-  void _addDiagnostics(RenderBox child, List<DiagnosticsNode> value, String name) {
-    value.add(child.toDiagnosticsNode(name: name));
-  }
-
-  final Map<S, RenderBox> _slotToChild = <S, RenderBox>{};
-
-  void _setChild(RenderBox? child, S slot) {
-    final RenderBox? oldChild = _slotToChild[slot];
-    if (oldChild != null) {
-      dropChild(oldChild);
-      _slotToChild.remove(slot);
-    }
-    if (child != null) {
-      _slotToChild[slot] = child;
-      adoptChild(child);
-    }
-  }
-}
-
-/// Element used by the [SlottedMultiChildRenderObjectWidgetMixin].
-class SlottedRenderObjectElement<S> extends RenderObjectElement {
-  /// Creates an element that uses the given widget as its configuration.
-  SlottedRenderObjectElement(SlottedMultiChildRenderObjectWidgetMixin<S> widget) : super(widget);
-
-  final Map<S, Element> _slotToChild = <S, Element>{};
-
-  @override
-  SlottedMultiChildRenderObjectWidgetMixin<S> get widget => super.widget as SlottedMultiChildRenderObjectWidgetMixin<S>;
-
-  @override
-  SlottedContainerRenderObjectMixin<S> get renderObject => super.renderObject as SlottedContainerRenderObjectMixin<S>;
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    _slotToChild.values.forEach(visitor);
-  }
-
-  @override
-  void forgetChild(Element child) {
-    assert(_slotToChild.containsValue(child));
-    assert(child.slot is S);
-    assert(_slotToChild.containsKey(child.slot));
-    _slotToChild.remove(child.slot);
-    super.forgetChild(child);
-  }
-
-  @override
-  void mount(Element? parent, Object? newSlot) {
-    super.mount(parent, newSlot);
-    _updateChildren();
-  }
-
-  @override
-  void update(SlottedMultiChildRenderObjectWidgetMixin<S> newWidget) {
-    super.update(newWidget);
-    assert(widget == newWidget);
-    _updateChildren();
-  }
-
-  List<S>? _debugPreviousSlots;
-
-  void _updateChildren() {
-    assert(() {
-      _debugPreviousSlots ??= widget.slots.toList();
-      return listEquals(_debugPreviousSlots, widget.slots.toList());
-    }(), '${widget.runtimeType}.slots must not change.');
-    assert(widget.slots.toSet().length == widget.slots.length, 'slots must be unique');
-
-    for (final S slot in widget.slots) {
-      _updateChild(widget.childForSlot(slot), slot);
-    }
-  }
-
-  void _updateChild(Widget? widget, S slot) {
-    final Element? oldChild = _slotToChild[slot];
-    assert(oldChild == null || oldChild.slot == slot); // Reason why [moveRenderObjectChild] is not reachable.
-    final Element? newChild = updateChild(oldChild, widget, slot);
-    if (oldChild != null) {
-      _slotToChild.remove(slot);
-    }
-    if (newChild != null) {
-      _slotToChild[slot] = newChild;
-    }
-  }
-
-  @override
-  void insertRenderObjectChild(RenderBox child, S slot) {
-    renderObject._setChild(child, slot);
-    assert(renderObject._slotToChild[slot] == child);
-  }
-
-  @override
-  void removeRenderObjectChild(RenderBox child, S slot) {
-    assert(renderObject._slotToChild[slot] == child);
-    renderObject._setChild(null, slot);
-    assert(renderObject._slotToChild[slot] == null);
-  }
-
-  @override
-  void moveRenderObjectChild(RenderBox child, Object? oldSlot, Object? newSlot) {
-    // Existing elements are never moved to a new slot, see assert in [_updateChild].
-    assert(false, 'not reachable');
-  }
-}
diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart
index 62e702e..c424d6e 100644
--- a/packages/flutter/lib/widgets.dart
+++ b/packages/flutter/lib/widgets.dart
@@ -116,7 +116,6 @@
 export 'src/widgets/sliver_layout_builder.dart';
 export 'src/widgets/sliver_persistent_header.dart';
 export 'src/widgets/sliver_prototype_extent_list.dart';
-export 'src/widgets/slotted_render_object_widget.dart';
 export 'src/widgets/spacer.dart';
 export 'src/widgets/status_transitions.dart';
 export 'src/widgets/table.dart';
diff --git a/packages/flutter/test/material/chip_test.dart b/packages/flutter/test/material/chip_test.dart
index e229d00..f4e0a7c 100644
--- a/packages/flutter/test/material/chip_test.dart
+++ b/packages/flutter/test/material/chip_test.dart
@@ -15,7 +15,7 @@
 import 'feedback_tester.dart';
 
 Finder findRenderChipElement() {
-  return find.byElementPredicate((Element e) => '${e.renderObject.runtimeType}' == '_RenderChip');
+  return find.byElementPredicate((Element e) => '${e.runtimeType}' == '_RenderChipElement');
 }
 
 RenderBox getMaterialBox(WidgetTester tester) {
diff --git a/packages/flutter/test/widgets/slotted_render_object_widget_test.dart b/packages/flutter/test/widgets/slotted_render_object_widget_test.dart
deleted file mode 100644
index 7da4ae4..0000000
--- a/packages/flutter/test/widgets/slotted_render_object_widget_test.dart
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2014 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import '../rendering/mock_canvas.dart';
-
-const Color green = Color(0xFF00FF00);
-const Color yellow = Color(0xFFFFFF00);
-
-void main() {
-  testWidgets('SlottedRenderObjectWidget test', (WidgetTester tester) async {
-    await tester.pumpWidget(buildWidget(
-      topLeft: Container(
-        height: 100,
-        width: 80,
-        color: yellow,
-        child: const Text('topLeft'),
-      ),
-      bottomRight: Container(
-        height: 120,
-        width: 110,
-        color: green,
-        child: const Text('bottomRight'),
-      ),
-    ));
-
-    expect(find.text('topLeft'), findsOneWidget);
-    expect(find.text('bottomRight'), findsOneWidget);
-    expect(tester.getSize(find.byType(_Diagonal)), const Size(80 + 110, 100 + 120));
-    expect(find.byType(_Diagonal), paints
-      ..rect(
-        rect: const Rect.fromLTWH(0, 0, 80, 100),
-        color: yellow,
-      )
-      ..rect(
-        rect: const Rect.fromLTWH(80, 100, 110, 120),
-        color: green,
-      )
-    );
-
-    await tester.pumpWidget(buildWidget(
-      topLeft: Container(
-        height: 200,
-        width: 100,
-        color: yellow,
-        child: const Text('topLeft'),
-      ),
-      bottomRight: Container(
-        height: 220,
-        width: 210,
-        color: green,
-        child: const Text('bottomRight'),
-      ),
-    ));
-
-    expect(find.text('topLeft'), findsOneWidget);
-    expect(find.text('bottomRight'), findsOneWidget);
-    expect(tester.getSize(find.byType(_Diagonal)), const Size(100 + 210, 200 + 220));
-    expect(find.byType(_Diagonal), paints
-      ..rect(
-        rect: const Rect.fromLTWH(0, 0, 100, 200),
-        color: yellow,
-      )
-      ..rect(
-        rect: const Rect.fromLTWH(100, 200, 210, 220),
-        color: green,
-      )
-    );
-
-    await tester.pumpWidget(buildWidget(
-      topLeft: Container(
-        height: 200,
-        width: 100,
-        color: yellow,
-        child: const Text('topLeft'),
-      ),
-      bottomRight: Container(
-        key: UniqueKey(),
-        height: 230,
-        width: 220,
-        color: green,
-        child: const Text('bottomRight'),
-      ),
-    ));
-
-    expect(find.text('topLeft'), findsOneWidget);
-    expect(find.text('bottomRight'), findsOneWidget);
-    expect(tester.getSize(find.byType(_Diagonal)), const Size(100 + 220, 200 + 230));
-    expect(find.byType(_Diagonal), paints
-      ..rect(
-        rect: const Rect.fromLTWH(0, 0, 100, 200),
-        color: yellow,
-      )
-      ..rect(
-        rect: const Rect.fromLTWH(100, 200, 220, 230),
-        color: green,
-      )
-    );
-
-    await tester.pumpWidget(buildWidget(
-      topLeft: Container(
-        height: 200,
-        width: 100,
-        color: yellow,
-        child: const Text('topLeft'),
-      ),
-    ));
-
-    expect(find.text('topLeft'), findsOneWidget);
-    expect(find.text('bottomRight'), findsNothing);
-    expect(tester.getSize(find.byType(_Diagonal)), const Size(100, 200));
-    expect(find.byType(_Diagonal), paints
-      ..rect(
-        rect: const Rect.fromLTWH(0, 0, 100, 200),
-        color: yellow,
-      )
-    );
-
-    await tester.pumpWidget(buildWidget());
-    expect(find.text('topLeft'), findsNothing);
-    expect(find.text('bottomRight'), findsNothing);
-    expect(tester.getSize(find.byType(_Diagonal)), Size.zero);
-    expect(find.byType(_Diagonal), paintsNothing);
-
-    await tester.pumpWidget(Container());
-    expect(find.byType(_Diagonal), findsNothing);
-  });
-
-  test('nameForSlot', () {
-    expect(_RenderDiagonal().publicNameForSlot(_DiagonalSlot.bottomRight), 'bottomRight');
-    expect(_RenderDiagonal().publicNameForSlot(_DiagonalSlot.topLeft), 'topLeft');
-    final _Slot slot = _Slot();
-    expect(_RenderTest().publicNameForSlot(slot), slot.toString());
-  });
-
-  testWidgets('debugDescribeChildren', (WidgetTester tester) async {
-    await tester.pumpWidget(buildWidget(
-      topLeft: const SizedBox(
-        height: 100,
-        width: 80,
-      ),
-      bottomRight: const SizedBox(
-        height: 120,
-        width: 110,
-      ),
-    ));
-
-    expect(
-      tester.renderObject(find.byType(_Diagonal)).toStringDeep(),
-      equalsIgnoringHashCodes(r'''
-_RenderDiagonal#00000 relayoutBoundary=up1
- │ creator: _Diagonal ← Align ← Directionality ← [root]
- │ parentData: offset=Offset(0.0, 0.0) (can use size)
- │ constraints: BoxConstraints(0.0<=w<=800.0, 0.0<=h<=600.0)
- │ size: Size(190.0, 220.0)
- │
- ├─topLeft: RenderConstrainedBox#00000 relayoutBoundary=up2
- │   creator: SizedBox ← _Diagonal ← Align ← Directionality ← [root]
- │   parentData: offset=Offset(0.0, 0.0) (can use size)
- │   constraints: BoxConstraints(unconstrained)
- │   size: Size(80.0, 100.0)
- │   additionalConstraints: BoxConstraints(w=80.0, h=100.0)
- │
- └─bottomRight: RenderConstrainedBox#00000 relayoutBoundary=up2
-     creator: SizedBox ← _Diagonal ← Align ← Directionality ← [root]
-     parentData: offset=Offset(80.0, 100.0) (can use size)
-     constraints: BoxConstraints(unconstrained)
-     size: Size(110.0, 120.0)
-     additionalConstraints: BoxConstraints(w=110.0, h=120.0)
-''')
-    );
-  });
-}
-
-Widget buildWidget({Widget? topLeft, Widget? bottomRight}) {
-  return Directionality(
-    textDirection: TextDirection.ltr,
-    child: Align(
-      alignment: Alignment.topLeft,
-      child: _Diagonal(
-        topLeft: topLeft,
-        bottomRight: bottomRight,
-      ),
-    ),
-  );
-}
-
-enum _DiagonalSlot {
-  topLeft,
-  bottomRight,
-}
-
-class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_DiagonalSlot> {
-  const _Diagonal({
-    Key? key,
-    this.topLeft,
-    this.bottomRight,
-    this.backgroundColor,
-  }) : super(key: key);
-
-  final Widget? topLeft;
-  final Widget? bottomRight;
-  final Color? backgroundColor;
-
-  @override
-  Iterable<_DiagonalSlot> get slots => _DiagonalSlot.values;
-
-  @override
-  Widget? childForSlot(Object slot) {
-    switch (slot) {
-      case _DiagonalSlot.topLeft:
-        return topLeft;
-      case _DiagonalSlot.bottomRight:
-        return bottomRight;
-    }
-  }
-
-  @override
-  SlottedContainerRenderObjectMixin<_DiagonalSlot> createRenderObject(
-    BuildContext context,
-  ) {
-    return _RenderDiagonal();
-  }
-}
-
-class _RenderDiagonal extends RenderBox with SlottedContainerRenderObjectMixin<_DiagonalSlot> {
-  RenderBox? get _topLeft => childForSlot(_DiagonalSlot.topLeft);
-  RenderBox? get _bottomRight => childForSlot(_DiagonalSlot.bottomRight);
-
-  @override
-  void performLayout() {
-    const BoxConstraints childConstraints = BoxConstraints();
-
-    Size topLeftSize = Size.zero;
-    if (_topLeft != null) {
-      _topLeft!.layout(childConstraints, parentUsesSize: true);
-      _positionChild(_topLeft!, Offset.zero);
-      topLeftSize = _topLeft!.size;
-    }
-
-    Size bottomRightSize = Size.zero;
-    if (_bottomRight != null) {
-      _bottomRight!.layout(childConstraints, parentUsesSize: true);
-      _positionChild(
-        _bottomRight!,
-        Offset(topLeftSize.width, topLeftSize.height),
-      );
-      bottomRightSize = _bottomRight!.size;
-    }
-
-    size = constraints.constrain(Size(
-      topLeftSize.width + bottomRightSize.width,
-      topLeftSize.height + bottomRightSize.height,
-    ));
-  }
-
-  void _positionChild(RenderBox child, Offset offset) {
-    (child.parentData! as BoxParentData).offset = offset;
-  }
-
-  @override
-  void paint(PaintingContext context, Offset offset) {
-    if (_topLeft != null) {
-      _paintChild(_topLeft!, context, offset);
-    }
-    if (_bottomRight != null) {
-      _paintChild(_bottomRight!, context, offset);
-    }
-  }
-
-  void _paintChild(RenderBox child, PaintingContext context, Offset offset) {
-    final BoxParentData childParentData = child.parentData! as BoxParentData;
-    context.paintChild(child, childParentData.offset + offset);
-  }
-
-  String publicNameForSlot(_DiagonalSlot slot) => debugNameForSlot(slot);
-}
-
-class _Slot {
-  @override
-  String toString() => describeIdentity(this);
-}
-
-class _RenderTest extends RenderBox with SlottedContainerRenderObjectMixin<_Slot> {
-  String publicNameForSlot(_Slot slot) => debugNameForSlot(slot);
-}
