-
Notifications
You must be signed in to change notification settings - Fork 159
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
pattern analysis #3115
pattern analysis #3115
Conversation
554b585
to
e17919f
Compare
Build fails due to warnings. Let me fix it. |
e17919f
to
2961dea
Compare
it seems that warnings are not related my code. |
2961dea
to
94e6fa2
Compare
I found ci complained about structured bindings in my code which are not supported by gcc48. |
@tamaroning is this ready for review ? |
@P-E-P yes! |
I leave some comments here for review |
// Entry point for computing match usefulness and check exhaustiveness | ||
void | ||
check_match_usefulness (Resolver::TypeCheckContext *ctx, | ||
TyTy::BaseType *scrutinee_ty, HIR::MatchExpr &expr) | ||
{ | ||
// Lower the arms to a more convenient representation. | ||
std::vector<MatrixRow> rows; | ||
for (auto &arm : expr.get_match_cases ()) | ||
{ | ||
PatStack pats; | ||
MatchArm lowered = lower_arm (ctx, arm, scrutinee_ty); | ||
PatOrWild pat = PatOrWild::make_pattern (lowered.get_pat ()); | ||
pats.push (pat); | ||
rows.push_back (MatrixRow (pats, lowered.has_guard ())); | ||
} | ||
|
||
std::vector<PlaceInfo> place_infos = {{PlaceInfo (scrutinee_ty)}}; | ||
Matrix matrix{rows, place_infos}; | ||
|
||
WitnessMatrix witness = compute_exhaustiveness_and_usefulness (ctx, matrix); | ||
|
||
emit_exhaustiveness_error (ctx, expr, witness); | ||
} |
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 an entry point function that is called for each match expression.
It converts all arms in a match expr to a matrix for which we compute witness (counterexamples of exhaustiveness).
static DeconstructedPat | ||
lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern, | ||
TyTy::BaseType *scrutinee_ty) |
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.
All patterns in the match expr are lowered to DeconstructedPat.
We support struct and enum-variant patterns for now. Other unimplemented patterns are handled by converting them to wildcard.
// The core of the algorithm. It computes the usefulness and exhaustiveness of a | ||
// given matrix recursively. | ||
// TODO: calculate usefulness | ||
static WitnessMatrix | ||
compute_exhaustiveness_and_usefulness (Resolver::TypeCheckContext *ctx, | ||
Matrix &matrix) |
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.
Matrix | ||
Matrix::specialize (const Constructor &ctor) const |
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.
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 great work!
I am sorry, the review took quite some time. I don't know this part of the codebase as much as I'd like to and I had to read through rustc's exhaustiveness mechanism to understand most of it. Your comments on the PR were really helpful, thank you!
I've highlighted a few nits that you could change but this shall not overshade your impressive work.
{} | ||
|
||
void | ||
PatternChecker::visit (BorrowExpr &expr) |
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.
We really need a default Hir visitor somewhere, this file could be half as long with it. I do not think this should happen in this PR as it probably requires a huge amount of refactor.
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.
+1
struct | ||
{ | ||
int64_t lo; | ||
int64_t hi; | ||
} int_range; |
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.
We'll have to support more variants (floating point ranges are going away but we need to support them), we should probably use a struct with a fully qualified name in this union.
gcc/rust/ChangeLog: * Make-lang.in: Add rust-hir-pattern-analysis.o. * rust-session-manager.cc (Session::compile_crate): Add pattern analysis pass. * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): Do typecheck for subpatterns. * checks/errors/rust-hir-pattern-analysis.cc: New file. * checks/errors/rust-hir-pattern-analysis.h: New file. gcc/testsuite/ChangeLog: * rust/compile/exhaustiveness1.rs: New test. * rust/compile/exhaustiveness2.rs: New test. * rust/compile/exhaustiveness3.rs: New test. Signed-off-by: Raiki Tamura <tamaron1203@gmail.com>
94e6fa2
to
9020cc0
Compare
Thank you for your review! I have fixed the code. |
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.
Great work!
This patch adds a pattern analysis pass which detects non-exhaustive match patterns and finds witnesses (counterexamples).
The algorithm I implemented is based on one described in rustc documents. The current implementation lacks some patterns (OR, literals, ranges, etc.), which is handled by converting them into wildcard pattern.