A potential fix, although it requires a change to the loader api.

The old approach is to calculate dirs, pass them to the loaders, and
remove any that have been used. This fails when templates from the
same directory extend eachother.

Instead, keep a list of template paths in the context. Define a
get_template and get_source on the loader. get_template takes
a skip argument. get_source yields matching templates, rather than
returning. get_template ignores any templates specified in skip.

This can require extra file system calls, but the generator approach
tries to limit only to what is necessary.
Try another approach.

This works for loaders other than the cached loader. This one is
problematic because it keys template name to the cache, assuming
this will always return the same value.