@@ -32,6 +32,7 @@ use super::FnCtxt;
32
32
33
33
use crate :: hir:: def_id:: DefId ;
34
34
use crate :: type_error_struct;
35
+ use hir:: def_id:: LOCAL_CRATE ;
35
36
use rustc_errors:: { struct_span_err, Applicability , DiagnosticBuilder , ErrorGuaranteed } ;
36
37
use rustc_hir as hir;
37
38
use rustc_hir:: lang_items:: LangItem ;
@@ -40,7 +41,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase;
40
41
use rustc_middle:: ty:: cast:: { CastKind , CastTy } ;
41
42
use rustc_middle:: ty:: error:: TypeError ;
42
43
use rustc_middle:: ty:: subst:: SubstsRef ;
43
- use rustc_middle:: ty:: { self , Ty , TypeAndMut , TypeVisitable } ;
44
+ use rustc_middle:: ty:: { self , Ty , TypeAndMut , TypeVisitable , VariantDef } ;
44
45
use rustc_session:: lint;
45
46
use rustc_session:: Session ;
46
47
use rustc_span:: symbol:: sym;
@@ -173,6 +174,7 @@ pub enum CastError {
173
174
/// or "a length". If this argument is None, then the metadata is unknown, for example,
174
175
/// when we're typechecking a type parameter with a ?Sized bound.
175
176
IntToFatCast ( Option < & ' static str > ) ,
177
+ ForeignNonExhaustiveAdt ,
176
178
}
177
179
178
180
impl From < ErrorGuaranteed > for CastError {
@@ -591,6 +593,17 @@ impl<'a, 'tcx> CastCheck<'tcx> {
591
593
}
592
594
err. emit ( ) ;
593
595
}
596
+ CastError :: ForeignNonExhaustiveAdt => {
597
+ make_invalid_casting_error (
598
+ fcx. tcx . sess ,
599
+ self . span ,
600
+ self . expr_ty ,
601
+ self . cast_ty ,
602
+ fcx,
603
+ )
604
+ . note ( "cannot cast a non-exhaustive enum defined in another crate" )
605
+ . emit ( ) ;
606
+ }
594
607
}
595
608
}
596
609
@@ -789,6 +802,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
789
802
_ => return Err ( CastError :: NonScalar ) ,
790
803
} ;
791
804
805
+ if let ty:: Adt ( adt_def, _) = * self . expr_ty . kind ( ) {
806
+ if adt_def. did ( ) . krate != LOCAL_CRATE {
807
+ if adt_def. variants ( ) . iter ( ) . any ( VariantDef :: is_field_list_non_exhaustive) {
808
+ return Err ( CastError :: ForeignNonExhaustiveAdt ) ;
809
+ }
810
+ }
811
+ }
812
+
792
813
match ( t_from, t_cast) {
793
814
// These types have invariants! can't cast into them.
794
815
( _, Int ( CEnum ) | FnPtr ) => Err ( CastError :: NonScalar ) ,
0 commit comments