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

pattern analysis #3115

Merged
merged 1 commit into from
Sep 11, 2024
Merged

pattern analysis #3115

merged 1 commit into from
Sep 11, 2024

Conversation

tamaroning
Copy link
Contributor

@tamaroning tamaroning commented Aug 2, 2024

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.

gccrs: Implement initial pattern analysis pass.
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.

@tamaroning tamaroning force-pushed the feat/pattern-analysis branch 3 times, most recently from 554b585 to e17919f Compare August 7, 2024 17:27
@tamaroning tamaroning changed the title pattern analysis (wip) pattern analysis Aug 7, 2024
@tamaroning tamaroning marked this pull request as ready for review August 7, 2024 17:38
@P-E-P P-E-P self-requested a review August 7, 2024 20:44
@tamaroning
Copy link
Contributor Author

Build fails due to warnings. Let me fix it.

@tamaroning
Copy link
Contributor Author

it seems that warnings are not related my code.

@tamaroning
Copy link
Contributor Author

tamaroning commented Aug 22, 2024

I found ci complained about structured bindings in my code which are not supported by gcc48.
Now i fixed and pushed the code.

@P-E-P
Copy link
Member

P-E-P commented Aug 29, 2024

@tamaroning is this ready for review ?

@tamaroning
Copy link
Contributor Author

@P-E-P yes!

@tamaroning
Copy link
Contributor Author

I leave some comments here for review

Comment on lines +1529 to +1551
// 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);
}
Copy link
Contributor Author

@tamaroning tamaroning Aug 29, 2024

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).

Comment on lines +1264 to +1266
static DeconstructedPat
lower_pattern (Resolver::TypeCheckContext *ctx, HIR::Pattern *pattern,
TyTy::BaseType *scrutinee_ty)
Copy link
Contributor Author

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.

Comment on lines +1444 to +1449
// 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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +947 to +948
Matrix
Matrix::specialize (const Constructor &ctor) const
Copy link
Contributor Author

@tamaroning tamaroning Aug 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@P-E-P P-E-P left a 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)
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Comment on lines 242 to 246
struct
{
int64_t lo;
int64_t hi;
} int_range;
Copy link
Member

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/checks/errors/rust-hir-pattern-analysis.h Outdated Show resolved Hide resolved
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>
@tamaroning
Copy link
Contributor Author

Thank you for your review! I have fixed the code.

Copy link
Member

@P-E-P P-E-P left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@P-E-P P-E-P added this pull request to the merge queue Sep 11, 2024
Merged via the queue into Rust-GCC:master with commit 9941d6f Sep 11, 2024
11 of 12 checks passed
This was referenced Sep 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants