Skip to content

Commit 928adba

Browse files
committed
Allow matching on consts of pattern types
1 parent 33658cb commit 928adba

File tree

3 files changed

+62
-7
lines changed
  • compiler
    • rustc_borrowck/src/type_check
    • rustc_mir_build/src/builder/matches
  • tests/ui/type/pattern_types

3 files changed

+62
-7
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,11 +2192,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21922192
}
21932193
}
21942194
CastKind::Transmute => {
2195-
span_mirbug!(
2196-
self,
2197-
rvalue,
2198-
"Unexpected CastKind::Transmute, which is not permitted in Analysis MIR",
2199-
);
2195+
let ty_from = op.ty(body, tcx);
2196+
match ty_from.kind() {
2197+
ty::Pat(base, _) if base == ty => {}
2198+
_ => span_mirbug!(
2199+
self,
2200+
rvalue,
2201+
"Unexpected CastKind::Transmute {ty_from:?} -> {ty:?}, which is not permitted in Analysis MIR",
2202+
),
2203+
}
22002204
}
22012205
}
22022206
}

compiler/rustc_mir_build/src/builder/matches/test.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
147147
let success_block = target_block(TestBranch::Success);
148148
let fail_block = target_block(TestBranch::Failure);
149149

150-
let expect_ty = value.ty();
151-
let expect = self.literal_operand(test.span, value);
150+
let mut expect_ty = value.ty();
151+
let mut expect = self.literal_operand(test.span, value);
152152

153153
let mut place = place;
154154
let mut block = block;
@@ -181,6 +181,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
181181
place = ref_str;
182182
ty = ref_str_ty;
183183
}
184+
&ty::Pat(base, _) => {
185+
assert_eq!(ty, value.ty());
186+
187+
let transmuted_place = self.temp(base, test.span);
188+
self.cfg.push_assign(
189+
block,
190+
self.source_info(scrutinee_span),
191+
transmuted_place,
192+
Rvalue::Cast(CastKind::Transmute, Operand::Copy(place), base),
193+
);
194+
195+
let transmuted_expect = self.temp(base, test.span);
196+
self.cfg.push_assign(
197+
block,
198+
self.source_info(test.span),
199+
transmuted_expect,
200+
Rvalue::Cast(CastKind::Transmute, expect, base),
201+
);
202+
203+
place = transmuted_place;
204+
expect = Operand::Copy(transmuted_expect);
205+
ty = base;
206+
expect_ty = base;
207+
}
184208
_ => {}
185209
}
186210

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#![feature(pattern_types, pattern_type_macro, structural_match)]
2+
3+
//@ check-pass
4+
5+
use std::marker::StructuralPartialEq;
6+
use std::pat::pattern_type;
7+
8+
struct Thing(pattern_type!(u32 is 1..));
9+
10+
impl StructuralPartialEq for Thing {}
11+
impl Eq for Thing {}
12+
impl PartialEq for Thing {
13+
fn eq(&self, other: &Thing) -> bool {
14+
// Never called, pattern matching of struct-eq types
15+
// destructures the type and equates its fields.
16+
todo!()
17+
}
18+
}
19+
20+
const TWO: Thing = Thing(unsafe { std::mem::transmute(2_u32) });
21+
22+
const _: () = match TWO {
23+
TWO => {}
24+
_ => unreachable!(),
25+
};
26+
27+
fn main() {}

0 commit comments

Comments
 (0)