Comparisons of list expressions, structure-valued expressions, tuples and structs #3057
Description
In testing all the comparisons between list expressions, structure-valued expressions, tuples, and structs in the p4c compiler, we found some examples rejected by the compiler (relates to p4lang/p4-spec#960). Some are likely compiler bugs, while some may not be.
Note: the tests are reordered and renumbered for a cleaner view, so it looks different from p4lang/p4-spec#960.
struct S {
bit<32> a;
bit<32> b;
}
control compute(inout hdr h) {
apply {
bool b1 = { 1, 2 } == { 1, 2 };
bool b2 = { a = 8w1, b = 8w2 } == { a = 8w1, b = 8w2 };
// bool b2_ = { a = 1, b = 2 } == { a = 1, b = 2 }; // p4c: Compiler Bug: Could not find type for <Constant>(11032) 1
// bool b3 = { a = 1, b = 2 } == {1, 2}; // p4c: error: ==: Cannot unify type Tuple(2) with unknown struct
bool b4 = (S) { a = 1, b = 2 } == {1, 2};
bool b5 = (S) { a = 1, b = 2 } == { a = 1, b = 2 };
// bool b5_ = { a = 1, b = 2 } == (S) { a = 1, b = 2 }; // p4c: error: ==: Cannot unify struct S to unknown struct
bool b6 = (S) { a = 1, b = 2 } == (S) { a = 1, b = 2 };
S s1 = { a = 1, b = 2 };
S s2 = { a = 1, b = 2 };
bool b7 = s1 == { a = 1, b = 2 };
bool b8 = s1 == (S) { a = 1, b = 2 };
bool b9 = s1 == s2;
tuple<bit<8>, bit<8>> t1 = {1, 2};
tuple<bit<8>, bit<8>> t2 = {1, 2};
bool b10 = t1 == { 1, 2 };
bool b11 = t1 == t2;
}
}
The tests b2_
and b5_
are likely bugs.
- For
b2_
, it seems to be some other issue with the compiler sinceb2
works well. - For
b5_
, it seems weird that the compiler cannot infer the type of the LHS. Given thatb5
works well, and there is no rule in the spec enforcing the direction of type inference, I think it is more likely a problem with the compiler.
With the test b3
aside, it seems tempting to summarize the allowed comparisons as:
- A list expression can be compared with a list expression, a structure-valued expression, a tuple, a struct, or a header for
equality (==) or inequality (!=) - A structure-valued expression can be compared with a list expression, a structure-valued expression, a struct, or a header for
equality (==) or inequality (!=) - Two tuples, two structs, and two headers can be compared for equality (==) or inequality (!=)
But the test b3
is indeed the corner case. Comparing b3
and b4
, a list expression can be compared with a structure-valued expression only when typRef
is explicit. We are still unsure whether b3 should be allowed or not: if yes, then the compiler needs to be fixed; otherwise, we need a more careful specification in the spec to explain this well.