Skip to content

Commit 8b4f040

Browse files
committed
check is violation ty included by const val
1 parent 4e0fb98 commit 8b4f040

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_hir::def_id::DefId;
33
use rustc_index::Idx;
44
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
55
use rustc_infer::traits::Obligation;
6-
use rustc_middle::mir;
6+
use rustc_middle::mir::{self, ConstValue};
77
use rustc_middle::thir::{FieldPat, Pat, PatKind};
88
use rustc_middle::ty::{self, Ty, TyCtxt, ValTree};
99
use rustc_session::lint;
@@ -198,7 +198,7 @@ impl<'tcx> ConstToPat<'tcx> {
198198
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
199199
let kind = PatKind::Error(e);
200200
return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
201-
} else if let ty::Adt(..) = cv.ty().kind() && matches!(cv, mir::Const::Val(..)) {
201+
} else if let ty::Adt(..) = cv.ty().kind() && let mir::Const::Val(const_val, const_ty) = cv && self.is_ty_included_by_const_val(const_val, const_ty, non_sm_ty) {
202202
// This branch is only entered when the current `cv` is `mir::Const::Val`.
203203
// This is because `mir::Const::ty` has already been handled by `Self::recur`
204204
// and the invalid types may be ignored.
@@ -266,6 +266,34 @@ impl<'tcx> ConstToPat<'tcx> {
266266
inlined_const_as_pat
267267
}
268268

269+
// Check if `child` is included within the const value.
270+
fn is_ty_included_by_const_val(
271+
&self,
272+
const_val: ConstValue<'tcx>,
273+
parent: Ty<'tcx>,
274+
child: Ty<'tcx>,
275+
) -> bool {
276+
if parent == self.tcx().normalize_erasing_regions(self.param_env, child) {
277+
return true;
278+
}
279+
match parent.kind() {
280+
ty::Adt(..) | ty::Tuple(_) | ty::Array(..) => {
281+
let destructured = self
282+
.tcx()
283+
.try_destructure_mir_constant_for_user_output(
284+
const_val,
285+
self.tcx().normalize_erasing_regions(self.param_env, parent),
286+
)
287+
.unwrap();
288+
destructured
289+
.fields
290+
.iter()
291+
.any(|field| self.is_ty_included_by_const_val(field.0, field.1, child))
292+
}
293+
_ => false,
294+
}
295+
}
296+
269297
#[instrument(level = "trace", skip(self), ret)]
270298
fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
271299
// double-check there even *is* a semantic `PartialEq` to dispatch to.

tests/ui/pattern/issue-117626.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
3+
#[derive(PartialEq)]
4+
struct NonMatchable;
5+
6+
impl Eq for NonMatchable {}
7+
8+
#[derive(PartialEq, Eq)]
9+
enum Foo {
10+
A(NonMatchable),
11+
B(*const u8),
12+
}
13+
14+
const CONST: Foo = Foo::B(std::ptr::null());
15+
16+
fn main() {
17+
match CONST {
18+
CONST => 0,
19+
_ => 1,
20+
};
21+
}

0 commit comments

Comments
 (0)