Skip to content

Commit

Permalink
Auto merge of #113470 - compiler-errors:new-solver-structurally-resol…
Browse files Browse the repository at this point in the history
…ve-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`
  • Loading branch information
bors committed Jul 11, 2023
2 parents b3ab80c + 846d54f commit 0a2681c
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 5 deletions.
12 changes: 7 additions & 5 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
mut def_bm: 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,
// for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
// the `Some(5)` which is not of type Ref.
Expand All @@ -353,7 +352,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Preserve the reference type. We'll need it later during THIR lowering.
pat_adjustments.push(expected);

expected = inner_ty;
expected = self.try_structurally_resolve_type(pat.span, inner_ty);
def_bm = ty::BindByReference(match def_bm {
// If default binding mode is by value, make it `ref` or `ref mut`
// (depending on whether we observe `&` or `&mut`).
Expand Down Expand Up @@ -627,6 +626,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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(
&self,
ba: hir::BindingAnnotation,
Expand All @@ -638,7 +640,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let var_ty = self.local_ty(span, var_id);
if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
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");
err.span_label(hir.span(var_id), msg);
let in_match = hir.parent_iter(var_id).any(|(_, n)| {
Expand All @@ -656,7 +658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&mut err,
span,
var_ty,
self.resolve_vars_with_obligations(ty),
self.resolve_vars_if_possible(ty),
ba,
);
err.emit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
)
.into(),
};
// FIXME(-Ztrait-solver=next): For diagnostic purposes, it would be nice
// to deeply normalize this type.
let normalized_term =
ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/panics/abort-on-panic.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// run-pass
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next

#![allow(unused_must_use)]
#![feature(c_unwind)]
Expand Down

0 comments on commit 0a2681c

Please sign in to comment.