Auto merge of #113470 - compiler-errors:new-solver-structurally-resolve-pat, r=lcnr
Structurally resolve in pattern matching when peeling refs in new solver Let me know if you want me to commit the minimized test: ```rust fn test() {} fn test2() {} fn main() { let tests: &[(_, fn())] = &[ ("test", test), ("test2", test2), ]; for (a, b) in tests { todo!(); } } ``` In that test above, the match scrutinee is `<std::vec::Iter<(&'static str, fn())> as Iterator>::Item`, which we cannot peel the refs from. We also need to structurally resolve in the loop, since structural resolve is inherently shallow. I haven't come up with a test where this matters, but I can if you care. Also, I removed two other calls to `resolve_vars_with_obligations` in diagnostics code that I'm pretty convinced are not useful. r? `@lcnr`
This commit is contained in:
commit
0a2681cc49
@ -335,8 +335,7 @@ fn peel_off_references(
|
|||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
mut def_bm: BindingMode,
|
mut def_bm: BindingMode,
|
||||||
) -> (Ty<'tcx>, BindingMode) {
|
) -> (Ty<'tcx>, BindingMode) {
|
||||||
let mut expected = self.resolve_vars_with_obligations(expected);
|
let mut expected = self.try_structurally_resolve_type(pat.span, expected);
|
||||||
|
|
||||||
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
// Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
|
||||||
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
|
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
|
||||||
// the `Some(5)` which is not of type Ref.
|
// the `Some(5)` which is not of type Ref.
|
||||||
@ -353,7 +352,7 @@ fn peel_off_references(
|
|||||||
// Preserve the reference type. We'll need it later during THIR lowering.
|
// Preserve the reference type. We'll need it later during THIR lowering.
|
||||||
pat_adjustments.push(expected);
|
pat_adjustments.push(expected);
|
||||||
|
|
||||||
expected = inner_ty;
|
expected = self.try_structurally_resolve_type(pat.span, inner_ty);
|
||||||
def_bm = ty::BindByReference(match def_bm {
|
def_bm = ty::BindByReference(match def_bm {
|
||||||
// If default binding mode is by value, make it `ref` or `ref mut`
|
// If default binding mode is by value, make it `ref` or `ref mut`
|
||||||
// (depending on whether we observe `&` or `&mut`).
|
// (depending on whether we observe `&` or `&mut`).
|
||||||
@ -627,6 +626,9 @@ fn check_pat_ident(
|
|||||||
local_ty
|
local_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// When a variable is bound several times in a `PatKind::Or`, it'll resolve all of the
|
||||||
|
/// subsequent bindings of the same name to the first usage. Verify that all of these
|
||||||
|
/// bindings have the same type by comparing them all against the type of that first pat.
|
||||||
fn check_binding_alt_eq_ty(
|
fn check_binding_alt_eq_ty(
|
||||||
&self,
|
&self,
|
||||||
ba: hir::BindingAnnotation,
|
ba: hir::BindingAnnotation,
|
||||||
@ -638,7 +640,7 @@ fn check_binding_alt_eq_ty(
|
|||||||
let var_ty = self.local_ty(span, var_id);
|
let var_ty = self.local_ty(span, var_id);
|
||||||
if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
|
if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
|
||||||
let hir = self.tcx.hir();
|
let hir = self.tcx.hir();
|
||||||
let var_ty = self.resolve_vars_with_obligations(var_ty);
|
let var_ty = self.resolve_vars_if_possible(var_ty);
|
||||||
let msg = format!("first introduced with type `{var_ty}` here");
|
let msg = format!("first introduced with type `{var_ty}` here");
|
||||||
err.span_label(hir.span(var_id), msg);
|
err.span_label(hir.span(var_id), msg);
|
||||||
let in_match = hir.parent_iter(var_id).any(|(_, n)| {
|
let in_match = hir.parent_iter(var_id).any(|(_, n)| {
|
||||||
@ -656,7 +658,7 @@ fn check_binding_alt_eq_ty(
|
|||||||
&mut err,
|
&mut err,
|
||||||
span,
|
span,
|
||||||
var_ty,
|
var_ty,
|
||||||
self.resolve_vars_with_obligations(ty),
|
self.resolve_vars_if_possible(ty),
|
||||||
ba,
|
ba,
|
||||||
);
|
);
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -1640,6 +1640,8 @@ fn report_projection_error(
|
|||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
|
// FIXME(-Ztrait-solver=next): For diagnostic purposes, it would be nice
|
||||||
|
// to deeply normalize this type.
|
||||||
let normalized_term =
|
let normalized_term =
|
||||||
ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);
|
ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
// run-pass
|
// run-pass
|
||||||
|
// revisions: current next
|
||||||
|
//[next] compile-flags: -Ztrait-solver=next
|
||||||
|
|
||||||
#![allow(unused_must_use)]
|
#![allow(unused_must_use)]
|
||||||
#![feature(c_unwind)]
|
#![feature(c_unwind)]
|
||||||
|
Loading…
Reference in New Issue
Block a user