@@ -70,7 +70,7 @@ import astconv::{ast_conv, ast_ty_to_ty};
70
70
import collect :: { methods} ; // ccx.to_ty()
71
71
import method :: { methods} ; // methods for method::lookup
72
72
import middle:: ty:: tys_in_fn_ty;
73
- import regionmanip :: { universally_quantify_from_sty ,
73
+ import regionmanip :: { replace_bound_regions_in_fn_ty ,
74
74
region_of, replace_bound_regions,
75
75
collect_bound_regions_in_tys} ;
76
76
import rscope:: * ;
@@ -84,7 +84,6 @@ type fn_ctxt =
84
84
// Used by loop bodies that return from the outer function
85
85
indirect_ret_ty : option < ty:: t > ,
86
86
purity : ast:: purity ,
87
- proto : ast:: proto ,
88
87
infcx : infer:: infer_ctxt ,
89
88
locals : hashmap < ast:: node_id , ty_vid > ,
90
89
@@ -128,55 +127,41 @@ fn check_bare_fn(ccx: @crate_ctxt,
128
127
id : ast:: node_id ,
129
128
self_ty : option < ty:: t > ) {
130
129
let fty = ty:: node_id_to_type ( ccx. tcx , id) ;
131
- let ret_ty = ty:: ty_fn_ret ( fty) ;
132
- let arg_tys = vec:: map ( ty:: ty_fn_args ( fty) ) { |a| a. ty } ;
133
- check_fn ( ccx, ast:: proto_bare, decl, body,
134
- ret_ty, arg_tys, false , none, self_ty) ;
130
+ let fn_ty = alt check ty:: get ( fty) . struct { ty:: ty_fn ( f) { f} } ;
131
+ check_fn ( ccx, self_ty, fn_ty, decl, body, false , none) ;
135
132
}
136
133
137
134
fn check_fn ( ccx : @crate_ctxt ,
138
- proto : ast:: proto ,
135
+ self_ty : option < ty:: t > ,
136
+ fn_ty : ty:: fn_ty ,
139
137
decl : ast:: fn_decl ,
140
138
body : ast:: blk ,
141
- ret_ty : ty:: t ,
142
- arg_tys : [ ty:: t ] ,
143
139
indirect_ret : bool ,
144
- old_fcx : option < @fn_ctxt > ,
145
- self_ty : option < ty:: t > ) {
140
+ old_fcx : option < @fn_ctxt > ) {
146
141
147
142
let tcx = ccx. tcx ;
148
143
149
- let isr = {
150
- // Find the list of in-scope regions. These are derived from the
151
- // various regions that are bound in the argument, return, and self
152
- // types. For each of those bound regions, we will create a mapping
153
- // to a free region tied to the node_id of this function. For an
154
- // in-depth discussion of why we must distinguish bound/free regions,
155
- // see the big comment in region.rs.
156
- let all_tys = arg_tys + [ ret_ty] + self_ty. to_vec ( ) ;
157
- let old_isr = option:: map_default ( old_fcx, @nil) {
158
- |fcx| fcx. in_scope_regions } ;
159
- collect_bound_regions_in_tys ( tcx, old_isr, all_tys) {
160
- |br| ty:: re_free ( body. node . id , br) }
161
- } ;
144
+ // ______________________________________________________________________
145
+ // First, we have to replace any bound regions in the fn and self
146
+ // types with free ones. The free region references will be bound
147
+ // the node_id of the body block.
162
148
163
- // Replace the bound regions that appear in the arg tys, ret ty, etc with
164
- // the free versions we just collected.
165
- let arg_tys = arg_tys. map {
166
- |arg_ty| replace_bound_regions ( tcx, body. span , isr, arg_ty)
167
- } ;
168
- let ret_ty = {
169
- replace_bound_regions ( tcx, body. span , isr, ret_ty)
170
- } ;
171
- let self_ty = option:: map ( self_ty) {
172
- |self_ty| replace_bound_regions ( tcx, body. span , isr, self_ty)
149
+ let { isr, self_ty, fn_ty} = {
150
+ let old_isr = option:: map_default ( old_fcx, @nil,
151
+ { |fcx| fcx. in_scope_regions } ) ;
152
+ replace_bound_regions_in_fn_ty ( tcx, old_isr, self_ty, fn_ty,
153
+ { |br| ty:: re_free ( body. node . id , br) } )
173
154
} ;
174
155
156
+ let arg_tys = fn_ty. inputs . map { |a| a. ty } ;
157
+ let ret_ty = fn_ty. output ;
158
+
175
159
#debug[ "check_fn(arg_tys=%?, ret_ty=%?, self_ty=%?)" ,
176
160
arg_tys. map { |a| ty_to_str ( tcx, a) } ,
177
161
ty_to_str ( tcx, ret_ty) ,
178
162
option:: map ( self_ty) { |st| ty_to_str ( tcx, st) } ] ;
179
163
164
+ // ______________________________________________________________________
180
165
// Create the function context. This is either derived from scratch or,
181
166
// in the case of function expressions, based on the outer context.
182
167
let fcx: @fn_ctxt = {
@@ -211,7 +196,6 @@ fn check_fn(ccx: @crate_ctxt,
211
196
ret_ty: ret_ty,
212
197
indirect_ret_ty: indirect_ret_ty,
213
198
purity: purity,
214
- proto: proto,
215
199
infcx: infcx,
216
200
locals: locals,
217
201
mut blocks: [ ] ,
@@ -708,74 +692,66 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
708
692
// A generic function to factor out common logic from call and bind
709
693
// expressions.
710
694
fn check_call_or_bind (
711
- fcx : @fn_ctxt , sp : span , call_expr_id : ast:: node_id , fty : ty:: t ,
695
+ fcx : @fn_ctxt , sp : span , call_expr_id : ast:: node_id , in_fty : ty:: t ,
712
696
args : [ option < @ast:: expr > ] ) -> { fty : ty:: t , bot : bool } {
713
697
714
698
let mut bot = false ;
715
699
716
700
// Replace all region parameters in the arguments and return
717
701
// type with fresh region variables.
718
702
719
- #debug[ "check_call_or_bind: before universal quant., fty =%s" ,
720
- fcx. infcx . ty_to_str ( fty ) ] ;
703
+ #debug[ "check_call_or_bind: before universal quant., in_fty =%s" ,
704
+ fcx. infcx . ty_to_str ( in_fty ) ] ;
721
705
722
706
// This is subtle: we expect `fty` to be a function type, which
723
707
// normally introduce a level of binding. In this case, we want to
724
708
// process the types bound by the function but not by any nested
725
709
// functions. Therefore, we match one level of structure.
726
- let fty =
727
- alt structure_of ( fcx, sp, fty) {
728
- sty @ ty:: ty_fn ( inner_fty) {
729
- let all_tys = tys_in_fn_ty ( inner_fty) ;
730
- universally_quantify_from_sty ( fcx, sp, all_tys, sty)
710
+ let fn_ty =
711
+ alt structure_of ( fcx, sp, in_fty) {
712
+ sty @ ty:: ty_fn ( fn_ty) {
713
+ replace_bound_regions_in_fn_ty (
714
+ fcx. ccx . tcx , @nil, none, fn_ty,
715
+ { |_br| fcx. infcx . next_region_var ( ) } ) . fn_ty
731
716
}
732
717
sty {
733
- #debug[ "not a fn ty: %?", sty] ;
734
-
735
- // if not a function type, we're gonna' report an error at
736
- // some point, since the user is trying to call this thing
737
- fty
718
+ // I would like to make this span_err, but it's
719
+ // really hard due to the way that expr_bind() is
720
+ // written.
721
+ fcx. ccx . tcx . sess . span_fatal ( sp, "mismatched types: \
722
+ expected function or native \
723
+ function but found "
724
+ + fcx. infcx . ty_to_str ( in_fty) ) ;
738
725
}
739
726
} ;
740
727
728
+ let fty = ty:: mk_fn ( fcx. tcx ( ) , fn_ty) ;
741
729
#debug[ "check_call_or_bind: after universal quant., fty=%s" ,
742
730
fcx. infcx . ty_to_str ( fty) ] ;
743
731
744
732
let supplied_arg_count = vec:: len ( args) ;
745
733
746
- // Grab the argument types
747
- let arg_tys = alt structure_of ( fcx, sp, fty) {
748
- ty:: ty_fn ( { inputs: arg_tys, output: ret_ty, _} ) {
749
- let expected_arg_count = vec:: len ( arg_tys) ;
750
- if expected_arg_count == supplied_arg_count {
751
- arg_tys. map { |a| a. ty }
752
- } else {
753
- fcx. ccx . tcx . sess . span_err (
754
- sp, #fmt[ "this function takes %u parameter%s but %u \
755
- parameter%s supplied", expected_arg_count,
756
- if expected_arg_count == 1 u {
757
- ""
758
- } else {
759
- "s"
760
- } ,
761
- supplied_arg_count,
762
- if supplied_arg_count == 1 u {
763
- " was"
764
- } else {
765
- "s were"
766
- } ] ) ;
767
- fcx. infcx . next_ty_vars ( supplied_arg_count)
768
- }
769
- }
770
-
771
- _ {
772
- // I would like to make this span_err, but it's really hard due to
773
- // the way that expr_bind() is written.
774
- fcx. ccx . tcx . sess . span_fatal ( sp, "mismatched types: \
775
- expected function or native \
776
- function but found "
777
- + fcx. infcx . ty_to_str ( fty) ) ;
778
- }
734
+ // Grab the argument types, supplying fresh type variables
735
+ // if the wrong number of arguments were supplied
736
+ let expected_arg_count = vec:: len ( fn_ty. inputs ) ;
737
+ let arg_tys = if expected_arg_count == supplied_arg_count {
738
+ fn_ty. inputs . map { |a| a. ty }
739
+ } else {
740
+ fcx. ccx . tcx . sess . span_err (
741
+ sp, #fmt[ "this function takes %u parameter%s but %u \
742
+ parameter%s supplied", expected_arg_count,
743
+ if expected_arg_count == 1 u {
744
+ ""
745
+ } else {
746
+ "s"
747
+ } ,
748
+ supplied_arg_count,
749
+ if supplied_arg_count == 1 u {
750
+ " was"
751
+ } else {
752
+ "s were"
753
+ } ] ) ;
754
+ fcx. infcx . next_ty_vars ( supplied_arg_count)
779
755
} ;
780
756
781
757
// Check the arguments.
@@ -1049,21 +1025,17 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1049
1025
} ;
1050
1026
1051
1027
// construct the function type
1052
- let fty = ty :: mk_fn ( tcx ,
1053
- astconv :: ty_of_fn_decl ( fcx , fcx , proto , decl,
1054
- expected_tys ) ) ;
1028
+ let fn_ty = astconv :: ty_of_fn_decl ( fcx , fcx , proto ,
1029
+ decl, expected_tys ) ;
1030
+ let fty = ty :: mk_fn ( tcx , fn_ty ) ;
1055
1031
1056
1032
#debug ( "check_expr_fn_with_unifier %s fty=%s" ,
1057
1033
expr_to_str ( expr) , fcx. infcx . ty_to_str ( fty) ) ;
1058
1034
1059
1035
fcx. write_ty ( expr. id , fty) ;
1060
1036
1061
- let ret_ty = ty:: ty_fn_ret ( fty) ;
1062
- let arg_tys = vec:: map ( ty:: ty_fn_args ( fty) ) { |a| a. ty } ;
1063
-
1064
- check_fn ( fcx. ccx , proto, decl, body,
1065
- ret_ty, arg_tys, is_loop_body, some ( fcx) ,
1066
- fcx. self_ty ) ;
1037
+ check_fn ( fcx. ccx , fcx. self_ty , fn_ty, decl, body,
1038
+ is_loop_body, some ( fcx) ) ;
1067
1039
}
1068
1040
1069
1041
@@ -1825,7 +1797,6 @@ fn check_const(ccx: @crate_ctxt, _sp: span, e: @ast::expr, id: ast::node_id) {
1825
1797
ret_ty: rty,
1826
1798
indirect_ret_ty: none,
1827
1799
purity: ast:: pure_fn,
1828
- proto: ast:: proto_box,
1829
1800
infcx: infer:: new_infer_ctxt ( ccx. tcx ) ,
1830
1801
locals: int_hash ( ) ,
1831
1802
mut blocks: [ ] ,
@@ -1865,7 +1836,6 @@ fn check_enum_variants(ccx: @crate_ctxt,
1865
1836
ret_ty: rty,
1866
1837
indirect_ret_ty: none,
1867
1838
purity: ast:: pure_fn,
1868
- proto: ast:: proto_box,
1869
1839
infcx: infer:: new_infer_ctxt ( ccx. tcx ) ,
1870
1840
locals: int_hash ( ) ,
1871
1841
mut blocks: [ ] ,
0 commit comments