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
Type unification fails with untyped integers. #764
Comments
I think that this is the correct behavior. Since this invocation is executed at runtime, the type of the argument must be specified. Note that we should allow int values for constructors. |
I don't know the type-checking intricacies in today's compiler, or whether there are more fundamental issues involved here, but the compiler does allow assignments to an lvalue of type bit or int, with a right-hand side that is an expression of type int (unlimited precision). Is there a reason that such 'auto-conversion from int to bit or int' is more difficult when the int is a parameter to an extern? |
The parameter in question has a type given by a type variable. The assignment is used to guess the value of the type variable. For some type variables we cannot allow the type to be int. |
Got it. Thanks for the explanation. |
Sorry, now I'm getting confused. Are we saying that a polymorphic function like I like to think of |
I realize that some externs assume their (generic) arguments are struct-like types, etc. -- e.g., consider But that's not the issue here -- we're just talking about being polymorphic over numeric base types. |
Int is not the union of Bit types, it is a separate type with similar operations syntactically, but whose semantics are actually different. It is reserved for values that are computed at compile-time. Any value that exists at runtime must have a type which is not int. |
What goes wrong if we added the constraint |
The motivation for this question is dealing with things like counter/meter indexes. In p4_14, it was pretty easy -- you just declare the size of the counter/meter and the compiler figures out the bit sizes of things from there: (eliding some stuff relating to counter type)
In p4_16/v1model (currently) you need explicit types and casts:
We could get rid of the need for the explicit
Arguably we should use a type parameter on the extern, but then the user has to write:
This at least puts the related numbers right next to each other, and forces the user to having matching types on the action parameter. |
From Chris's code snippet A: extern void func<T>(in T x);
...
func(5); I would say that TypeInference ought to infer that This relates to the discussion in p4-spec issue #331 about what There are trickier cases than snippet A. For example, snippet B from tuintt.p4.txt: extern void func<T>(in T x);
...
func({5}); I would say that TypeInference ought to infer that
But if you ask
Either way it's a compiler bug. We see that a violation has been introduced at or before pass BindTypeVariables but this violation is normally not tripped over until pass StrengthReduction. Interestingly, BindTypeVariables immediately follows TypeInference. I suspect that TypeInference is actually the pass that introduces the violation but in a form not detected by the dumping of p4 code. Or, to put my surmise in terms of how the current compiler thinks, in snippet B it seems that TypeInference failed to realize that it could not infer the type of T and it left a bomb behind instead. |
To me, this is the right way to think about the problem, and the right way to organize the compiler:
|
I have tagged this as enhancement, because I think that the fix is to just give a better error message. |
I hope we can close this issue. The issue about allowing 'int' as a type should be a spec issue. |
Yes, I think the revised error message (can't infer bit width for type parameter) is much clearer and tells the user what to do (use a constant with an explicit size). |
When trying to infer types to a type-abstract extern function, unification fails if the extern is called with an untyped integer:
gives an error
(using a typed integer, eg
8w5
works fine).This is an area that the spec doesn't really talk about, as we've deliberately tried to avoid getting into complex type inferencing issues. It kind-of makes sense to have untyped integers not infer a type for their argument, but it makes it inconvenient to have type-"friendly" methods in an architecture (extern functions that can take any type of argument without requiring an explicit cast), which can't then work with untyped integer constants.
The text was updated successfully, but these errors were encountered: