private void validateListMapSetShapes(PathFinder finder, Model model, List<ValidationEvent> events) {
        finder.relationshipFilter(rel -> !(rel.getShape().isStructureShape() || rel.getShape().isUnionShape()));

        for (ListShape shape : model.getListShapes()) {
            validateListMapSetShapes(shape, finder, events);
        }

        for (SetShape shape : model.getSetShapes()) {
            validateListMapSetShapes(shape, finder, events);
        }

        for (MapShape shape : model.getMapShapes()) {
            validateListMapSetShapes(shape, finder, events);
        }

        finder.relationshipFilter(FunctionalUtils.alwaysTrue());
    }
Ensures that list, set, and map shapes are not directly recursive,
meaning that if they do have a recursive reference to themselves,
one or more references that form the recursive path travels through
a structure or union shape. And ensures that structure members are
not infinitely mutually recursive using the required trait.

<p>This check removes an entire class of problems from things like
code generators where a list of itself or a list of maps of itself
is impossible to define.
smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/ShapeRecursionValidator.java