Allow dicts to contain non-comparable objects as keys

RELNOTES: Skylark dicts internally don't rely on keys order anymore and accept
any hashable values (i.e. structs with immutable values) as keys. Iteration order of dictionaries is no longer specified.

--
PiperOrigin-RevId: 141055080
MOS_MIGRATED_REVID=141055080
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
index 17f5484..066c544 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
@@ -657,6 +657,11 @@
   }
 
   @Test
+  public void testProtoFieldsOrder() throws Exception {
+    checkTextMessage("struct(d=4, b=2, c=3, a=1).to_proto()", "a: 1", "b: 2", "c: 3", "d: 4");
+  }
+
+  @Test
   public void testTextMessageEscapes() throws Exception {
     checkTextMessage("struct(name='a\"b').to_proto()", "name: \"a\\\"b\"");
     checkTextMessage("struct(name='a\\'b').to_proto()", "name: \"a'b\"");
@@ -810,6 +815,14 @@
   }
 
   @Test
+  public void testStructIncomparability() throws Exception {
+    checkErrorContains("Cannot compare structs", "struct(a = 1) < struct(a = 2)");
+    checkErrorContains("Cannot compare structs", "struct(a = 1) > struct(a = 2)");
+    checkErrorContains("Cannot compare structs", "struct(a = 1) <= struct(a = 2)");
+    checkErrorContains("Cannot compare structs", "struct(a = 1) >= struct(a = 2)");
+  }
+
+  @Test
   public void testStructAccessingFieldsFromSkylark() throws Exception {
     eval("x = struct(a = 1, b = 2)", "x1 = x.a", "x2 = x.b");
     assertThat(lookup("x1")).isEqualTo(1);
@@ -934,6 +947,18 @@
   }
 
   @Test
+  public void testStructsInDicts() throws Exception {
+    eval("d = {struct(a = 1): 'aa', struct(b = 2): 'bb'}");
+    assertThat(eval("d[struct(a = 1)]")).isEqualTo("aa");
+    assertThat(eval("d[struct(b = 2)]")).isEqualTo("bb");
+    assertThat(eval("str([d[k] for k in d])")).isEqualTo("[\"aa\", \"bb\"]");
+
+    checkErrorContains(
+        "unhashable type: 'struct'",
+        "{struct(a = []): 'foo'}");
+  }
+
+  @Test
   public void testStructMembersAreImmutable() throws Exception {
     checkErrorContains(
         "cannot assign to 's.x'",