@@ -49,7 +49,7 @@ import tvec = trans_vec;
49
49
fn type_of( cx : @crate_ctxt , sp : span , t : ty:: t ) : type_has_static_size ( cx , t )
50
50
-> TypeRef {
51
51
// Should follow from type_has_static_size -- argh.
52
- // FIXME
52
+ // FIXME (requires Issue #586)
53
53
check non_ty_var ( cx, t) ;
54
54
type_of_inner ( cx, sp, t)
55
55
}
@@ -59,6 +59,8 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
59
59
let atys = [ ] ;
60
60
for arg in inputs {
61
61
let arg_ty = arg. ty ;
62
+ // FIXME: would be nice to have a constraint on arg
63
+ // that would obviate the need for this check
62
64
check non_ty_var( cx, arg_ty) ;
63
65
atys += [ T_ptr ( type_of_inner ( cx, sp, arg_ty) ) ] ;
64
66
}
@@ -114,9 +116,12 @@ fn type_of_fn(cx: @crate_ctxt, sp: span, proto: ast::proto,
114
116
115
117
// Given a function type and a count of ty params, construct an llvm type
116
118
fn type_of_fn_from_ty( cx : @crate_ctxt , sp : span , fty : ty:: t ,
117
- ty_param_count : uint ) -> TypeRef {
119
+ ty_param_count : uint )
120
+ : returns_non_ty_var ( cx , fty ) -> TypeRef {
118
121
let by_ref = ast_util:: ret_by_ref ( ty:: ty_fn_ret_style ( cx. tcx , fty) ) ;
119
- // FIXME: constraint?
122
+ // FIXME: Check should be unnecessary, b/c it's implied
123
+ // by returns_non_ty_var(t). Make that a postcondition
124
+ // (see Issue #586)
120
125
let ret_ty = ty:: ty_fn_ret ( cx. tcx , fty) ;
121
126
check non_ty_var( cx, ret_ty) ;
122
127
ret type_of_fn( cx, sp, ty:: ty_fn_proto ( cx. tcx , fty) ,
@@ -197,6 +202,8 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
197
202
T_struct ( tys)
198
203
}
199
204
ty:: ty_fn ( _, _, _, _, _) {
205
+ // FIXME: could be a constraint on ty_fn
206
+ check returns_non_ty_var ( cx, t) ;
200
207
T_fn_pair ( * cx, type_of_fn_from_ty ( cx, sp, t, 0 u) )
201
208
}
202
209
ty:: ty_native_fn ( abi, args, out) {
@@ -251,6 +258,7 @@ fn type_of_ty_param_kinds_and_ty(lcx: @local_ctxt, sp: span,
251
258
let t = tpt. ty ;
252
259
alt ty:: struct ( cx. tcx , t) {
253
260
ty:: ty_fn ( _, _, _, _, _) {
261
+ check returns_non_ty_var ( cx, t) ;
254
262
let llfnty = type_of_fn_from_ty ( cx, sp, t, std:: vec:: len ( tpt. kinds ) ) ;
255
263
ret T_fn_pair ( * cx, llfnty) ;
256
264
}
@@ -2717,27 +2725,30 @@ fn trans_for_each(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
2717
2725
// Step 1: Generate code to build an environment containing pointers
2718
2726
// to all of the upvars
2719
2727
let lcx = cx. fcx . lcx ;
2728
+ let ccx = lcx. ccx ;
2720
2729
2721
2730
// FIXME: possibly support alias-mode here?
2722
- let decl_ty = node_id_type ( lcx . ccx , local. node . id ) ;
2723
- let upvars = get_freevars ( lcx . ccx . tcx , body. node . id ) ;
2731
+ let decl_ty = node_id_type ( ccx, local. node . id ) ;
2732
+ let upvars = get_freevars ( ccx. tcx , body. node . id ) ;
2724
2733
2725
2734
let llenv = build_closure ( cx, upvars, false ) ;
2726
2735
2727
2736
// Step 2: Declare foreach body function.
2728
2737
let s: str =
2729
- mangle_internal_name_by_path_and_seq ( lcx . ccx , lcx. path , "foreach" ) ;
2738
+ mangle_internal_name_by_path_and_seq ( ccx, lcx. path , "foreach" ) ;
2730
2739
2731
2740
// The 'env' arg entering the body function is a fake env member (as in
2732
2741
// the env-part of the normal rust calling convention) that actually
2733
2742
// points to a stack allocated env in this frame. We bundle that env
2734
2743
// pointer along with the foreach-body-fn pointer into a 'normal' fn pair
2735
2744
// and pass it in as a first class fn-arg to the iterator.
2745
+ let iter_body_fn = ty:: mk_iter_body_fn ( ccx. tcx , decl_ty) ;
2746
+ // FIXME: should be a postcondition on mk_iter_body_fn
2747
+ check returns_non_ty_var ( ccx, iter_body_fn) ;
2736
2748
let iter_body_llty =
2737
- type_of_fn_from_ty ( lcx. ccx , cx. sp ,
2738
- ty:: mk_iter_body_fn ( lcx. ccx . tcx , decl_ty) , 0 u) ;
2749
+ type_of_fn_from_ty ( ccx, cx. sp , iter_body_fn, 0 u) ;
2739
2750
let lliterbody: ValueRef =
2740
- decl_internal_fastcall_fn ( lcx . ccx . llmod , s, iter_body_llty) ;
2751
+ decl_internal_fastcall_fn ( ccx. llmod , s, iter_body_llty) ;
2741
2752
let fcx = new_fn_ctxt_w_id ( lcx, cx. sp , lliterbody, body. node . id ,
2742
2753
ast:: return_val) ;
2743
2754
fcx. iterbodyty = cx. fcx . iterbodyty ;
@@ -3258,16 +3269,21 @@ fn trans_cast(cx: @block_ctxt, e: @ast::expr, id: ast::node_id) -> result {
3258
3269
ret rslt( e_res. bcx , newval) ;
3259
3270
}
3260
3271
3272
+ // pth is cx.path
3261
3273
fn trans_bind_thunk ( cx : @local_ctxt , sp : span , incoming_fty : ty:: t ,
3262
3274
outgoing_fty : ty:: t , args : [ option:: t < @ast:: expr > ] ,
3263
3275
env_ty : ty:: t , ty_param_count : uint ,
3264
- target_fn : option:: t < ValueRef > ) ->
3265
- { val : ValueRef , ty: TypeRef } {
3266
- // FIXME
3267
- // This should be a precondition on trans_bind_thunk, but we would need
3268
- // to support record fields as constraint args
3269
- let ccx = cx. ccx ;
3270
- check ( type_has_static_size ( ccx, incoming_fty) ) ;
3276
+ target_fn : option:: t < ValueRef > )
3277
+ -> { val : ValueRef , ty: TypeRef } {
3278
+ // If we supported constraints on record fields, we could make the
3279
+ // constraints for this function:
3280
+ /*
3281
+ : returns_non_ty_var(ccx, outgoing_fty),
3282
+ type_has_static_size(ccx, incoming_fty) ->
3283
+ */
3284
+ // but since we don't, we have to do the checks at the beginning.
3285
+ let ccx = cx. ccx ;
3286
+ check type_has_static_size ( ccx, incoming_fty) ;
3271
3287
3272
3288
// Here we're not necessarily constructing a thunk in the sense of
3273
3289
// "function with no arguments". The result of compiling 'bind f(foo,
@@ -3424,8 +3440,11 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
3424
3440
// This is necessary because the type of the function that we have
3425
3441
// in the closure does not know how many type descriptors the function
3426
3442
// needs to take.
3443
+ let ccx = bcx_ccx ( bcx) ;
3444
+
3445
+ check returns_non_ty_var ( ccx, outgoing_fty) ;
3427
3446
let lltargetty =
3428
- type_of_fn_from_ty ( bcx_ccx ( bcx ) , sp, outgoing_fty, ty_param_count) ;
3447
+ type_of_fn_from_ty ( ccx , sp, outgoing_fty, ty_param_count) ;
3429
3448
lltargetfn = PointerCast ( bcx, lltargetfn, T_ptr ( lltargetty) ) ;
3430
3449
FastCall ( bcx, lltargetfn, llargs) ;
3431
3450
build_return ( bcx) ;
@@ -3972,8 +3991,10 @@ fn trans_expr_out(cx: @block_ctxt, e: @ast::expr, output: out_method) ->
3972
3991
}
3973
3992
ast:: expr_fn ( f) {
3974
3993
let ccx = bcx_ccx ( cx) ;
3994
+ let fty = node_id_type ( ccx, e. id ) ;
3995
+ check returns_non_ty_var ( ccx, fty) ;
3975
3996
let llfnty: TypeRef =
3976
- type_of_fn_from_ty ( ccx, e. span , node_id_type ( ccx , e . id ) , 0 u) ;
3997
+ type_of_fn_from_ty ( ccx, e. span , fty , 0 u) ;
3977
3998
let sub_cx = extend_path ( cx. fcx . lcx , ccx. names . next ( "anon" ) ) ;
3978
3999
let s = mangle_internal_name_by_path ( ccx, sub_cx. path ) ;
3979
4000
let llfn = decl_internal_fastcall_fn ( ccx. llmod , s, llfnty) ;
@@ -5416,13 +5437,16 @@ fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
5416
5437
5417
5438
fn decl_fn_and_pair ( ccx : @crate_ctxt , sp : span , path : [ str ] , flav : str ,
5418
5439
ty_params : [ ast:: ty_param ] , node_id : ast:: node_id ) {
5419
- decl_fn_and_pair_full ( ccx, sp, path, flav, ty_params, node_id,
5420
- node_id_type ( ccx, node_id) ) ;
5440
+ // FIXME: pull this out
5441
+ let t = node_id_type ( ccx, node_id) ;
5442
+ check returns_non_ty_var ( ccx, t) ;
5443
+ decl_fn_and_pair_full ( ccx, sp, path, flav, ty_params, node_id, t) ;
5421
5444
}
5422
5445
5423
5446
fn decl_fn_and_pair_full ( ccx : @crate_ctxt , sp : span , path : [ str ] , _flav : str ,
5424
5447
ty_params : [ ast:: ty_param ] , node_id : ast:: node_id ,
5425
- node_type : ty:: t ) {
5448
+ node_type : ty:: t )
5449
+ : returns_non_ty_var( ccx , node_type ) {
5426
5450
let path = path;
5427
5451
let llfty =
5428
5452
type_of_fn_from_ty ( ccx, sp, node_type, std:: vec:: len ( ty_params) ) ;
@@ -5830,8 +5854,10 @@ fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, pt: [str], v: vt<[str]>) {
5830
5854
// the dtor_id. This is a bit counter-intuitive, but simplifies
5831
5855
// ty_res, which would have to carry around two def_ids otherwise
5832
5856
// -- one to identify the type, and one to find the dtor symbol.
5833
- decl_fn_and_pair_full ( ccx, i. span , new_pt, "res_dtor" , tps, i. id ,
5834
- node_id_type ( ccx, dtor_id) ) ;
5857
+ let t = node_id_type ( ccx, dtor_id) ;
5858
+ // FIXME: how to get rid of this check?
5859
+ check returns_non_ty_var ( ccx, t) ;
5860
+ decl_fn_and_pair_full ( ccx, i. span , new_pt, "res_dtor" , tps, i. id , t) ;
5835
5861
}
5836
5862
_ { }
5837
5863
}
0 commit comments