@@ -32,6 +32,7 @@ use super::FnCtxt;
3232
3333use crate :: hir:: def_id:: DefId ;
3434use crate :: type_error_struct;
35+ use hir:: def_id:: LOCAL_CRATE ;
3536use rustc_errors:: { struct_span_err, Applicability , DiagnosticBuilder , ErrorGuaranteed } ;
3637use rustc_hir as hir;
3738use rustc_hir:: lang_items:: LangItem ;
@@ -40,7 +41,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase;
4041use rustc_middle:: ty:: cast:: { CastKind , CastTy } ;
4142use rustc_middle:: ty:: error:: TypeError ;
4243use rustc_middle:: ty:: subst:: SubstsRef ;
43- use rustc_middle:: ty:: { self , Ty , TypeAndMut , TypeVisitable } ;
44+ use rustc_middle:: ty:: { self , Ty , TypeAndMut , TypeVisitable , VariantDef } ;
4445use rustc_session:: lint;
4546use rustc_session:: Session ;
4647use rustc_span:: symbol:: sym;
@@ -173,6 +174,7 @@ pub enum CastError {
173174 /// or "a length". If this argument is None, then the metadata is unknown, for example,
174175 /// when we're typechecking a type parameter with a ?Sized bound.
175176 IntToFatCast ( Option < & ' static str > ) ,
177+ ForeignNonExhaustiveAdt ,
176178}
177179
178180impl From < ErrorGuaranteed > for CastError {
@@ -591,6 +593,17 @@ impl<'a, 'tcx> CastCheck<'tcx> {
591593 }
592594 err. emit ( ) ;
593595 }
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+ }
594607 }
595608 }
596609
@@ -789,6 +802,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
789802 _ => return Err ( CastError :: NonScalar ) ,
790803 } ;
791804
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+
792813 match ( t_from, t_cast) {
793814 // These types have invariants! can't cast into them.
794815 ( _, Int ( CEnum ) | FnPtr ) => Err ( CastError :: NonScalar ) ,
0 commit comments