Skip to content

Commit

Permalink
mir: Don't lose sub-patterns inside slice patterns.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Mar 10, 2016
1 parent 355abcb commit 48217d6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 11 deletions.
7 changes: 7 additions & 0 deletions src/librustc_mir/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,13 @@ pub struct MatchPair<'pat, 'tcx:'pat> {

// ... must match this pattern.
pattern: &'pat Pattern<'tcx>,

// HACK(eddyb) This is used to toggle whether a Slice pattern
// has had its length checked. This is only necessary because
// the "rest" part of the pattern right now has type &[T] and
// as such, it requires an Rvalue::Slice to be generated.
// See RFC 495 / issue #23121 for the eventual (proper) solution.
slice_len_checked: bool
}

#[derive(Clone, Debug, PartialEq)]
Expand Down
20 changes: 12 additions & 8 deletions src/librustc_mir/build/matches/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,18 @@ impl<'a,'tcx> Builder<'a,'tcx> {
Err(match_pair)
}

PatternKind::Array { ref prefix, ref slice, ref suffix } => {
PatternKind::Range { .. } |
PatternKind::Variant { .. } => {
// cannot simplify, test is required
Err(match_pair)
}

PatternKind::Slice { .. } if !match_pair.slice_len_checked => {
Err(match_pair)
}

PatternKind::Array { ref prefix, ref slice, ref suffix } |
PatternKind::Slice { ref prefix, ref slice, ref suffix } => {
unpack!(block = self.prefix_suffix_slice(&mut candidate.match_pairs,
block,
match_pair.lvalue.clone(),
Expand All @@ -105,13 +116,6 @@ impl<'a,'tcx> Builder<'a,'tcx> {
Ok(block)
}

PatternKind::Slice { .. } |
PatternKind::Range { .. } |
PatternKind::Variant { .. } => {
// cannot simplify, test is required
Err(match_pair)
}

PatternKind::Leaf { ref subpatterns } => {
// tuple struct, match subpats (if any)
candidate.match_pairs
Expand Down
25 changes: 22 additions & 3 deletions src/librustc_mir/build/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
}
}

PatternKind::Slice { ref prefix, ref slice, ref suffix } => {
PatternKind::Slice { ref prefix, ref slice, ref suffix }
if !match_pair.slice_len_checked => {
let len = prefix.len() + suffix.len();
let op = if slice.is_some() {
BinOp::Ge
Expand All @@ -89,6 +90,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
}

PatternKind::Array { .. } |
PatternKind::Slice { .. } |
PatternKind::Wild |
PatternKind::Binding { .. } |
PatternKind::Leaf { .. } |
Expand Down Expand Up @@ -413,9 +415,26 @@ impl<'a,'tcx> Builder<'a,'tcx> {
}
}

TestKind::Eq { .. } |
TestKind::Range { .. } |
// If we are performing a length check, then this
// informs slice patterns, but nothing else.
TestKind::Len { .. } => {
let pattern_test = self.test(&match_pair);
match *match_pair.pattern.kind {
PatternKind::Slice { .. } if pattern_test.kind == test.kind => {
let mut new_candidate = candidate.clone();

// Set up the MatchKind to simplify this like an array.
new_candidate.match_pairs[match_pair_index]
.slice_len_checked = true;
resulting_candidates[0].push(new_candidate);
true
}
_ => false
}
}

TestKind::Eq { .. } |
TestKind::Range { .. } => {
// These are all binary tests.
//
// FIXME(#29623) we can be more clever here
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/build/matches/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
MatchPair {
lvalue: lvalue,
pattern: pattern,
slice_len_checked: false,
}
}
}

2 comments on commit 48217d6

@nikomatsakis
Copy link

Choose a reason for hiding this comment

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

ok. (sigh. we should really patch this up.)

@eddyb
Copy link
Owner Author

@eddyb eddyb commented on 48217d6 Mar 15, 2016

Choose a reason for hiding this comment

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

@arielb1 has opened rust-lang#32202 which we can land after this PR.

Please sign in to comment.