19
19
use self :: UseError :: * ;
20
20
21
21
use middle:: borrowck:: * ;
22
+ use middle:: borrowck:: LoanPathElem :: * ;
23
+ use middle:: borrowck:: LoanPathKind :: * ;
22
24
use middle:: expr_use_visitor as euv;
23
25
use middle:: mem_categorization as mc;
24
26
use middle:: region;
@@ -33,49 +35,51 @@ use std::rc::Rc;
33
35
// be less precise in its handling of Box while still allowing moves out of a
34
36
// Box. They should be removed when OwnedPtr is removed from LoanPath.
35
37
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 > {
37
39
//! Returns the base of the leftmost dereference of an OwnedPtr in
38
40
//! `loan_path`. If there is no dereference of an OwnedPtr in `loan_path`,
39
41
//! then it just returns `loan_path` itself.
40
42
41
- return match owned_ptr_base_path_helper ( loan_path) {
43
+ return match helper ( loan_path) {
42
44
Some ( new_loan_path) => new_loan_path,
43
45
None => loan_path. clone ( )
44
46
} ;
45
47
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 {
48
50
LpVar ( _) | LpUpvar ( _) => None ,
49
51
LpExtend ( ref lp_base, _, LpDeref ( mc:: OwnedPtr ) ) => {
50
- match owned_ptr_base_path_helper ( & * * lp_base) {
52
+ match helper ( & * * lp_base) {
51
53
v @ Some ( _) => v,
52
54
None => Some ( & * * lp_base)
53
55
}
54
56
}
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)
56
59
}
57
60
}
58
61
}
59
62
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 > > {
61
64
//! The equivalent of `owned_ptr_base_path` for an &Rc<LoanPath> rather than
62
65
//! a &LoanPath.
63
66
64
- return match owned_ptr_base_path_helper ( loan_path) {
67
+ return match helper ( loan_path) {
65
68
Some ( new_loan_path) => new_loan_path,
66
69
None => loan_path. clone ( )
67
70
} ;
68
71
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 {
71
74
LpVar ( _) | LpUpvar ( _) => None ,
72
75
LpExtend ( ref lp_base, _, LpDeref ( mc:: OwnedPtr ) ) => {
73
- match owned_ptr_base_path_helper ( lp_base) {
76
+ match helper ( lp_base) {
74
77
v @ Some ( _) => v,
75
78
None => Some ( lp_base. clone ( ) )
76
79
}
77
80
}
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)
79
83
}
80
84
}
81
85
}
@@ -84,7 +88,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> {
84
88
bccx : & ' a BorrowckCtxt < ' a , ' tcx > ,
85
89
dfcx_loans : & ' a LoanDataFlow < ' a , ' tcx > ,
86
90
move_data : move_data:: FlowedMoveData < ' a , ' tcx > ,
87
- all_loans : & ' a [ Loan ] ,
91
+ all_loans : & ' a [ Loan < ' tcx > ] ,
88
92
}
89
93
90
94
impl < ' a , ' tcx > euv:: Delegate < ' tcx > for CheckLoanCtxt < ' a , ' tcx > {
@@ -99,6 +103,11 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
99
103
self . consume_common ( consume_id, consume_span, cmt, mode) ;
100
104
}
101
105
106
+ fn matched_pat ( & mut self ,
107
+ _matched_pat : & ast:: Pat ,
108
+ _cmt : mc:: cmt ,
109
+ _mode : euv:: MatchMode ) { }
110
+
102
111
fn consume_pat ( & mut self ,
103
112
consume_pat : & ast:: Pat ,
104
113
cmt : mc:: cmt < ' tcx > ,
@@ -183,7 +192,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
183
192
pub fn check_loans < ' a , ' b , ' c , ' tcx > ( bccx : & BorrowckCtxt < ' a , ' tcx > ,
184
193
dfcx_loans : & LoanDataFlow < ' b , ' tcx > ,
185
194
move_data : move_data:: FlowedMoveData < ' c , ' tcx > ,
186
- all_loans : & [ Loan ] ,
195
+ all_loans : & [ Loan < ' tcx > ] ,
187
196
decl : & ast:: FnDecl ,
188
197
body : & ast:: Block ) {
189
198
debug ! ( "check_loans(body id={})" , body. id) ;
@@ -202,9 +211,9 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
202
211
}
203
212
204
213
#[ deriving( PartialEq ) ]
205
- enum UseError {
214
+ enum UseError < ' tcx > {
206
215
UseOk ,
207
- UseWhileBorrowed ( /*loan*/ Rc < LoanPath > , /*loan*/ Span )
216
+ UseWhileBorrowed ( /*loan*/ Rc < LoanPath < ' tcx > > , /*loan*/ Span )
208
217
}
209
218
210
219
fn compatible_borrow_kinds ( borrow_kind1 : ty:: BorrowKind ,
@@ -216,7 +225,7 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
216
225
impl < ' a , ' tcx > CheckLoanCtxt < ' a , ' tcx > {
217
226
pub fn tcx ( & self ) -> & ' a ty:: ctxt < ' tcx > { self . bccx . tcx }
218
227
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 )
220
229
-> bool {
221
230
//! Iterates over each loan that has been issued
222
231
//! on entrance to `scope`, regardless of whether it is
@@ -232,7 +241,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
232
241
233
242
pub fn each_in_scope_loan ( & self ,
234
243
scope : region:: CodeExtent ,
235
- op: |& Loan | -> bool)
244
+ op: |& Loan < ' tcx > | -> bool )
236
245
-> bool {
237
246
//! Like `each_issued_loan()`, but only considers loans that are
238
247
//! currently in scope.
@@ -249,8 +258,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
249
258
250
259
fn each_in_scope_loan_affecting_path ( & self ,
251
260
scope : region:: CodeExtent ,
252
- loan_path : & LoanPath ,
253
- op: |& Loan | -> bool)
261
+ loan_path : & LoanPath < ' tcx > ,
262
+ op: |& Loan < ' tcx > | -> bool )
254
263
-> bool {
255
264
//! Iterates through all of the in-scope loans affecting `loan_path`,
256
265
//! calling `op`, and ceasing iteration if `false` is returned.
@@ -294,10 +303,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
294
303
295
304
let mut loan_path = loan_path;
296
305
loop {
297
- match * loan_path {
306
+ match loan_path. kind {
298
307
LpVar ( _) | LpUpvar ( _) => {
299
308
break ;
300
309
}
310
+ LpDowncast ( ref lp_base, _) |
301
311
LpExtend ( ref lp_base, _, _) => {
302
312
loan_path = & * * lp_base;
303
313
}
@@ -363,8 +373,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
363
373
}
364
374
365
375
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 > ) {
368
378
//! Checks whether `old_loan` and `new_loan` can safely be issued
369
379
//! simultaneously.
370
380
@@ -383,10 +393,10 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
383
393
}
384
394
385
395
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 > )
390
400
-> bool {
391
401
//! Checks whether the restrictions introduced by `loan1` would
392
402
//! prohibit `loan2`. Returns false if an error is reported.
@@ -549,7 +559,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
549
559
true
550
560
}
551
561
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 {
553
563
match cmt. cat {
554
564
mc:: cat_local( _) => true ,
555
565
_ => false
@@ -559,7 +569,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
559
569
fn consume_common ( & self ,
560
570
id : ast:: NodeId ,
561
571
span : Span ,
562
- cmt : mc:: cmt ,
572
+ cmt : mc:: cmt < ' tcx > ,
563
573
mode : euv:: ConsumeMode ) {
564
574
match opt_loan_path ( & cmt) {
565
575
Some ( lp) => {
@@ -600,7 +610,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
600
610
fn check_for_copy_of_frozen_path ( & self ,
601
611
id : ast:: NodeId ,
602
612
span : Span ,
603
- copy_path : & LoanPath ) {
613
+ copy_path : & LoanPath < ' tcx > ) {
604
614
match self . analyze_restrictions_on_use ( id, copy_path, ty:: ImmBorrow ) {
605
615
UseOk => { }
606
616
UseWhileBorrowed ( loan_path, loan_span) => {
@@ -621,7 +631,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
621
631
fn check_for_move_of_borrowed_path ( & self ,
622
632
id : ast:: NodeId ,
623
633
span : Span ,
624
- move_path : & LoanPath ,
634
+ move_path : & LoanPath < ' tcx > ,
625
635
move_kind : move_data:: MoveKind ) {
626
636
// We want to detect if there are any loans at all, so we search for
627
637
// any loans incompatible with MutBorrrow, since all other kinds of
@@ -652,9 +662,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
652
662
653
663
pub fn analyze_restrictions_on_use ( & self ,
654
664
expr_id : ast:: NodeId ,
655
- use_path : & LoanPath ,
665
+ use_path : & LoanPath < ' tcx > ,
656
666
borrow_kind : ty:: BorrowKind )
657
- -> UseError {
667
+ -> UseError < ' tcx > {
658
668
debug ! ( "analyze_restrictions_on_use(expr_id={}, use_path={})" ,
659
669
self . tcx( ) . map. node_to_string( expr_id) ,
660
670
use_path. repr( self . tcx( ) ) ) ;
@@ -678,7 +688,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
678
688
id : ast:: NodeId ,
679
689
span : Span ,
680
690
use_kind : MovedValueUseKind ,
681
- lp : & Rc < LoanPath > ) {
691
+ lp : & Rc < LoanPath < ' tcx > > ) {
682
692
/*!
683
693
* Reports an error if `expr` (which should be a path)
684
694
* is using a moved/uninitialized value
@@ -702,7 +712,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
702
712
id : ast:: NodeId ,
703
713
span : Span ,
704
714
use_kind : MovedValueUseKind ,
705
- lp : & Rc < LoanPath > )
715
+ lp : & Rc < LoanPath < ' tcx > > )
706
716
{
707
717
/*!
708
718
* Reports an error if assigning to `lp` will use a
@@ -722,10 +732,15 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
722
732
* (*p).x = 22; // not ok, p is uninitialized, can't deref
723
733
*/
724
734
725
- match * * lp {
735
+ match lp . kind {
726
736
LpVar ( _) | LpUpvar ( _) => {
727
737
// assigning to `x` does not require that `x` is initialized
728
738
}
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
+ }
729
744
LpExtend ( ref lp_base, _, LpInterior ( _) ) => {
730
745
// assigning to `P.f` is ok if assigning to `P` is ok
731
746
self . check_if_assigned_path_is_moved ( id, span,
@@ -864,7 +879,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
864
879
cmt = b;
865
880
}
866
881
867
- mc:: cat_downcast( b) |
882
+ mc:: cat_downcast( b, _ ) |
868
883
mc:: cat_interior( b, _) => {
869
884
assert_eq ! ( cmt. mutbl, mc:: McInherited ) ;
870
885
cmt = b;
@@ -915,11 +930,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
915
930
}
916
931
}
917
932
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 > ,
920
935
assignment_id : ast:: NodeId ,
921
936
assignment_span : Span ,
922
- assignee_cmt : mc:: cmt )
937
+ assignee_cmt : mc:: cmt < ' tcx > )
923
938
{
924
939
//! Check for assignments that violate the terms of an
925
940
//! outstanding loan.
@@ -939,7 +954,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
939
954
940
955
pub fn report_illegal_mutation ( & self ,
941
956
span : Span ,
942
- loan_path : & LoanPath ,
957
+ loan_path : & LoanPath < ' tcx > ,
943
958
loan : & Loan ) {
944
959
self . bccx . span_err (
945
960
span,
0 commit comments