Skip to content

Commit c3d3727

Browse files
committed
Clarify specialize_one_pattern
Using a more error-oriented approache to `Option`.
1 parent 3551f1a commit c3d3727

File tree

1 file changed

+48
-57
lines changed

1 file changed

+48
-57
lines changed

src/librustc_mir_build/hair/pattern/_match.rs

Lines changed: 48 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,7 +2390,10 @@ fn specialize_one_pattern<'p, 'tcx>(
23902390
) -> Option<Fields<'p, 'tcx>> {
23912391
if let NonExhaustive = constructor {
23922392
// Only a wildcard pattern can match the special extra constructor
2393-
return if pat.is_wildcard() { Some(Fields::empty()) } else { None };
2393+
if !pat.is_wildcard() {
2394+
return None;
2395+
}
2396+
return Some(Fields::empty());
23942397
}
23952398

23962399
let result = match *pat.kind {
@@ -2400,12 +2403,11 @@ fn specialize_one_pattern<'p, 'tcx>(
24002403

24012404
PatKind::Variant { adt_def, variant_index, ref subpatterns, .. } => {
24022405
let variant = &adt_def.variants[variant_index];
2406+
if constructor != &Variant(variant.def_id) {
2407+
return None;
2408+
}
24032409
let is_non_exhaustive = cx.is_foreign_non_exhaustive_variant(pat.ty, variant);
2404-
Some(Variant(variant.def_id))
2405-
.filter(|variant_constructor| variant_constructor == constructor)
2406-
.map(|_| {
2407-
patterns_for_variant(cx, subpatterns, ctor_wild_subpatterns, is_non_exhaustive)
2408-
})
2410+
Some(patterns_for_variant(cx, subpatterns, ctor_wild_subpatterns, is_non_exhaustive))
24092411
}
24102412

24112413
PatKind::Leaf { ref subpatterns } => {
@@ -2425,11 +2427,10 @@ fn specialize_one_pattern<'p, 'tcx>(
24252427
// Shortcut for `n == 0` where no matter what `alloc` and `offset` we produce,
24262428
// the result would be exactly what we early return here.
24272429
if n == 0 {
2428-
if ctor_wild_subpatterns.len() as u64 == 0 {
2429-
return Some(Fields::empty());
2430-
} else {
2430+
if ctor_wild_subpatterns.len() as u64 != n {
24312431
return None;
24322432
}
2433+
return Some(Fields::empty());
24332434
}
24342435
match value.val {
24352436
ty::ConstKind::Value(ConstValue::ByRef { offset, alloc, .. }) => {
@@ -2463,76 +2464,66 @@ fn specialize_one_pattern<'p, 'tcx>(
24632464
constructor,
24642465
),
24652466
};
2466-
if ctor_wild_subpatterns.len() as u64 == n {
2467-
// convert a constant slice/array pattern to a list of patterns.
2468-
let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
2469-
let ptr = Pointer::new(AllocId(0), offset);
2470-
let pats = (0..n)
2471-
.map(|i| {
2472-
let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
2473-
let scalar = alloc.read_scalar(&cx.tcx, ptr, layout.size).ok()?;
2474-
let scalar = scalar.not_undef().ok()?;
2475-
let value = ty::Const::from_scalar(cx.tcx, scalar, ty);
2476-
let pattern =
2477-
Pat { ty, span: pat.span, kind: box PatKind::Constant { value } };
2478-
Some(&*cx.pattern_arena.alloc(pattern))
2479-
})
2480-
.collect::<Option<_>>()?;
2481-
Some(Fields::from_vec(pats))
2482-
} else {
2483-
None
2467+
if ctor_wild_subpatterns.len() as u64 != n {
2468+
return None;
24842469
}
2470+
// Convert a constant slice/array pattern to a list of patterns.
2471+
let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
2472+
let ptr = Pointer::new(AllocId(0), offset);
2473+
let pats = (0..n)
2474+
.map(|i| {
2475+
let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
2476+
let scalar = alloc.read_scalar(&cx.tcx, ptr, layout.size).ok()?;
2477+
let scalar = scalar.not_undef().ok()?;
2478+
let value = ty::Const::from_scalar(cx.tcx, scalar, ty);
2479+
let pattern = Pat { ty, span: pat.span, kind: box PatKind::Constant { value } };
2480+
Some(&*cx.pattern_arena.alloc(pattern))
2481+
})
2482+
.collect::<Option<_>>()?;
2483+
Some(Fields::from_vec(pats))
24852484
}
24862485

24872486
PatKind::Constant { .. } | PatKind::Range { .. } => {
24882487
// If the constructor is a:
24892488
// - Single value: add a row if the pattern contains the constructor.
24902489
// - Range: add a row if the constructor intersects the pattern.
24912490
if let IntRange(ctor) = constructor {
2492-
match IntRange::from_pat(cx.tcx, cx.param_env, pat) {
2493-
Some(pat) => ctor.intersection(cx.tcx, &pat).map(|_| {
2494-
// Constructor splitting should ensure that all intersections we encounter
2495-
// are actually inclusions.
2496-
assert!(ctor.is_subrange(&pat));
2497-
Fields::empty()
2498-
}),
2499-
_ => None,
2500-
}
2491+
let pat = IntRange::from_pat(cx.tcx, cx.param_env, pat)?;
2492+
ctor.intersection(cx.tcx, &pat)?;
2493+
// Constructor splitting should ensure that all intersections we encounter
2494+
// are actually inclusions.
2495+
assert!(ctor.is_subrange(&pat));
25012496
} else {
25022497
// Fallback for non-ranges and ranges that involve
25032498
// floating-point numbers, which are not conveniently handled
25042499
// by `IntRange`. For these cases, the constructor may not be a
25052500
// range so intersection actually devolves into being covered
25062501
// by the pattern.
2507-
constructor_covered_by_range(cx.tcx, cx.param_env, constructor, pat)
2508-
.map(|()| Fields::empty())
2502+
constructor_covered_by_range(cx.tcx, cx.param_env, constructor, pat)?;
25092503
}
2504+
Some(Fields::empty())
25102505
}
25112506

25122507
PatKind::Array { ref prefix, ref slice, ref suffix }
25132508
| PatKind::Slice { ref prefix, ref slice, ref suffix } => match *constructor {
25142509
Slice(_) => {
2510+
// Number of subpatterns for this pattern
25152511
let pat_len = prefix.len() + suffix.len();
2516-
if let Some(slice_count) = ctor_wild_subpatterns.len().checked_sub(pat_len) {
2517-
if slice_count == 0 || slice.is_some() {
2518-
Some(Fields::from_vec(
2519-
prefix
2520-
.iter()
2521-
.chain(
2522-
ctor_wild_subpatterns
2523-
.iter()
2524-
.skip(prefix.len())
2525-
.take(slice_count)
2526-
.chain(suffix.iter()),
2527-
)
2528-
.collect(),
2529-
))
2530-
} else {
2531-
None
2532-
}
2533-
} else {
2534-
None
2512+
// Number of subpatterns for this constructor
2513+
let arity = ctor_wild_subpatterns.len();
2514+
2515+
if slice.is_none() && arity != pat_len {
2516+
return None;
25352517
}
2518+
2519+
// Number of subpatterns matched by the `..` subslice pattern (is 0 for a slice
2520+
// pattern of fixed length).
2521+
let subslice_count = arity.checked_sub(pat_len)?;
2522+
let subslice_pats =
2523+
ctor_wild_subpatterns.iter().skip(prefix.len()).take(subslice_count);
2524+
Some(Fields::from_vec(
2525+
prefix.iter().chain(subslice_pats).chain(suffix.iter()).collect(),
2526+
))
25362527
}
25372528
ConstantValue(cv) => {
25382529
match slice_pat_covered_by_const(

0 commit comments

Comments
 (0)