Skip to content

Commit 0d034a2

Browse files
committed
Fix inhabitedness of non-exhaustive variants.
This commit ensures that non-exhaustive variants are considered inhabited when used in extern crates.
1 parent 0db087e commit 0d034a2

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

src/librustc/ty/inhabitedness/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,14 @@ impl<'a, 'gcx, 'tcx> VariantDef {
134134
AdtKind::Enum => true,
135135
AdtKind::Struct => false,
136136
};
137-
DefIdForest::union(tcx, self.fields.iter().map(|f| {
138-
f.uninhabited_from(tcx, substs, is_enum)
139-
}))
137+
// Non-exhaustive variants from other crates are always considered inhabited.
138+
if self.is_field_list_non_exhaustive() && !self.def_id.is_local() {
139+
DefIdForest::empty()
140+
} else {
141+
DefIdForest::union(tcx, self.fields.iter().map(|f| {
142+
f.uninhabited_from(tcx, substs, is_enum)
143+
}))
144+
}
140145
}
141146
}
142147

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,18 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
388388
}
389389
}
390390

391+
fn is_non_exhaustive_variant<'p>(&self, pattern: &'p Pattern<'tcx>) -> bool
392+
where 'a: 'p
393+
{
394+
match *pattern.kind {
395+
PatternKind::Variant { adt_def, variant_index, .. } => {
396+
let ref variant = adt_def.variants[variant_index];
397+
variant.is_field_list_non_exhaustive()
398+
}
399+
_ => false,
400+
}
401+
}
402+
391403
fn is_non_exhaustive_enum(&self, ty: Ty<'tcx>) -> bool {
392404
match ty.sty {
393405
ty::Adt(adt_def, ..) => adt_def.is_variant_list_non_exhaustive(),
@@ -1097,10 +1109,17 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
10971109
debug!("is_useful_expand_first_col: pcx={:#?}, expanding {:#?}", pcx, v[0]);
10981110

10991111
if let Some(constructors) = pat_constructors(cx, v[0], pcx) {
1100-
debug!("is_useful - expanding constructors: {:#?}", constructors);
1101-
split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c|
1102-
is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)
1103-
).find(|result| result.is_useful()).unwrap_or(NotUseful)
1112+
let is_declared_nonexhaustive = cx.is_non_exhaustive_variant(v[0]) && !cx.is_local(pcx.ty);
1113+
debug!("is_useful - expanding constructors: {:#?}, is_declared_nonexhaustive: {:?}",
1114+
constructors, is_declared_nonexhaustive);
1115+
1116+
if is_declared_nonexhaustive {
1117+
Useful
1118+
} else {
1119+
split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c|
1120+
is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)
1121+
).find(|result| result.is_useful()).unwrap_or(NotUseful)
1122+
}
11041123
} else {
11051124
debug!("is_useful - expanding wildcard");
11061125

src/test/ui/pattern/const-pat-ice.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1071:5
1+
thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1083:5
22
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
33

44
error: internal compiler error: unexpected panic

0 commit comments

Comments
 (0)