@@ -20,7 +20,10 @@ use core::prelude::*;
2020
2121use middle:: borrowck:: preserve:: { PreserveCondition , PcOk , PcIfPure } ;
2222use middle:: borrowck:: { Loan , bckerr, bckres, BorrowckCtxt , err_mutbl} ;
23+ use middle:: borrowck:: { LoanKind , TotalFreeze , PartialFreeze ,
24+ TotalTake , PartialTake , Immobile } ;
2325use middle:: borrowck:: { req_maps} ;
26+ use middle:: borrowck:: loan;
2427use middle:: mem_categorization:: { cat_binding, cat_discr, cmt, comp_variant} ;
2528use middle:: mem_categorization:: { mem_categorization_ctxt} ;
2629use middle:: mem_categorization:: { opt_deref_kind} ;
@@ -340,13 +343,22 @@ impl GatherLoanCtxt {
340343 fn guarantee_valid ( @mut self ,
341344 cmt : cmt ,
342345 req_mutbl : ast:: mutability ,
343- scope_r : ty:: Region ) {
346+ scope_r : ty:: Region )
347+ {
348+
349+ let loan_kind = match req_mutbl {
350+ m_mutbl => TotalTake ,
351+ m_imm => TotalFreeze ,
352+ m_const => Immobile
353+ } ;
344354
345355 self . bccx . stats . guaranteed_paths += 1 ;
346356
347- debug ! ( "guarantee_valid(cmt=%s, req_mutbl=%s, scope_r=%s)" ,
357+ debug ! ( "guarantee_valid(cmt=%s, req_mutbl=%?, \
358+ loan_kind=%?, scope_r=%s)",
348359 self . bccx. cmt_to_repr( cmt) ,
349- self . bccx. mut_to_str( req_mutbl) ,
360+ req_mutbl,
361+ loan_kind,
350362 region_to_str( self . tcx( ) , scope_r) ) ;
351363 let _i = indenter ( ) ;
352364
@@ -362,10 +374,10 @@ impl GatherLoanCtxt {
362374 // it within that scope, the loan will be detected and an
363375 // error will be reported.
364376 Some ( _) => {
365- match self . bccx . loan ( cmt, scope_r, req_mutbl ) {
377+ match loan :: loan ( self . bccx , cmt, scope_r, loan_kind ) {
366378 Err ( ref e) => { self . bccx . report ( ( * e) ) ; }
367379 Ok ( move loans) => {
368- self . add_loans ( cmt, req_mutbl , scope_r, move loans) ;
380+ self . add_loans ( cmt, loan_kind , scope_r, move loans) ;
369381 }
370382 }
371383 }
@@ -378,7 +390,7 @@ impl GatherLoanCtxt {
378390 // pointer is desired, that is ok as long as we are pure)
379391 None => {
380392 let result: bckres < PreserveCondition > = {
381- do self . check_mutbl ( req_mutbl , cmt) . chain |pc1| {
393+ do self . check_mutbl ( loan_kind , cmt) . chain |pc1| {
382394 do self . bccx . preserve ( cmt, scope_r,
383395 self . item_ub ,
384396 self . root_ub ) . chain |pc2| {
@@ -446,37 +458,41 @@ impl GatherLoanCtxt {
446458 // reqires an immutable pointer, but `f` lives in (aliased)
447459 // mutable memory.
448460 fn check_mutbl ( @mut self ,
449- req_mutbl : ast :: mutability ,
461+ loan_kind : LoanKind ,
450462 cmt : cmt )
451463 -> bckres < PreserveCondition > {
452- debug ! ( "check_mutbl(req_mutbl =%?, cmt.mutbl=%?)" ,
453- req_mutbl , cmt. mutbl) ;
464+ debug ! ( "check_mutbl(loan_kind =%?, cmt.mutbl=%?)" ,
465+ loan_kind , cmt. mutbl) ;
454466
455- if req_mutbl == m_const || req_mutbl == cmt. mutbl {
456- debug ! ( "required is const or they are the same" ) ;
457- Ok ( PcOk )
458- } else {
459- let e = bckerr { cmt : cmt, code : err_mutbl ( req_mutbl) } ;
460- if req_mutbl == m_imm {
461- // if this is an @mut box, then it's generally OK to borrow as
462- // &imm; this will result in a write guard
463- if cmt. cat . is_mutable_box ( ) {
467+ match loan_kind {
468+ Immobile => Ok ( PcOk ) ,
469+
470+ TotalTake | PartialTake => {
471+ if cmt. mutbl . is_mutable ( ) {
464472 Ok ( PcOk )
465473 } else {
466- // you can treat mutable things as imm if you are pure
467- debug ! ( "imm required, must be pure" ) ;
474+ Err ( bckerr { cmt : cmt, code : err_mutbl ( loan_kind) } )
475+ }
476+ }
468477
478+ TotalFreeze | PartialFreeze => {
479+ if cmt. mutbl . is_immutable ( ) {
480+ Ok ( PcOk )
481+ } else if cmt. cat . is_mutable_box ( ) {
482+ Ok ( PcOk )
483+ } else {
484+ // Eventually:
485+ let e = bckerr { cmt : cmt,
486+ code : err_mutbl ( loan_kind) } ;
469487 Ok ( PcIfPure ( e) )
470488 }
471- } else {
472- Err ( e)
473489 }
474490 }
475491 }
476492
477493 fn add_loans ( @mut self ,
478494 cmt : cmt ,
479- req_mutbl : ast :: mutability ,
495+ loan_kind : LoanKind ,
480496 scope_r : ty:: Region ,
481497 +loans : ~[ Loan ] ) {
482498 if loans. len ( ) == 0 {
@@ -526,7 +542,7 @@ impl GatherLoanCtxt {
526542
527543 self . add_loans_to_scope_id ( scope_id, move loans) ;
528544
529- if req_mutbl == m_imm && cmt. mutbl != m_imm {
545+ if loan_kind . is_freeze ( ) && ! cmt. mutbl . is_immutable ( ) {
530546 self . bccx . stats . loaned_paths_imm += 1 ;
531547
532548 if self . tcx ( ) . sess . borrowck_note_loan ( ) {
@@ -542,7 +558,9 @@ impl GatherLoanCtxt {
542558 fn add_loans_to_scope_id ( @mut self ,
543559 scope_id : ast:: node_id ,
544560 +loans : ~[ Loan ] ) {
545- debug ! ( "adding %u loans to scope_id %?" , loans. len( ) , scope_id) ;
561+ debug ! ( "adding %u loans to scope_id %?: %s" ,
562+ loans. len( ) , scope_id,
563+ str :: connect( loans. map( |l| self . bccx. loan_to_repr( l) ) , ", " ) ) ;
546564 match self . req_maps . req_loan_map . find ( & scope_id) {
547565 Some ( req_loans) => {
548566 req_loans. push_all ( loans) ;
0 commit comments