message: [XLA] Fix bugs and improve error messages in tuple comparisons in literal_test_util.
  * Fix bug where EqualsTuple() only compared the first tuple element (!).
  * Compare all tuple elements, even when the first one fails.
  * Print out which tuple element we're looking at when we get a
  mismatch.
diff: @@ -57,7 +57,8 @@ namespace xla {
  }
  for (int i = 0; i < expected.tuple_shapes_size(); ++i) {
  ::testing::AssertionResult result =
  - EqualShapes(expected.tuple_shapes(i), actual.tuple_shapes(i));
  + EqualShapes(expected.tuple_shapes(i), actual.tuple_shapes(i))
  + << "mismatch in tuple index " << i;
  if (!result) {
  return result;
  }
  @@ -345,20 +346,28 @@ bool ExpectLiteralsEqual(const Literal& expected, const Literal& actual,
  << " actual shape = " << actual.shape().ShortDebugString();
  }
  AssertEqualShapes(expected.shape(), actual.shape());
  +
  + ::testing::AssertionResult err = ::testing::AssertionSuccess();
  for (uint64 i = 0; i < expected.tuple_literals_size(); ++i) {
  + SCOPED_TRACE(tensorflow::strings::StrCat(
  + "Tuple index ", i, " in ", ShapeUtil::HumanString(expected.shape())));
  const auto& expected_element = expected.tuple_literals(i);
  const auto& actual_element = actual.tuple_literals(i);
  +
  + ::testing::AssertionResult res = [&] {
  if (ShapeUtil::IsTuple(expected_element.shape())) {
  - auto ret = EqualTuple(expected_element, actual_element);
  - if (!ret) {
  - return ret;
  - }
  + return EqualTuple(expected_element, actual_element);
  } else {
  return Equal(expected_element, actual_element);
  }
  + }();
  +
  + if (!res && err) {
  + err = res;
  + }
  }
  - return ::testing::AssertionSuccess();
  + return err;
  }
  /* static */ void LiteralTestUtil::ExpectEqualTuple(const Literal& expected,
  @@ -633,28 +642,29 @@ bool NearComparator::ExpectValuesNear<bfloat16>(bfloat16 expected,
  << " actual shape = " << actual.shape().ShortDebugString();
  }
  AssertEqualShapes(expected.shape(), actual.shape());
  +
  + ::testing::AssertionResult err = ::testing::AssertionSuccess();
  for (uint64 i = 0; i < expected.tuple_literals_size(); ++i) {
  + SCOPED_TRACE(tensorflow::strings::StrCat(
  + "Tuple index ", i, " in ", ShapeUtil::HumanString(expected.shape())));
  const auto& expected_element = expected.tuple_literals(i);
  const auto& actual_element = actual.tuple_literals(i);
  +
  + ::testing::AssertionResult res = [&] {
  if (ShapeUtil::IsTuple(expected_element.shape())) {
  - auto ret = NearTuple(expected_element, actual_element, error);
  - if (!ret) {
  - return ret;
  - }
  + return NearTuple(expected_element, actual_element, error);
  } else if (ShapeUtil::ElementIsFloating(expected_element.shape())) {
  - auto ret = Near(expected_element, actual_element, error);
  - if (!ret) {
  - return ret;
  - }
  + return Near(expected_element, actual_element, error);
  } else {
  - auto ret = Equal(expected_element, actual_element);
  - if (!ret) {
  - return ret;
  + return Equal(expected_element, actual_element);
  }
  + }();
  +
  + if (err && !res) {
  + err = res;
  }
  }
  -
  - return ::testing::AssertionSuccess();
  + return err;
  }
  /* static */ void LiteralTestUtil::ExpectNearTuple(const Literal& expected,
  