Skip to content

Commit abebe8a

Browse files
committed
Use T as the subpattern type of Box<T>
The subpattern type of boxes being nil does not make sense because of box patterns. They should have their inner type as the subpattern type.
1 parent dfb8c80 commit abebe8a

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

src/librustc_const_eval/_match.rs

+20-15
Original file line numberDiff line numberDiff line change
@@ -774,21 +774,26 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
774774
},
775775
ty::TyRef(_, ref ty_and_mut) => vec![ty_and_mut.ty],
776776
ty::TyAdt(adt, substs) => {
777-
adt.variants[ctor.variant_index_for_adt(adt)].fields.iter().map(|field| {
778-
let is_visible = adt.is_enum()
779-
|| field.vis.is_accessible_from(cx.module, cx.tcx);
780-
if is_visible {
781-
field.ty(cx.tcx, substs)
782-
} else {
783-
// Treat all non-visible fields as nil. They
784-
// can't appear in any other pattern from
785-
// this match (because they are private),
786-
// so their type does not matter - but
787-
// we don't want to know they are
788-
// uninhabited.
789-
cx.tcx.mk_nil()
790-
}
791-
}).collect()
777+
if adt.is_box() {
778+
// Use T as the sub pattern type of Box<T>.
779+
vec![substs[0].as_type().unwrap()]
780+
} else {
781+
adt.variants[ctor.variant_index_for_adt(adt)].fields.iter().map(|field| {
782+
let is_visible = adt.is_enum()
783+
|| field.vis.is_accessible_from(cx.module, cx.tcx);
784+
if is_visible {
785+
field.ty(cx.tcx, substs)
786+
} else {
787+
// Treat all non-visible fields as nil. They
788+
// can't appear in any other pattern from
789+
// this match (because they are private),
790+
// so their type does not matter - but
791+
// we don't want to know they are
792+
// uninhabited.
793+
cx.tcx.mk_nil()
794+
}
795+
}).collect()
796+
}
792797
}
793798
_ => vec![],
794799
}

src/test/run-pass/issue-42679.rs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(box_syntax)]
12+
#![feature(box_patterns)]
13+
14+
#[derive(Debug, PartialEq)]
15+
enum Test {
16+
Foo(usize),
17+
Bar(isize),
18+
}
19+
20+
fn main() {
21+
let a = box Test::Foo(10);
22+
let b = box Test::Bar(-20);
23+
match (a, b) {
24+
(_, box Test::Foo(_)) => unreachable!(),
25+
(box Test::Foo(x), b) => {
26+
assert_eq!(x, 10);
27+
assert_eq!(b, box Test::Bar(-20));
28+
},
29+
_ => unreachable!(),
30+
}
31+
}

0 commit comments

Comments
 (0)