private void validateStructurePaths(PathFinder finder, Model model, List<ValidationEvent> events) {
        finder.relationshipFilter(rel -> {
            if (rel.getShape().isStructureShape()) {
                return rel.getNeighborShape().get().hasTrait(RequiredTrait.ID);
            } else {
                return rel.getShape().isMemberShape();
            }
        });

        for (StructureShape shape : model.getStructureShapes()) {
            for (PathFinder.Path path : finder.search(shape, Collections.singletonList(shape))) {
                events.add(error(shape,
                        String.format(
                                "Found invalid shape recursion: %s. A structure cannot be mutually recursive through all "
                                        + "required members.",
                                formatPath(path))));
            }
        }
    }
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