@@ -73,10 +73,10 @@ fn encl_region_of_def(fcx: @fn_ctxt, def: ast::def) -> ty::Region {
73
73
}
74
74
75
75
impl @rcx {
76
- fn resolve_type ( unresolved_ty : ty:: t ) -> Option < ty:: t > {
76
+ fn resolve_type ( unresolved_ty : ty:: t ) -> ty:: t {
77
77
/*!
78
78
* Try to resolve the type for the given node, returning
79
- * None if an error results. Note that we never care
79
+ * t_err if an error results. Note that we never care
80
80
* about the details of the error, the same error will be
81
81
* detected and reported in the writeback phase.
82
82
*
@@ -104,13 +104,13 @@ impl @rcx {
104
104
*/
105
105
match resolve_type ( self . fcx . infcx ( ) , unresolved_ty,
106
106
resolve_and_force_all_but_regions) {
107
- Ok ( t) => Some ( t ) ,
108
- Err ( _) => None
107
+ Ok ( t) => t ,
108
+ Err ( _) => ty :: mk_err ( self . fcx . tcx ( ) )
109
109
}
110
110
}
111
111
112
112
/// Try to resolve the type for the given node.
113
- fn resolve_node_type ( id : ast:: node_id ) -> Option < ty:: t > {
113
+ fn resolve_node_type ( id : ast:: node_id ) -> ty:: t {
114
114
self . resolve_type ( self . fcx . node_ty ( id) )
115
115
}
116
116
}
@@ -181,6 +181,12 @@ fn visit_block(b: ast::blk, &&rcx: @rcx, v: rvt) {
181
181
fn visit_expr( expr : @ast:: expr , & & rcx: @rcx , v : rvt ) {
182
182
debug ! ( "visit_expr(e=%s)" , rcx. fcx. expr_to_str( expr) ) ;
183
183
184
+ for rcx. fcx. inh. adjustments. find( expr. id) . each |adjustment| {
185
+ for adjustment. autoref. each |autoref| {
186
+ guarantor:: for_autoref( rcx, expr, * adjustment, autoref) ;
187
+ }
188
+ }
189
+
184
190
match /*bad*/ copy expr. node {
185
191
ast : : expr_path( * ) => {
186
192
// Avoid checking the use of local variables, as we
@@ -250,15 +256,14 @@ fn visit_expr(expr: @ast::expr, &&rcx: @rcx, v: rvt) {
250
256
// particular case. There is an extensive comment on the
251
257
// function check_cast_for_escaping_regions() in kind.rs
252
258
// explaining how it goes about doing that.
253
- for rcx. resolve_node_type( expr. id) . each |target_ty| {
254
- match ty:: get ( * target_ty) . sty {
255
- ty:: ty_trait( _, _, vstore_slice( trait_region) ) => {
256
- let source_ty = rcx. fcx . expr_ty ( source) ;
257
- constrain_regions_in_type ( rcx, trait_region,
258
- expr. span , source_ty) ;
259
- }
260
- _ => ( )
259
+ let target_ty = rcx. resolve_node_type( expr. id) ;
260
+ match ty:: get( target_ty) . sty {
261
+ ty : : ty_trait( _, _, vstore_slice( trait_region) ) => {
262
+ let source_ty = rcx. fcx. expr_ty( source) ;
263
+ constrain_regions_in_type( rcx, trait_region,
264
+ expr. span, source_ty) ;
261
265
}
266
+ _ => ( )
262
267
}
263
268
}
264
269
@@ -271,16 +276,15 @@ fn visit_expr(expr: @ast::expr, &&rcx: @rcx, v: rvt) {
271
276
}
272
277
273
278
ast:: expr_fn( * ) | ast:: expr_fn_block( * ) => {
274
- for rcx. resolve_node_type( expr. id) . each |function_type| {
275
- match ty:: get ( * function_type) . sty {
276
- ty:: ty_fn( ref fn_ty) => {
277
- if fn_ty. meta . proto == ast:: ProtoBorrowed {
278
- constrain_free_variables (
279
- rcx, fn_ty. meta . region , expr) ;
280
- }
279
+ let function_type = rcx. resolve_node_type( expr. id) ;
280
+ match ty:: get( function_type) . sty {
281
+ ty : : ty_fn( ref fn_ty) => {
282
+ if fn_ty. meta. proto == ast:: ProtoBorrowed {
283
+ constrain_free_variables(
284
+ rcx, fn_ty. meta. region, expr) ;
281
285
}
282
- _ => ( )
283
286
}
287
+ _ => ( )
284
288
}
285
289
}
286
290
@@ -409,15 +413,10 @@ fn constrain_regions_in_type_of_node(
409
413
// Try to resolve the type. If we encounter an error, then typeck
410
414
// is going to fail anyway, so just stop here and let typeck
411
415
// report errors later on in the writeback phase.
412
- let ty = match rcx. resolve_node_type( id) {
413
- None => { return true ; }
414
- Some ( ty) => { ty }
415
- } ;
416
-
416
+ let ty = rcx. resolve_node_type( id) ;
417
417
debug ! ( "constrain_regions_in_type_of_node(\
418
418
ty=%s, id=%d, encl_region=%?)",
419
419
ty_to_str( tcx, ty) , id, encl_region) ;
420
-
421
420
constrain_regions_in_type( rcx, encl_region, span, ty)
422
421
}
423
422
@@ -567,6 +566,30 @@ mod guarantor {
567
566
}
568
567
}
569
568
569
+ pub fn for_autoref( rcx: @rcx,
570
+ expr: @ast:: expr,
571
+ adjustment: & ty:: AutoAdjustment ,
572
+ autoref: & ty:: AutoRef )
573
+ {
574
+ /*!
575
+ *
576
+ * Computes the guarantor for an expression that has an
577
+ * autoref adjustment and links it to the lifetime of the
578
+ * autoref. This is only important when auto re-borrowing
579
+ * region pointers.
580
+ */
581
+
582
+ debug!( "guarantor:: for_autoref( expr=%s) ", rcx. fcx. expr_to_str( expr) ) ;
583
+ let _i = :: util:: common:: indenter( ) ;
584
+
585
+ let mut expr_ct = categorize_unadjusted( rcx, expr) ;
586
+ expr_ct = apply_autoderefs(
587
+ rcx, expr, adjustment. autoderefs, expr_ct) ;
588
+ for expr_ct. cat. guarantor. each |g| {
589
+ infallibly_mk_subr( rcx, true , expr. span, autoref. region, * g) ;
590
+ }
591
+ }
592
+
570
593
fn link(
571
594
rcx: @rcx,
572
595
span: span,
@@ -589,9 +612,10 @@ mod guarantor {
589
612
// this routine is used for the result of ref bindings and &
590
613
// expressions, both of which always yield a region variable, so
591
614
// mk_subr should never fail.
592
- for rcx. resolve_node_type( id) . each |rptr_ty| {
593
- debug ! ( "rptr_ty=%s" , ty_to_str( rcx. fcx. ccx. tcx, * rptr_ty) ) ;
594
- let r = ty:: ty_region( * rptr_ty) ;
615
+ let rptr_ty = rcx. resolve_node_type( id) ;
616
+ if !ty:: type_contains_err( rptr_ty) {
617
+ debug!( "rptr_ty=%s", ty_to_str( rcx. fcx. ccx. tcx, rptr_ty) ) ;
618
+ let r = ty:: ty_region( rptr_ty) ;
595
619
infallibly_mk_subr( rcx, true, span, r, bound) ;
596
620
}
597
621
}
@@ -608,6 +632,11 @@ mod guarantor {
608
632
pointer: PointerCat
609
633
}
610
634
635
+ struct ExprCategorizationType {
636
+ cat: ExprCategorization ,
637
+ ty: ty:: t
638
+ }
639
+
611
640
fn guarantor( rcx: @rcx, expr: @ast:: expr) -> Option <ty:: Region > {
612
641
debug!( "guarantor( expr=%s) ", rcx. fcx. expr_to_str( expr) ) ;
613
642
match expr. node {
@@ -683,52 +712,76 @@ mod guarantor {
683
712
debug!( "categorize( expr=%s) ", rcx. fcx. expr_to_str( expr) ) ;
684
713
let _i = :: util:: common:: indenter( ) ;
685
714
686
- let tcx = rcx. fcx. ccx. tcx;
687
- if rcx. fcx. ccx. method_map. contains_key( expr. id) {
688
- debug!( "method call") ;
689
- return id_categorization( rcx, None , expr. id) ;
690
- }
691
-
692
- let expr_ty = match rcx. resolve_node_type( expr. id) {
693
- None => { return id_categorization( rcx, None , expr. id) ; }
694
- Some ( t) => { t }
695
- } ;
696
- let mut cat = ExprCategorization {
697
- guarantor: guarantor( rcx, expr) ,
698
- pointer: pointer_categorize( expr_ty)
699
- } ;
700
-
701
- debug!( "before adjustments, cat=%?", cat) ;
715
+ let mut expr_ct = categorize_unadjusted( rcx, expr) ;
716
+ debug!( "before adjustments, cat=%?", expr_ct. cat) ;
702
717
703
718
for rcx. fcx. inh. adjustments. find( expr. id) . each |adjustment| {
704
719
debug ! ( "adjustment=%?" , adjustment) ;
705
- for uint:: range( 0 , adjustment. autoderefs) |_| {
706
- cat. guarantor = guarantor_of_deref( & cat) ;
707
720
708
- match ty:: deref( tcx, expr_ty, true) {
709
- Some ( t) => {
710
- cat. pointer = pointer_categorize( t. ty) ;
711
- }
712
- None => {
713
- tcx. sess. span_bug(
714
- expr. span,
715
- fmt!( "Autoderef but type not derefable: %s",
716
- ty_to_str( tcx, expr_ty) ) ) ;
717
- }
718
- }
721
+ expr_ct = apply_autoderefs(
722
+ rcx, expr, adjustment. autoderefs, expr_ct) ;
719
723
720
- debug!( "autoderef, cat=%?", cat) ;
724
+ for adjustment. autoref. each |autoref| {
725
+ expr_ct. cat. guarantor = None ;
726
+ expr_ct. cat. pointer = BorrowedPointer ( autoref. region) ;
727
+ debug!( "autoref, cat=%?", expr_ct. cat) ;
721
728
}
729
+ }
722
730
723
- for adjustment. autoref. each |autoref| {
724
- cat. guarantor = None ;
725
- cat. pointer = BorrowedPointer ( autoref. region) ;
726
- debug!( "autoref, cat=%?", cat) ;
731
+ debug!( "result=%?", expr_ct. cat) ;
732
+ return expr_ct. cat;
733
+ }
734
+
735
+ fn categorize_unadjusted( rcx: @rcx,
736
+ expr: @ast:: expr) -> ExprCategorizationType {
737
+ debug!( "categorize_unadjusted( expr=%s) ", rcx. fcx. expr_to_str( expr) ) ;
738
+ let _i = :: util:: common:: indenter( ) ;
739
+
740
+ let guarantor = {
741
+ if rcx. fcx. ccx. method_map. contains_key( expr. id) {
742
+ None
743
+ } else {
744
+ guarantor( rcx, expr)
727
745
}
746
+ } ;
747
+
748
+ let expr_ty = rcx. resolve_node_type( expr. id) ;
749
+ ExprCategorizationType {
750
+ cat: ExprCategorization {
751
+ guarantor: guarantor,
752
+ pointer: pointer_categorize( expr_ty)
753
+ } ,
754
+ ty: expr_ty
728
755
}
756
+ }
729
757
730
- debug!( "result=%?", cat) ;
731
- return cat;
758
+ fn apply_autoderefs(
759
+ +rcx: @rcx,
760
+ +expr: @ast:: expr,
761
+ +autoderefs: uint,
762
+ +ct: ExprCategorizationType ) -> ExprCategorizationType
763
+ {
764
+ let mut ct = ct;
765
+ let tcx = rcx. fcx. ccx. tcx;
766
+ for uint:: range( 0 , autoderefs) |_| {
767
+ ct. cat. guarantor = guarantor_of_deref( & ct. cat) ;
768
+
769
+ match ty:: deref( tcx, ct. ty, true) {
770
+ Some ( mt) => {
771
+ ct. ty = mt. ty;
772
+ ct. cat. pointer = pointer_categorize( ct. ty) ;
773
+ }
774
+ None => {
775
+ tcx. sess. span_bug(
776
+ expr. span,
777
+ fmt!( "Autoderef but type not derefable: %s",
778
+ ty_to_str( tcx, ct. ty) ) ) ;
779
+ }
780
+ }
781
+
782
+ debug!( "autoderef, cat=%?", ct. cat) ;
783
+ }
784
+ return ct;
732
785
}
733
786
734
787
fn pointer_categorize( ty: ty:: t) -> PointerCat {
@@ -752,19 +805,6 @@ mod guarantor {
752
805
}
753
806
}
754
807
755
- fn id_categorization( rcx: @rcx,
756
- guarantor: Option <ty:: Region >,
757
- id: ast:: node_id) -> ExprCategorization
758
- {
759
- let pointer = match rcx. resolve_node_type( id) {
760
- None => NotPointer ,
761
- Some ( t) => pointer_categorize( t)
762
- } ;
763
-
764
- ExprCategorization { guarantor: guarantor,
765
- pointer: pointer}
766
- }
767
-
768
808
fn guarantor_of_deref( cat: & ExprCategorization ) -> Option <ty:: Region > {
769
809
match cat. pointer {
770
810
NotPointer => cat. guarantor,
@@ -824,16 +864,18 @@ mod guarantor {
824
864
link_ref_bindings_in_pat( rcx, p, guarantor)
825
865
}
826
866
ast:: pat_region( p) => {
827
- for rcx. resolve_node_type( pat. id) . each |rptr_ty| {
828
- let r = ty:: ty_region( * rptr_ty) ;
867
+ let rptr_ty = rcx. resolve_node_type( pat. id) ;
868
+ if !ty:: type_contains_err( rptr_ty) {
869
+ let r = ty:: ty_region( rptr_ty) ;
829
870
link_ref_bindings_in_pat( rcx, p, Some ( r) ) ;
830
871
}
831
872
}
832
873
ast:: pat_lit( * ) => { }
833
874
ast:: pat_range( * ) => { }
834
875
ast:: pat_vec( ref ps, ref opt_tail_pat) => {
835
- for rcx. resolve_node_type( pat. id) . each |vec_ty| {
836
- let vstore = ty:: ty_vstore( * vec_ty) ;
876
+ let vec_ty = rcx. resolve_node_type( pat. id) ;
877
+ if !ty:: type_contains_err( vec_ty) {
878
+ let vstore = ty:: ty_vstore( vec_ty) ;
837
879
let guarantor1 = match vstore {
838
880
ty:: vstore_fixed( _) | ty:: vstore_uniq => guarantor,
839
881
ty:: vstore_slice( r) => Some ( r) ,
0 commit comments