@@ -699,6 +699,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
699
699
lp : & Rc < LoanPath < ' tcx > > ) {
700
700
debug ! ( "check_if_path_is_moved(id={}, use_kind={:?}, lp={})" ,
701
701
id, use_kind, lp. repr( self . bccx. tcx) ) ;
702
+
703
+ // FIXME (22079): if you find yourself tempted to cut and paste
704
+ // the body below and then specializing the error reporting,
705
+ // consider refactoring this instead!
706
+
702
707
let base_lp = owned_ptr_base_path_rc ( lp) ;
703
708
self . move_data . each_move_of ( id, & base_lp, |the_move, moved_lp| {
704
709
self . bccx . report_use_of_moved_value (
@@ -745,6 +750,29 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
745
750
use_kind, lp_base) ;
746
751
}
747
752
LpExtend ( ref lp_base, _, LpInterior ( InteriorField ( _) ) ) => {
753
+ match lp_base. to_type ( ) . sty {
754
+ ty:: ty_struct( def_id, _) | ty:: ty_enum( def_id, _) => {
755
+ if ty:: has_dtor ( self . tcx ( ) , def_id) {
756
+ // In the case where the owner implements drop, then
757
+ // the path must be initialized to prevent a case of
758
+ // partial reinitialization
759
+ //
760
+ // FIXME (22079): could refactor via hypothetical
761
+ // generalized check_if_path_is_moved
762
+ let loan_path = owned_ptr_base_path_rc ( lp_base) ;
763
+ self . move_data . each_move_of ( id, & loan_path, |_, _| {
764
+ self . bccx
765
+ . report_partial_reinitialization_of_uninitialized_structure (
766
+ span,
767
+ & * loan_path) ;
768
+ false
769
+ } ) ;
770
+ return ;
771
+ }
772
+ } ,
773
+ _ => { } ,
774
+ }
775
+
748
776
// assigning to `P.f` is ok if assigning to `P` is ok
749
777
self . check_if_assigned_path_is_moved ( id, span,
750
778
use_kind, lp_base) ;
@@ -775,10 +803,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
775
803
mark_variable_as_used_mut ( self , assignee_cmt) ;
776
804
}
777
805
}
806
+
778
807
return ;
779
808
}
780
809
781
- // Initializations are OK.
810
+ // Initializations are OK if and only if they aren't partial
811
+ // reinitialization of a partially-uninitialized structure.
782
812
if mode == euv:: Init {
783
813
return
784
814
}
0 commit comments