docs: def merged_type(t, s):
      # type: (AbstractType, AbstractType) -> Optional[AbstractType]
      """Return merged type if two items can be merged in to a different, more general type.
  
      Return None if merging is not possible.
      """
      if isinstance(t, TupleType) and isinstance(s, TupleType):
          if len(t.items) == len(s.items):
              return TupleType([combine_types([ti, si]) for ti, si in zip(t.items, s.items)])
          all_items = t.items + s.items
          if all_items and all(item == all_items[0] for item in all_items[1:]):
              # Merge multiple compatible fixed-length tuples into a variable-length tuple type.
              return ClassType('Tuple', [all_items[0]])
      elif (isinstance(t, TupleType) and isinstance(s, ClassType) and s.name == 'Tuple'
            and len(s.args) == 1):
          if all(item == s.args[0] for item in t.items):
              # Merge fixed-length tuple and variable-length tuple.
              return s
      elif isinstance(s, TupleType) and isinstance(t, ClassType) and t.name == 'Tuple':
          return merged_type(s, t)
      elif isinstance(s, NoReturnType):
          return t
      elif isinstance(t, NoReturnType):
          return s
      elif isinstance(s, AnyType):
          # This seems to be usually desirable, since Anys tend to come from unknown types.
          return t
      elif isinstance(t, AnyType):
          # Similar to above.
          return s
      return None