-
Notifications
You must be signed in to change notification settings - Fork 447
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
[NFC] Eliminate the majority of dynamic_cast
usage in the codebase in favor of ICastable interface
#4382
Conversation
16be4f6
to
9d008e1
Compare
@@ -450,9 +450,8 @@ bool TypeUnification::unify(const BinaryConstraint *constraint) { | |||
} | |||
return constraint->reportError(constraints->getCurrentSubstitution()); | |||
} else if (dest->is<IR::Type_Declaration>() && src->is<IR::Type_Declaration>()) { | |||
bool canUnify = typeid(dest) == typeid(src) && dest->to<IR::Type_Declaration>()->name == |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pre-existing p4c bug. typeid(dest) == typeid(src)
is always true since both dest
and src
are of IR::Type*
types and typeid of these expressions matches. Changing to typeid(*dest) == typeid(*src)
would yield an error as it will consider generic substituted type and correspondent substitution to be separate types, when they are not. This change just removes always true condition. No test changes / failures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I definitely agree this was always-true conjunct. I am just wondering if this is a bug that we are not checking that the "kinds" of types match, but I would say it is probably safe to compare names only. It doubt there can be two entities with the same name and one declaring different kind of thing then the other (e.g. extern vs. parser), as you already have an example where the types does not match correctly, I agree with just dropping the conjunct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we take the exiting testcase for this code, then checking the typeids yields to very confusing error message. As I noted – the ordinary type and the substituted generic type are different nodes, so the typeid check would fail. However, the diagnostics produced is confusing, IIRC – cannot unify "int" with "int"
or something like this.
/// produces a message that is easier to debug. | ||
|
||
// default checkedTo implementation for nodes: just fallback to generic ICastable method | ||
template <typename T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that static_type_name
is defined only on concrete classes, not on interfaces. So, without this change use of checkedCastTo<T>
where T
is interface would produce compile error. As a result, one was able to use as<T>()
with T
being interface, but not checkedCastTo<T>()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe we should have static_type_name
generated also for interfaces. That is a separate task though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likely there was some rationale for this behavior. But maybe not. Though, I tend to agree that having a static type name everywhere would be be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likely there was some rationale for this behavior.
I added the ICastable class at some point because I noticed we repeated this pattern a lot. At the time node_type_name
and static_type_name
were simply not required. There is no reason not to add them, but it will likely take some effort across the entire compiler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fruffy Sorry, I do not follow. What are you suggesting? Indeed we can get rid of this implementation, however we'll end with less friendly error message. Some tests checks this btw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just clarifying on
Likely there was some rationale for this behavior.
There was not a concrete reason why things were done this way. No need to get rid of the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, as far as I can see static_type_name
and its usage in checkedTo
predates ICastable
. It's just checkedTo
is rarely used in the codebase for issue to trigger :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, there were a few nodes that implemented their own checkedTo
and to
but did not add the other functions. This class just unified things, the mangled typename was, well, "good enough".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this changes and for splitting them off, this is a great cleanup. I have just a few minor points and questions.
/// produces a message that is easier to debug. | ||
|
||
// default checkedTo implementation for nodes: just fallback to generic ICastable method | ||
template <typename T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe we should have static_type_name
generated also for interfaces. That is a separate task though.
@@ -450,9 +450,8 @@ bool TypeUnification::unify(const BinaryConstraint *constraint) { | |||
} | |||
return constraint->reportError(constraints->getCurrentSubstitution()); | |||
} else if (dest->is<IR::Type_Declaration>() && src->is<IR::Type_Declaration>()) { | |||
bool canUnify = typeid(dest) == typeid(src) && dest->to<IR::Type_Declaration>()->name == |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I definitely agree this was always-true conjunct. I am just wondering if this is a bug that we are not checking that the "kinds" of types match, but I would say it is probably safe to compare names only. It doubt there can be two entities with the same name and one declaring different kind of thing then the other (e.g. extern vs. parser), as you already have an example where the types does not match correctly, I agree with just dropping the conjunct.
@vlstill Added suggestions from the review, please check |
@@ -32,12 +32,18 @@ class ICastable { | |||
return to<T>() != nullptr; | |||
} | |||
|
|||
/// Tries to convert the class to type T. Returns a nullptr if the cast fails. | |||
/// Performs a checked cast. A BUG occurs if the cast fails. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::bad_cast
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's leave it as-is. As I said, custom-rtti
branch implements it via checkedCast
. So we won't change the comment all the time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly asking because it might take a while longer until the other PR is merged. But the comment was wrong in the first place and this is an improvement...
BUG and std::bad_cast are close enough in behavior so it is fine.
/// produces a message that is easier to debug. | ||
|
||
// default checkedTo implementation for nodes: just fallback to generic ICastable method | ||
template <typename T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likely there was some rationale for this behavior.
I added the ICastable class at some point because I noticed we repeated this pattern a lot. At the time node_type_name
and static_type_name
were simply not required. There is no reason not to add them, but it will likely take some effort across the entire compiler.
…or of ICastable interface
Co-authored-by: Vladimír Štill <git@vstill.eu>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no further comments from my side on this PR.
Head branch was pushed to by a user without write access
Co-authored-by: Vladimír Štill <git@vstill.eu>
@fruffy Looks like bazel is stuck, I cannot restart it sadly:
|
@fruffy Thanks for restarting! Could you please merge it for me? Auto-merge does not work since I do not have write access. |
If you plan on contributing more to p4c going forward we could make Kyle and you contributors with merge rights (https://github.com/orgs/p4lang/teams/p4c-committers). |
I do have other patches in my queue, yes. Just one step at a time :) |
Yes, that will be great. As Anton mentioned earlier, we have already made some of these changes to our compiler over a year ago, but haven't been able to upstream them yet for a number of reasons. But moving forward, we should be able to contribute more, I think. :) |
Could you send me an email (on my website) with your email addresses and some context? I can then start the discussion. |
This is a spin-off from #4377