Skip to content

Fully destructure slice and array constants into patterns #77390

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

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler/rustc_mir_build/src/thir/pattern/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,11 @@ enum Constructor<'tcx> {
Single,
/// Enum variants.
Variant(DefId),
/// String literals
/// String literals. These have their own variant, because they behave essentially like
/// `&[u8]`, but there's no way to pattern match on parts of strings. So we could convert them
/// to slice constructors, but then we'd have to special case other code sites to not treat them
/// *exactly* like slice constructors. It seems simpler overall to just give them their own
/// variant.
Copy link
Member

@RalfJung RalfJung Oct 12, 2020

Choose a reason for hiding this comment

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

Is it true that Constructor is used only for exhaustiveness checking, but does not actually affect MIR construction for pattern matching?

If yes, I think it would be good to mention that in the enum Constructor doc comment (but doesn't have to be in this PR).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't actually know. Decisions on MIR match construction may be made on information obtained via Constructor.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it's only for exhaustiveness

Copy link
Member

Choose a reason for hiding this comment

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

I know because I've changed Constructor without any code breaking outside of this _match.rs.

Str(&'tcx ty::Const<'tcx>),
Copy link
Member

Choose a reason for hiding this comment

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

Okay so this type is indeed only used for exhaustiveness checking, that's why we do not need consts in here? Maybe add that to the type doccomment.

Copy link
Member

Choose a reason for hiding this comment

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

Why are strings special here?

/// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
IntRange(IntRange<'tcx>),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ crate enum PatKind<'tcx> {
subpattern: Pat<'tcx>,
},

/// Opaque constant. This will be treated as a single, but unknown value.
/// Except for `&str`, which will be handled as a string pattern and thus exhaustiveness
/// checking will detect if you use the same string twice in different patterns.
Constant {
Copy link
Member

@Nadrieril Nadrieril Oct 12, 2020

Choose a reason for hiding this comment

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

This comment should also mention int ranges etc then

value: &'tcx ty::Const<'tcx>,
},
Expand Down