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 Fixesrust-lang/trait-system-refactor-initiative#200 r? lcnr
2 parents a054be7 + 9af6ee5 commit f7168af

2 files changed

Lines changed: 41 additions & 9 deletions

File tree

‎compiler/rustc_hir_typeck/src/pat.rs‎

Lines changed: 17 additions & 9 deletions
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
ifself.tcx.features().deref_patterns(){
688691
letmut peeled_ty = lit_ty;
689692
letmut pat_ref_layers = 0;
690-
whilelet ty::Ref(_, inner_ty, mutbl) = *peeled_ty.kind(){
693+
whilelet 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))
Lines changed: 24 additions & 0 deletions
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+
traitFoo{
10+
typeBar;
11+
}
12+
13+
implFoofor(){
14+
typeBar = i32;
15+
}
16+
17+
fnmain(){
18+
constX: <()asFoo>::Bar = 0;
19+
20+
match0{
21+
X..=X => {}
22+
_ => {}
23+
}
24+
}

0 commit comments

Comments
 (0)