Skip to content

Commit e587901

Browse files
committed
move logic for telling whether to peel smart pointers into a helper
The new logic for determining whether to peel references will depend on whether smart pointers need to be peeled before matching.
1 parent 2958d89 commit e587901

File tree

1 file changed

+27
-17
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+27
-17
lines changed

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -531,24 +531,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
531531
// If `deref_patterns` is enabled, peel a smart pointer from the scrutinee type. See the
532532
// examples in `tests/ui/pattern/deref_patterns/`.
533533
_ if self.tcx.features().deref_patterns()
534-
&& let AdjustMode::Peel { kind: PeelKind::Implicit { until_adt } } = adjust_mode
534+
&& let AdjustMode::Peel { kind: peel_kind } = adjust_mode
535535
&& pat.default_binding_modes
536-
// For simplicity, only apply overloaded derefs if `expected` is a known ADT.
537-
// FIXME(deref_patterns): we'll get better diagnostics for users trying to
538-
// implicitly deref generics if we allow them here, but primitives, tuples, and
539-
// inference vars definitely should be stopped. Figure out what makes most sense.
540-
&& let ty::Adt(scrutinee_adt, _) = *expected.kind()
541-
// Don't peel if the pattern type already matches the scrutinee. E.g., stop here if
542-
// matching on a `Cow<'a, T>` scrutinee with a `Cow::Owned(_)` pattern.
543-
&& until_adt != Some(scrutinee_adt.did())
544-
// At this point, the pattern isn't able to match `expected` without peeling. Check
545-
// that it implements `Deref` before assuming it's a smart pointer, to get a normal
546-
// type error instead of a missing impl error if not. This only checks for `Deref`,
547-
// not `DerefPure`: we require that too, but we want a trait error if it's missing.
548-
&& let Some(deref_trait) = self.tcx.lang_items().deref_trait()
549-
&& self
550-
.type_implements_trait(deref_trait, [expected], self.param_env)
551-
.may_apply() =>
536+
&& self.should_peel_smart_pointer(peel_kind, expected) =>
552537
{
553538
debug!("scrutinee ty {expected:?} is a smart pointer, inserting overloaded deref");
554539
// The scrutinee is a smart pointer; implicitly dereference it. This adds a
@@ -720,6 +705,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
720705
}
721706
}
722707

708+
/// Determine whether `expected` is a smart pointer type that should be peeled before matching.
709+
fn should_peel_smart_pointer(&self, peel_kind: PeelKind, expected: Ty<'tcx>) -> bool {
710+
// Explicit `deref!(_)` patterns match against smart pointers; don't peel in that case.
711+
if let PeelKind::Implicit { until_adt, .. } = peel_kind
712+
// For simplicity, only apply overloaded derefs if `expected` is a known ADT.
713+
// FIXME(deref_patterns): we'll get better diagnostics for users trying to
714+
// implicitly deref generics if we allow them here, but primitives, tuples, and
715+
// inference vars definitely should be stopped. Figure out what makes most sense.
716+
&& let ty::Adt(scrutinee_adt, _) = *expected.kind()
717+
// Don't peel if the pattern type already matches the scrutinee. E.g., stop here if
718+
// matching on a `Cow<'a, T>` scrutinee with a `Cow::Owned(_)` pattern.
719+
&& until_adt != Some(scrutinee_adt.did())
720+
// At this point, the pattern isn't able to match `expected` without peeling. Check
721+
// that it implements `Deref` before assuming it's a smart pointer, to get a normal
722+
// type error instead of a missing impl error if not. This only checks for `Deref`,
723+
// not `DerefPure`: we require that too, but we want a trait error if it's missing.
724+
&& let Some(deref_trait) = self.tcx.lang_items().deref_trait()
725+
&& self.type_implements_trait(deref_trait, [expected], self.param_env).may_apply()
726+
{
727+
true
728+
} else {
729+
false
730+
}
731+
}
732+
723733
fn check_pat_expr_unadjusted(&self, lt: &'tcx hir::PatExpr<'tcx>) -> Ty<'tcx> {
724734
let ty = match &lt.kind {
725735
rustc_hir::PatExprKind::Lit { lit, negated } => {

0 commit comments

Comments
 (0)