about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs19
1 files changed, 17 insertions, 2 deletions
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index a8be207dbb3..3d483e322a8 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -15,7 +15,7 @@ use rustc_index::vec::Idx;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::mir::FakeReadCause;
-use rustc_middle::ty::{self, adjustment, Ty, TyCtxt};
+use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt};
 use rustc_target::abi::VariantIdx;
 use std::iter;
 
@@ -845,5 +845,20 @@ fn delegate_consume<'a, 'tcx>(
 }
 
 fn is_multivariant_adt(ty: Ty<'tcx>) -> bool {
-    if let ty::Adt(def, _) = ty.kind() { def.variants.len() > 1 } else { false }
+    if let ty::Adt(def, _) = ty.kind() {
+        // Note that if a non-exhaustive SingleVariant is defined in another crate, we need
+        // to assume that more cases will be added to the variant in the future. This mean
+        // that we should handle non-exhaustive SingleVariant the same way we would handle
+        // a MultiVariant.
+        // If the variant is not local it must be defined in another crate.
+        let is_non_exhaustive = match def.adt_kind() {
+            AdtKind::Struct | AdtKind::Union => {
+                def.non_enum_variant().is_field_list_non_exhaustive()
+            }
+            AdtKind::Enum => def.is_variant_list_non_exhaustive(),
+        };
+        def.variants.len() > 1 || (!def.did.is_local() && is_non_exhaustive)
+    } else {
+        false
+    }
 }