Takes a type and a set of basic types, and substitutes all instances of ANY_TYPE with all
    possible basic types and returns a list with all possible combinations.  Note that this
    substitution is unconstrained.  That is, If you have a type with placeholders, <#1,#1> for
    example, this may substitute the placeholders with different basic types. In that case, you'd
    want to use ``_substitute_placeholder_type`` instead.

def substitute_any_type(type_: Type, basic_types: Set[BasicType]) -> List[Type]:
    """
    Takes a type and a set of basic types, and substitutes all instances of ANY_TYPE with all
    possible basic types and returns a list with all possible combinations.  Note that this
    substitution is unconstrained.  That is, If you have a type with placeholders, <#1,#1> for
    example, this may substitute the placeholders with different basic types. In that case, you'd
    want to use ``_substitute_placeholder_type`` instead.
    """
    if type_ == ANY_TYPE:
        return list(basic_types)
    if isinstance(type_, BasicType):
        return [type_]
    # If we've made it this far, we have a ComplexType, and we can just call
    # `type_.substitute_any_type()`.
    return type_.substitute_any_type(basic_types)