Skip to content

Commit f7168af

Browse files
authored
Rollup merge of #140707 - compiler-errors:range-pat-struct-norm, r=lcnr
Structurally normalize in range pattern checking in HIR typeck Fixes rust-lang/trait-system-refactor-initiative#200 r? lcnr
2 parents a054be7 + 9af6ee5 commit f7168af

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+17-9
Original file line numberDiff line numberDiff line change
@@ -650,14 +650,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
650650
match &pat.kind {
651651
// Type checking these product-like types successfully always require
652652
// that the expected type be of those types and not reference types.
653-
PatKind::Tuple(..)
654-
| PatKind::Range(..)
655-
| PatKind::Slice(..) => AdjustMode::peel_all(),
653+
PatKind::Tuple(..) | PatKind::Range(..) | PatKind::Slice(..) => AdjustMode::peel_all(),
656654
// When checking an explicit deref pattern, only peel reference types.
657655
// FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box
658656
// patterns may want `PeelKind::Implicit`, stopping on encountering a box.
659-
| PatKind::Box(_)
660-
| PatKind::Deref(_) => AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat },
657+
PatKind::Box(_) | PatKind::Deref(_) => {
658+
AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat }
659+
}
661660
// A never pattern behaves somewhat like a literal or unit variant.
662661
PatKind::Never => AdjustMode::peel_all(),
663662
// For patterns with paths, how we peel the scrutinee depends on the path's resolution.
@@ -679,25 +678,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
679678
&& self.tcx.features().deref_patterns()
680679
&& !matches!(lt.kind, PatExprKind::Lit { .. })
681680
{
682-
span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind);
681+
span_bug!(
682+
lt.span,
683+
"FIXME(deref_patterns): adjust mode unimplemented for {:?}",
684+
lt.kind
685+
);
683686
}
684687
// Call `resolve_vars_if_possible` here for inline const blocks.
685688
let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt));
686689
// If `deref_patterns` is enabled, allow `if let "foo" = &&"foo" {}`.
687690
if self.tcx.features().deref_patterns() {
688691
let mut peeled_ty = lit_ty;
689692
let mut pat_ref_layers = 0;
690-
while let ty::Ref(_, inner_ty, mutbl) = *peeled_ty.kind() {
693+
while let ty::Ref(_, inner_ty, mutbl) =
694+
*self.try_structurally_resolve_type(pat.span, peeled_ty).kind()
695+
{
691696
// We rely on references at the head of constants being immutable.
692697
debug_assert!(mutbl.is_not());
693698
pat_ref_layers += 1;
694699
peeled_ty = inner_ty;
695700
}
696-
AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: None, pat_ref_layers } }
701+
AdjustMode::Peel {
702+
kind: PeelKind::Implicit { until_adt: None, pat_ref_layers },
703+
}
697704
} else {
698705
if lit_ty.is_ref() { AdjustMode::Pass } else { AdjustMode::peel_all() }
699706
}
700-
},
707+
}
701708

702709
// Ref patterns are complicated, we handle them in `check_pat_ref`.
703710
PatKind::Ref(..)
@@ -928,6 +935,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
928935
// be peeled to `str` while ty here is still `&str`, if we don't
929936
// err early here, a rather confusing unification error will be
930937
// emitted instead).
938+
let ty = self.try_structurally_resolve_type(expr.span, ty);
931939
let fail =
932940
!(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error());
933941
Some((fail, ty, expr.span))
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ check-pass
2+
//@ revisions: current next
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] compile-flags: -Znext-solver
5+
6+
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/200>.
7+
// Make sure we structurally normalize in range pattern checking in HIR typeck.
8+
9+
trait Foo {
10+
type Bar;
11+
}
12+
13+
impl Foo for () {
14+
type Bar = i32;
15+
}
16+
17+
fn main() {
18+
const X: <() as Foo>::Bar = 0;
19+
20+
match 0 {
21+
X..=X => {}
22+
_ => {}
23+
}
24+
}

0 commit comments

Comments
 (0)