Structurally resolve in check_ref_cast and calc_adjust_mode
This commit is contained in:
parent
1973872013
commit
9af6ee50ed
2 changed files with 41 additions and 9 deletions
|
|
@ -650,14 +650,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
match &pat.kind {
|
||||
// Type checking these product-like types successfully always require
|
||||
// that the expected type be of those types and not reference types.
|
||||
PatKind::Tuple(..)
|
||||
| PatKind::Range(..)
|
||||
| PatKind::Slice(..) => AdjustMode::peel_all(),
|
||||
PatKind::Tuple(..) | PatKind::Range(..) | PatKind::Slice(..) => AdjustMode::peel_all(),
|
||||
// When checking an explicit deref pattern, only peel reference types.
|
||||
// FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box
|
||||
// patterns may want `PeelKind::Implicit`, stopping on encountering a box.
|
||||
| PatKind::Box(_)
|
||||
| PatKind::Deref(_) => AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat },
|
||||
PatKind::Box(_) | PatKind::Deref(_) => {
|
||||
AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat }
|
||||
}
|
||||
// A never pattern behaves somewhat like a literal or unit variant.
|
||||
PatKind::Never => AdjustMode::peel_all(),
|
||||
// For patterns with paths, how we peel the scrutinee depends on the path's resolution.
|
||||
|
|
@ -679,7 +678,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&& self.tcx.features().deref_patterns()
|
||||
&& !matches!(lt.kind, PatExprKind::Lit { .. })
|
||||
{
|
||||
span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind);
|
||||
span_bug!(
|
||||
lt.span,
|
||||
"FIXME(deref_patterns): adjust mode unimplemented for {:?}",
|
||||
lt.kind
|
||||
);
|
||||
}
|
||||
// Call `resolve_vars_if_possible` here for inline const blocks.
|
||||
let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt));
|
||||
|
|
@ -687,17 +690,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if self.tcx.features().deref_patterns() {
|
||||
let mut peeled_ty = lit_ty;
|
||||
let mut pat_ref_layers = 0;
|
||||
while let ty::Ref(_, inner_ty, mutbl) = *peeled_ty.kind() {
|
||||
while let ty::Ref(_, inner_ty, mutbl) =
|
||||
*self.try_structurally_resolve_type(pat.span, peeled_ty).kind()
|
||||
{
|
||||
// We rely on references at the head of constants being immutable.
|
||||
debug_assert!(mutbl.is_not());
|
||||
pat_ref_layers += 1;
|
||||
peeled_ty = inner_ty;
|
||||
}
|
||||
AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: None, pat_ref_layers } }
|
||||
AdjustMode::Peel {
|
||||
kind: PeelKind::Implicit { until_adt: None, pat_ref_layers },
|
||||
}
|
||||
} else {
|
||||
if lit_ty.is_ref() { AdjustMode::Pass } else { AdjustMode::peel_all() }
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Ref patterns are complicated, we handle them in `check_pat_ref`.
|
||||
PatKind::Ref(..)
|
||||
|
|
@ -928,6 +935,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// be peeled to `str` while ty here is still `&str`, if we don't
|
||||
// err early here, a rather confusing unification error will be
|
||||
// emitted instead).
|
||||
let ty = self.try_structurally_resolve_type(expr.span, ty);
|
||||
let fail =
|
||||
!(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error());
|
||||
Some((fail, ty, expr.span))
|
||||
|
|
|
|||
24
tests/ui/pattern/normalize-ty-in-range.rs
Normal file
24
tests/ui/pattern/normalize-ty-in-range.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//@ check-pass
|
||||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/200>.
|
||||
// Make sure we structurally normalize in range pattern checking in HIR typeck.
|
||||
|
||||
trait Foo {
|
||||
type Bar;
|
||||
}
|
||||
|
||||
impl Foo for () {
|
||||
type Bar = i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
const X: <() as Foo>::Bar = 0;
|
||||
|
||||
match 0 {
|
||||
X..=X => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue