Skip to content

Commit

Permalink
Auto merge of rust-lang#73446 - ecstatic-morse:issue-73431, r=pnkfelix
Browse files Browse the repository at this point in the history
Make novel structural match violations not a `bug`

Fixes (on master) rust-lang#73431.

Ideally, `CustomEq` would emit a strict subset of the structural match errors that are found by `search_for_structural_match_violation`, since it allows more cases due to value-based reasoning. However, const qualification is more conservative than `search_for_structural_match_violation` around associated constants, since qualification does not try to substitute type parameters.

In the long term, we should probably make const qualification work for generic associated constants, but I don't like extending its capabilities even further.

r? @pnkfelix
  • Loading branch information
bors committed Jun 18, 2020
2 parents e55d3f9 + 3a1207f commit 036b5fe
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/librustc_mir_build/hair/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
cv.ty, structural
);

// This can occur because const qualification treats all associated constants as
// opaque, whereas `search_for_structural_match_violation` tries to monomorphize them
// before it runs.
//
// FIXME(#73448): Find a way to bring const qualification into parity with
// `search_for_structural_match_violation`.
if structural.is_none() && mir_structural_match_violation {
bug!("MIR const-checker found novel structural match violation");
warn!("MIR const-checker found novel structural match violation. See #73448.");
return inlined_const_as_pat;
}

if let Some(non_sm_ty) = structural {
Expand Down
29 changes: 29 additions & 0 deletions src/test/ui/consts/const_in_pattern/issue-73431.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// run-pass

// Regression test for https://github.com/rust-lang/rust/issues/73431.

pub trait Zero {
const ZERO: Self;
}

impl Zero for usize {
const ZERO: Self = 0;
}

impl<T: Zero> Zero for Wrapper<T> {
const ZERO: Self = Wrapper(T::ZERO);
}

#[derive(Debug, PartialEq, Eq)]
pub struct Wrapper<T>(T);

fn is_zero(x: Wrapper<usize>) -> bool {
match x {
Zero::ZERO => true,
_ => false,
}
}

fn main() {
let _ = is_zero(Wrapper(42));
}

0 comments on commit 036b5fe

Please sign in to comment.