1919use self :: UseError :: * ;
2020
2121use middle:: borrowck:: * ;
22+ use middle:: borrowck:: LoanPathElem :: * ;
23+ use middle:: borrowck:: LoanPathKind :: * ;
2224use middle:: expr_use_visitor as euv;
2325use middle:: mem_categorization as mc;
2426use middle:: region;
@@ -33,49 +35,51 @@ use std::rc::Rc;
3335// be less precise in its handling of Box while still allowing moves out of a
3436// Box. They should be removed when OwnedPtr is removed from LoanPath.
3537
36- fn owned_ptr_base_path < ' a > ( loan_path : & ' a LoanPath ) -> & ' a LoanPath {
38+ fn owned_ptr_base_path < ' a , ' tcx > ( loan_path : & ' a LoanPath < ' tcx > ) -> & ' a LoanPath < ' tcx > {
3739 //! Returns the base of the leftmost dereference of an OwnedPtr in
3840 //! `loan_path`. If there is no dereference of an OwnedPtr in `loan_path`,
3941 //! then it just returns `loan_path` itself.
4042
41- return match owned_ptr_base_path_helper ( loan_path) {
43+ return match helper ( loan_path) {
4244 Some ( new_loan_path) => new_loan_path,
4345 None => loan_path. clone ( )
4446 } ;
4547
46- fn owned_ptr_base_path_helper < ' a > ( loan_path : & ' a LoanPath ) -> Option < & ' a LoanPath > {
47- match * loan_path {
48+ fn helper < ' a , ' tcx > ( loan_path : & ' a LoanPath < ' tcx > ) -> Option < & ' a LoanPath < ' tcx > > {
49+ match loan_path. kind {
4850 LpVar ( _) | LpUpvar ( _) => None ,
4951 LpExtend ( ref lp_base, _, LpDeref ( mc:: OwnedPtr ) ) => {
50- match owned_ptr_base_path_helper ( & * * lp_base) {
52+ match helper ( & * * lp_base) {
5153 v @ Some ( _) => v,
5254 None => Some ( & * * lp_base)
5355 }
5456 }
55- LpExtend ( ref lp_base, _, _) => owned_ptr_base_path_helper ( & * * lp_base)
57+ LpDowncast ( ref lp_base, _) |
58+ LpExtend ( ref lp_base, _, _) => helper ( & * * lp_base)
5659 }
5760 }
5861}
5962
60- fn owned_ptr_base_path_rc ( loan_path : & Rc < LoanPath > ) -> Rc < LoanPath > {
63+ fn owned_ptr_base_path_rc < ' tcx > ( loan_path : & Rc < LoanPath < ' tcx > > ) -> Rc < LoanPath < ' tcx > > {
6164 //! The equivalent of `owned_ptr_base_path` for an &Rc<LoanPath> rather than
6265 //! a &LoanPath.
6366
64- return match owned_ptr_base_path_helper ( loan_path) {
67+ return match helper ( loan_path) {
6568 Some ( new_loan_path) => new_loan_path,
6669 None => loan_path. clone ( )
6770 } ;
6871
69- fn owned_ptr_base_path_helper ( loan_path : & Rc < LoanPath > ) -> Option < Rc < LoanPath > > {
70- match * * loan_path {
72+ fn helper < ' tcx > ( loan_path : & Rc < LoanPath < ' tcx > > ) -> Option < Rc < LoanPath < ' tcx > > > {
73+ match loan_path. kind {
7174 LpVar ( _) | LpUpvar ( _) => None ,
7275 LpExtend ( ref lp_base, _, LpDeref ( mc:: OwnedPtr ) ) => {
73- match owned_ptr_base_path_helper ( lp_base) {
76+ match helper ( lp_base) {
7477 v @ Some ( _) => v,
7578 None => Some ( lp_base. clone ( ) )
7679 }
7780 }
78- LpExtend ( ref lp_base, _, _) => owned_ptr_base_path_helper ( lp_base)
81+ LpDowncast ( ref lp_base, _) |
82+ LpExtend ( ref lp_base, _, _) => helper ( lp_base)
7983 }
8084 }
8185}
@@ -84,7 +88,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> {
8488 bccx : & ' a BorrowckCtxt < ' a , ' tcx > ,
8589 dfcx_loans : & ' a LoanDataFlow < ' a , ' tcx > ,
8690 move_data : move_data:: FlowedMoveData < ' a , ' tcx > ,
87- all_loans : & ' a [ Loan ] ,
91+ all_loans : & ' a [ Loan < ' tcx > ] ,
8892}
8993
9094impl < ' a , ' tcx > euv:: Delegate < ' tcx > for CheckLoanCtxt < ' a , ' tcx > {
@@ -99,6 +103,11 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
99103 self . consume_common ( consume_id, consume_span, cmt, mode) ;
100104 }
101105
106+ fn matched_pat ( & mut self ,
107+ _matched_pat : & ast:: Pat ,
108+ _cmt : mc:: cmt ,
109+ _mode : euv:: MatchMode ) { }
110+
102111 fn consume_pat ( & mut self ,
103112 consume_pat : & ast:: Pat ,
104113 cmt : mc:: cmt < ' tcx > ,
@@ -183,7 +192,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
183192pub fn check_loans < ' a , ' b , ' c , ' tcx > ( bccx : & BorrowckCtxt < ' a , ' tcx > ,
184193 dfcx_loans : & LoanDataFlow < ' b , ' tcx > ,
185194 move_data : move_data:: FlowedMoveData < ' c , ' tcx > ,
186- all_loans : & [ Loan ] ,
195+ all_loans : & [ Loan < ' tcx > ] ,
187196 decl : & ast:: FnDecl ,
188197 body : & ast:: Block ) {
189198 debug ! ( "check_loans(body id={})" , body. id) ;
@@ -202,9 +211,9 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
202211}
203212
204213#[ deriving( PartialEq ) ]
205- enum UseError {
214+ enum UseError < ' tcx > {
206215 UseOk ,
207- UseWhileBorrowed ( /*loan*/ Rc < LoanPath > , /*loan*/ Span )
216+ UseWhileBorrowed ( /*loan*/ Rc < LoanPath < ' tcx > > , /*loan*/ Span )
208217}
209218
210219fn compatible_borrow_kinds ( borrow_kind1 : ty:: BorrowKind ,
@@ -216,7 +225,7 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
216225impl < ' a , ' tcx > CheckLoanCtxt < ' a , ' tcx > {
217226 pub fn tcx ( & self ) -> & ' a ty:: ctxt < ' tcx > { self . bccx . tcx }
218227
219- pub fn each_issued_loan ( & self , scope : region:: CodeExtent , op: |& Loan | -> bool)
228+ pub fn each_issued_loan ( & self , scope : region:: CodeExtent , op: |& Loan < ' tcx > | -> bool )
220229 -> bool {
221230 //! Iterates over each loan that has been issued
222231 //! on entrance to `scope`, regardless of whether it is
@@ -232,7 +241,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
232241
233242 pub fn each_in_scope_loan ( & self ,
234243 scope : region:: CodeExtent ,
235- op: |& Loan | -> bool)
244+ op: |& Loan < ' tcx > | -> bool )
236245 -> bool {
237246 //! Like `each_issued_loan()`, but only considers loans that are
238247 //! currently in scope.
@@ -249,8 +258,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
249258
250259 fn each_in_scope_loan_affecting_path ( & self ,
251260 scope : region:: CodeExtent ,
252- loan_path : & LoanPath ,
253- op: |& Loan | -> bool)
261+ loan_path : & LoanPath < ' tcx > ,
262+ op: |& Loan < ' tcx > | -> bool )
254263 -> bool {
255264 //! Iterates through all of the in-scope loans affecting `loan_path`,
256265 //! calling `op`, and ceasing iteration if `false` is returned.
@@ -294,10 +303,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
294303
295304 let mut loan_path = loan_path;
296305 loop {
297- match * loan_path {
306+ match loan_path. kind {
298307 LpVar ( _) | LpUpvar ( _) => {
299308 break ;
300309 }
310+ LpDowncast ( ref lp_base, _) |
301311 LpExtend ( ref lp_base, _, _) => {
302312 loan_path = & * * lp_base;
303313 }
@@ -363,8 +373,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
363373 }
364374
365375 pub fn report_error_if_loans_conflict ( & self ,
366- old_loan : & Loan ,
367- new_loan : & Loan ) {
376+ old_loan : & Loan < ' tcx > ,
377+ new_loan : & Loan < ' tcx > ) {
368378 //! Checks whether `old_loan` and `new_loan` can safely be issued
369379 //! simultaneously.
370380
@@ -383,10 +393,10 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
383393 }
384394
385395 pub fn report_error_if_loan_conflicts_with_restriction ( & self ,
386- loan1 : & Loan ,
387- loan2 : & Loan ,
388- old_loan : & Loan ,
389- new_loan : & Loan )
396+ loan1 : & Loan < ' tcx > ,
397+ loan2 : & Loan < ' tcx > ,
398+ old_loan : & Loan < ' tcx > ,
399+ new_loan : & Loan < ' tcx > )
390400 -> bool {
391401 //! Checks whether the restrictions introduced by `loan1` would
392402 //! prohibit `loan2`. Returns false if an error is reported.
@@ -549,7 +559,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
549559 true
550560 }
551561
552- fn is_local_variable_or_arg ( & self , cmt : mc:: cmt ) -> bool {
562+ fn is_local_variable_or_arg ( & self , cmt : mc:: cmt < ' tcx > ) -> bool {
553563 match cmt. cat {
554564 mc:: cat_local( _) => true ,
555565 _ => false
@@ -559,7 +569,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
559569 fn consume_common ( & self ,
560570 id : ast:: NodeId ,
561571 span : Span ,
562- cmt : mc:: cmt ,
572+ cmt : mc:: cmt < ' tcx > ,
563573 mode : euv:: ConsumeMode ) {
564574 match opt_loan_path ( & cmt) {
565575 Some ( lp) => {
@@ -600,7 +610,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
600610 fn check_for_copy_of_frozen_path ( & self ,
601611 id : ast:: NodeId ,
602612 span : Span ,
603- copy_path : & LoanPath ) {
613+ copy_path : & LoanPath < ' tcx > ) {
604614 match self . analyze_restrictions_on_use ( id, copy_path, ty:: ImmBorrow ) {
605615 UseOk => { }
606616 UseWhileBorrowed ( loan_path, loan_span) => {
@@ -621,7 +631,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
621631 fn check_for_move_of_borrowed_path ( & self ,
622632 id : ast:: NodeId ,
623633 span : Span ,
624- move_path : & LoanPath ,
634+ move_path : & LoanPath < ' tcx > ,
625635 move_kind : move_data:: MoveKind ) {
626636 // We want to detect if there are any loans at all, so we search for
627637 // any loans incompatible with MutBorrrow, since all other kinds of
@@ -652,9 +662,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
652662
653663 pub fn analyze_restrictions_on_use ( & self ,
654664 expr_id : ast:: NodeId ,
655- use_path : & LoanPath ,
665+ use_path : & LoanPath < ' tcx > ,
656666 borrow_kind : ty:: BorrowKind )
657- -> UseError {
667+ -> UseError < ' tcx > {
658668 debug ! ( "analyze_restrictions_on_use(expr_id={}, use_path={})" ,
659669 self . tcx( ) . map. node_to_string( expr_id) ,
660670 use_path. repr( self . tcx( ) ) ) ;
@@ -678,7 +688,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
678688 id : ast:: NodeId ,
679689 span : Span ,
680690 use_kind : MovedValueUseKind ,
681- lp : & Rc < LoanPath > ) {
691+ lp : & Rc < LoanPath < ' tcx > > ) {
682692 /*!
683693 * Reports an error if `expr` (which should be a path)
684694 * is using a moved/uninitialized value
@@ -702,7 +712,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
702712 id : ast:: NodeId ,
703713 span : Span ,
704714 use_kind : MovedValueUseKind ,
705- lp : & Rc < LoanPath > )
715+ lp : & Rc < LoanPath < ' tcx > > )
706716 {
707717 /*!
708718 * Reports an error if assigning to `lp` will use a
@@ -722,10 +732,15 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
722732 * (*p).x = 22; // not ok, p is uninitialized, can't deref
723733 */
724734
725- match * * lp {
735+ match lp . kind {
726736 LpVar ( _) | LpUpvar ( _) => {
727737 // assigning to `x` does not require that `x` is initialized
728738 }
739+ LpDowncast ( ref lp_base, _) => {
740+ // assigning to `(P->Variant).f` is ok if assigning to `P` is ok
741+ self . check_if_assigned_path_is_moved ( id, span,
742+ use_kind, lp_base) ;
743+ }
729744 LpExtend ( ref lp_base, _, LpInterior ( _) ) => {
730745 // assigning to `P.f` is ok if assigning to `P` is ok
731746 self . check_if_assigned_path_is_moved ( id, span,
@@ -864,7 +879,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
864879 cmt = b;
865880 }
866881
867- mc:: cat_downcast( b) |
882+ mc:: cat_downcast( b, _ ) |
868883 mc:: cat_interior( b, _) => {
869884 assert_eq ! ( cmt. mutbl, mc:: McInherited ) ;
870885 cmt = b;
@@ -915,11 +930,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
915930 }
916931 }
917932
918- fn check_for_assignment_to_borrowed_path (
919- this : & CheckLoanCtxt ,
933+ fn check_for_assignment_to_borrowed_path < ' a , ' tcx > (
934+ this : & CheckLoanCtxt < ' a , ' tcx > ,
920935 assignment_id : ast:: NodeId ,
921936 assignment_span : Span ,
922- assignee_cmt : mc:: cmt )
937+ assignee_cmt : mc:: cmt < ' tcx > )
923938 {
924939 //! Check for assignments that violate the terms of an
925940 //! outstanding loan.
@@ -939,7 +954,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
939954
940955 pub fn report_illegal_mutation ( & self ,
941956 span : Span ,
942- loan_path : & LoanPath ,
957+ loan_path : & LoanPath < ' tcx > ,
943958 loan : & Loan ) {
944959 self . bccx . span_err (
945960 span,
0 commit comments