Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler Bug: Could not find type of <Type_Header> ... on specialized generic struct type #4835

Closed
jaehyun1ee opened this issue Jul 26, 2024 · 9 comments · Fixed by #5133
Closed
Assignees
Labels
bug This behavior is unintended and should be fixed. core Topics concerning the core segments of the compiler (frontend, midend, parser)

Comments

@jaehyun1ee
Copy link

The following program, bug-generic.p4 fails to typecheck when given a command $ p4c --target bmv2 --arch v1model bug-generic.p4.

#include <core.p4>
#include <v1model.p4>

typedef standard_metadata_t std_meta_t;

header standard_t<T> {
  T src;
  T dst;
}

struct headers_t<T> {
  standard_t<T> standard;
}

struct meta_t { }

parser MyParser(packet_in pkt, out headers_t<bit<8>> hdr, inout meta_t meta, inout std_meta_t std_meta) {
    state start {
        pkt.extract<standard_t<bit<8>>>(hdr.standard);
        // pkt.extract(hdr.standard); <-- this also fails
        transition accept;
    }
}

control MyVerifyChecksum(inout headers_t<bit<8>> hdr, inout meta_t meta) {
    apply { }
}
control MyComputeChecksum(inout headers_t<bit<8>> hdr, inout meta_t meta) {
    apply { }
}
control MyIngress(inout headers_t<bit<8>> hdr, inout meta_t meta, inout std_meta_t std_meta) {
   apply { }
}
control MyEgress(inout headers_t<bit<8>> hdr, inout meta_t meta, inout std_meta_t std_meta) {
    apply { }
}
control MyDeparser(packet_out pkt, in headers_t<bit<8>> hdr) {
    apply { }
}
V1Switch(MyParser(), MyVerifyChecksum(), MyIngress(), MyEgress(), MyComputeChecksum(), MyDeparser()) main;

Here, I defined a generic struct headers_t<T> that has a field of generic header type standard_t<T>. In the parameter of MyParser, the type is specialized as headers_t<big<8>>. So I expect that both pkt.extract(hdr.standard); or pkt.extract<standard_t<bit<8>>>(hdr.standard); should typecheck.

However, the compiler fails to typecheck with an error message:

Compiler Bug: bug-generic.p4(19): Could not find type of <Type_Header>(40455) standard_t_0/66 header standard_t_0 {
  bit<8> src;
  bit<8> dst; }
header standard_t<T> {
       ^^^^^^^^^^

The same error message occurs when I do not pass the type argument standard_t<bit<8>> to pkt.extract method.

@fruffy fruffy added the bug This behavior is unintended and should be fixed. label Jul 26, 2024
@iamAyushChamoli
Copy link

iamAyushChamoli commented Aug 1, 2024

In your P4 program, you're trying to use a generic header standard_t, which should work with different types. However, the P4 language and its compiler have limitations when it comes to generics. Specifically, the pkt.extract() method requires a concrete header type, and the compiler struggles to resolve generic types at compile time. The P4 compiler requires that all header types be fully specified at compile time.
Something like:
header standard_8_t { bit<8> src; bit<8> dst; }

struct headers_t { standard_8_t standard; }

@jaehyun1ee
Copy link
Author

Thank you for the explanation!

Yet, I'm afraid I did not understand what you meant by "concrete".
Isn't the type argument standard_t<bit<8>> for pkt.extract method "concrete"?
The type constructor standard_t<T> has been concretized (or specialized) by bit<8>.
Similarly, the type of hdr is also concretized as headers_t<bit<8>>.

So my question would boil down to:
i) Is my program allowed according to the P4 specification, but not being compiled due to compiler limitation, or
ii) Is it now allowed by the P4 specification at the first place?

@iamAyushChamoli
Copy link

If I am understanding your issue correctly, then it is basically an issue about concretization and generic methods/constructors. I certainly am not the expert here but yes,

Isn't the type argument standard_t<bit<8>> for pkt.extract method "concrete"?

this is concrete, and as you've mentioned in your issue, the error pops up when you do not pass this concretized argument. So we're on the same page so far.

Is my program allowed according to the P4 specification, but not being compiled due to compiler limitation,

Yes, it is allowed as The P4 language specification allows the use of generic types and their specialization into concrete types. This is part of the language's design to provide flexibility and reuse through parameterized types.
The issue that you are facing is most likely a compiler limitation issue. It is likely that the version of P4 Compiler that you are using does not support your current problem.

I'm certainly not the expert here but this is what I can make out of the entire situation.

@jaehyun1ee
Copy link
Author

Ah, I see. Now I guess we are on the same page :)

One minor clarification though,

the error pops up when you do not pass this concretized argument. So we're on the same page so far.

The error pops up regardless of the type argument being passed.
i.e., pkt.extract(hdr.standard); fails as well as pkt.extract<standard_t<bit<8>>(hdr.standard);, with the same error message.

@iamAyushChamoli
Copy link

This might be a silly question but while running pkt.extract<standard_t<bit<8>>(hdr.standard);, did you make sure that you concretize it during it's instantiation/declaration? Could it be possible that you tried passing a concretized value to the pkt.extract() method but forgot to concretize it during declaration?

@fruffy
Copy link
Collaborator

fruffy commented Aug 1, 2024

The compiler should never throw an exception like Compiler Bug: to a user. This is a problem with the compiler regardless whether this is valid P4 or not.

@jaehyun1ee
Copy link
Author

@iamAyushChamoli

Hmm, I'm not sure if I can answer the question. The code example doesn't compile due to failure in the compiler's type checker, so I didn't have a chance to execute the code.

@asl
Copy link
Contributor

asl commented Mar 11, 2025

@vlstill Will #5133 handle this?

@vlstill vlstill self-assigned this Mar 11, 2025
vlstill added a commit to vlstill/p4c that referenced this issue Mar 11, 2025
Signed-off-by: Vladimír Štill <[email protected]>
@vlstill
Copy link
Contributor

vlstill commented Mar 11, 2025

@vlstill Will #5133 handle this?

Yes it does :-) I've added a commit with the test there (& validated it failed before). I was able to use the commented line without explicit specialization of extract. The problem was specialization order inside the compiler.

@vlstill vlstill added the core Topics concerning the core segments of the compiler (frontend, midend, parser) label Mar 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This behavior is unintended and should be fixed. core Topics concerning the core segments of the compiler (frontend, midend, parser)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants