Skip to content

Commit 4143379

Browse files
Rollup merge of #87161 - sexxi-goose:fix-issue-87097, r=nikomatsakis
RFC2229: Use the correct place type Closes #87097 The ICE occurred because instead of looking at the type of the place after all the projections are applied, we instead looked at the `base_ty` of the Place to decide whether a discriminant should be read of not. This lead to two issues: 1. the kind of the type is not necessarily `Adt` since we only look at the `base_ty`, it could be instead `Ref` for example 2. if the kind of the type is `Adt` you could still be looking at the wrong variant to make a decision on whether the discriminant should be read or not r? `@nikomatsakis`
2 parents c1b9bbf + 9fe470b commit 4143379

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

compiler/rustc_typeck/src/expr_use_visitor.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,16 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
252252
| PatKind::Path(..)
253253
| PatKind::Struct(..)
254254
| PatKind::Tuple(..) => {
255-
// If the PatKind is a TupleStruct, Struct or Tuple then we want to check
255+
// If the PatKind is a TupleStruct, Path, Struct or Tuple then we want to check
256256
// whether the Variant is a MultiVariant or a SingleVariant. We only want
257257
// to borrow discr if it is a MultiVariant.
258258
// If it is a SingleVariant and creates a binding we will handle that when
259259
// this callback gets called again.
260-
if let ty::Adt(def, _) = place.place.base_ty.kind() {
260+
261+
// Get the type of the Place after all projections have been applied
262+
let place_ty = place.place.ty();
263+
264+
if let ty::Adt(def, _) = place_ty.kind() {
261265
if def.variants.len() > 1 {
262266
needs_to_be_read = true;
263267
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// run-pass
2+
// edition:2021
3+
4+
enum Variant {
5+
A,
6+
B, //~ WARNING: variant is never constructed: `B`
7+
}
8+
9+
struct A {
10+
field: Variant,
11+
}
12+
13+
fn discriminant_is_a_ref() {
14+
let here = A { field: Variant::A };
15+
let out_ref = &here.field;
16+
17+
|| match out_ref { //~ WARNING: unused closure that must be used
18+
Variant::A => (),
19+
Variant::B => (),
20+
};
21+
}
22+
23+
fn discriminant_is_a_field() {
24+
let here = A { field: Variant::A };
25+
26+
|| match here.field { //~ WARNING: unused closure that must be used
27+
Variant::A => (),
28+
Variant::B => (),
29+
};
30+
}
31+
32+
fn main() {
33+
discriminant_is_a_ref();
34+
discriminant_is_a_field();
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
warning: variant is never constructed: `B`
2+
--> $DIR/issue-87097.rs:6:5
3+
|
4+
LL | B,
5+
| ^
6+
|
7+
= note: `#[warn(dead_code)]` on by default
8+
9+
warning: unused closure that must be used
10+
--> $DIR/issue-87097.rs:17:5
11+
|
12+
LL | / || match out_ref {
13+
LL | | Variant::A => (),
14+
LL | | Variant::B => (),
15+
LL | | };
16+
| |______^
17+
|
18+
= note: `#[warn(unused_must_use)]` on by default
19+
= note: closures are lazy and do nothing unless called
20+
21+
warning: unused closure that must be used
22+
--> $DIR/issue-87097.rs:26:5
23+
|
24+
LL | / || match here.field {
25+
LL | | Variant::A => (),
26+
LL | | Variant::B => (),
27+
LL | | };
28+
| |______^
29+
|
30+
= note: closures are lazy and do nothing unless called
31+
32+
warning: 3 warnings emitted
33+

0 commit comments

Comments
 (0)