@@ -2429,7 +2429,7 @@ fn trans_external_path(cx: @block_ctxt, did: ast::def_id,
2429
2429
2430
2430
fn monomorphic_fn ( ccx : @crate_ctxt , fn_id : ast:: def_id , substs : [ ty:: t ] ,
2431
2431
dicts : option < typeck:: dict_res > )
2432
- -> { llfn : ValueRef , fty : ty:: t } {
2432
+ -> option < { llfn: ValueRef , fty : ty:: t } > {
2433
2433
let substs = vec:: map ( substs, { |t|
2434
2434
alt ty:: get ( t) . struct {
2435
2435
ty:: ty_box ( mt) {
@@ -2447,29 +2447,47 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
2447
2447
none { [ ] }
2448
2448
} } ;
2449
2449
alt ccx. monomorphized . find ( hash_id) {
2450
- some ( val) { ret val; }
2450
+ some ( val) { ret some ( val) ; }
2451
2451
none { }
2452
2452
}
2453
2453
let tpt = ty:: lookup_item_type ( ccx. tcx , fn_id) ;
2454
2454
let mono_ty = ty:: substitute_type_params ( ccx. tcx , substs, tpt. ty ) ;
2455
- let ( item, pt) = alt ccx. tcx . items . get ( fn_id. node ) {
2456
- ast_map:: node_item ( i, p) { ( i, p) } _ { fail; }
2457
- } ;
2458
- let pt = * pt + [ path_name ( item. ident ) ] ;
2459
- let result = alt item. node {
2460
- ast:: item_fn ( decl, _, body) {
2461
- let llfty = type_of_fn_from_ty ( ccx, mono_ty, [ ] ) ;
2455
+ let llfty = type_of_fn_from_ty ( ccx, mono_ty, [ ] ) ;
2456
+ let lldecl;
2457
+ alt ccx. tcx . items . get ( fn_id. node ) {
2458
+ ast_map:: node_item ( item, pt) {
2459
+ let pt = * pt + [ path_name ( item. ident ) ] ;
2460
+ let s = mangle_exported_name ( ccx, pt, mono_ty) ;
2461
+ lldecl = decl_cdecl_fn ( ccx. llmod , s, llfty) ;
2462
+ alt item. node {
2463
+ ast:: item_fn ( decl, _, body) {
2464
+ trans_fn ( ccx, pt, decl, body, lldecl, no_self, [ ] ,
2465
+ some ( substs) , fn_id. node ) ;
2466
+ }
2467
+ ast:: item_res ( decl, _, _, _, ctor_id) {
2468
+ trans_res_ctor ( ccx, pt, decl, ctor_id, [ ] , some ( substs) , lldecl) ;
2469
+ }
2470
+ _ { fail "Unexpected item type" ; }
2471
+ }
2472
+ }
2473
+ ast_map:: node_variant ( v, enum_id, pt) {
2474
+ let pt = * pt + [ path_name ( v. node . name ) ] ;
2462
2475
let s = mangle_exported_name ( ccx, pt, mono_ty) ;
2463
- let lldecl = decl_cdecl_fn ( ccx. llmod , s, llfty) ;
2464
- trans_fn ( ccx, pt, decl, body, lldecl, no_self, [ ] ,
2465
- some ( substs) , fn_id. node ) ;
2466
- lldecl
2476
+ lldecl = decl_cdecl_fn ( ccx. llmod , s, llfty) ;
2477
+ let tvs = ty:: enum_variants ( ccx. tcx , enum_id) ;
2478
+ let this_tv = option:: get ( vec:: find ( * tvs, { |tv|
2479
+ tv. id . node == fn_id. node } ) ) ;
2480
+ trans_enum_variant ( ccx, enum_id. node , v, this_tv. disr_val ,
2481
+ vec:: len ( * tvs) == 1 u, [ ] , some ( substs) , lldecl) ;
2467
2482
}
2468
- _ { fail "FIXME[mono] handle other constructs" ; }
2469
- } ;
2470
- let val = { llfn: result, fty: mono_ty} ;
2483
+ ast_map:: node_native_item ( _, _) {
2484
+ ret none;
2485
+ }
2486
+ _ { fail "Unexpected node type" ; }
2487
+ }
2488
+ let val = { llfn: lldecl, fty: mono_ty} ;
2471
2489
ccx. monomorphized . insert ( hash_id, val) ;
2472
- val
2490
+ some ( val)
2473
2491
}
2474
2492
2475
2493
fn lval_static_fn ( bcx : @block_ctxt , fn_id : ast:: def_id , id : ast:: node_id )
@@ -2484,10 +2502,14 @@ fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
2484
2502
alt b { ty : : bound_iface ( _) { false } _ { true } }
2485
2503
} ) } ) {
2486
2504
let dicts = ccx. dict_map . find ( id) ;
2487
- let { llfn, fty} = monomorphic_fn ( ccx, fn_id, tys, dicts) ;
2488
- ret { bcx : bcx, val : llfn,
2489
- kind : owned, env : null_env,
2490
- generic : generic_mono ( fty) } ;
2505
+ alt monomorphic_fn ( ccx, fn_id, tys, dicts) {
2506
+ some ( { llfn, fty} ) {
2507
+ ret { bcx : bcx, val : llfn,
2508
+ kind : owned, env : null_env,
2509
+ generic : generic_mono ( fty) } ;
2510
+ }
2511
+ none { }
2512
+ }
2491
2513
}
2492
2514
let val = if fn_id. crate == ast:: local_crate {
2493
2515
// Internal reference.
@@ -4362,15 +4384,6 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
4362
4384
ret bcx;
4363
4385
}
4364
4386
4365
- fn arg_tys_of_fn ( ccx : @crate_ctxt , id : ast:: node_id ) -> [ ty:: arg ] {
4366
- let tt = ty:: node_id_to_type ( ccx. tcx , id) ;
4367
- alt ty:: get ( tt) . struct {
4368
- ty:: ty_fn ( { inputs, _} ) { inputs }
4369
- _ { ccx. sess . bug ( #fmt ( "arg_tys_of_fn called on non-function\
4370
- type %s", ty_to_str ( ccx. tcx , tt) ) ) ; }
4371
- }
4372
- }
4373
-
4374
4387
// Ties up the llstaticallocas -> llloadenv -> llderivedtydescs ->
4375
4388
// lldynamicallocas -> lltop edges, and builds the return block.
4376
4389
fn finish_fn ( fcx : @fn_ctxt , lltop : BasicBlockRef ) {
@@ -4407,7 +4420,7 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
4407
4420
let lltop = bcx. llbb ;
4408
4421
let block_ty = node_id_type ( bcx, body. node . id ) ;
4409
4422
4410
- let arg_tys = arg_tys_of_fn ( fcx . ccx , id) ;
4423
+ let arg_tys = ty :: ty_fn_args ( node_id_type ( bcx , id) ) ;
4411
4424
alt param_substs {
4412
4425
some( ts) {
4413
4426
arg_tys = vec:: map ( arg_tys, { |a|
@@ -4459,23 +4472,23 @@ fn trans_fn(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
4459
4472
}
4460
4473
4461
4474
fn trans_res_ctor ( ccx : @crate_ctxt , path : path , dtor : ast:: fn_decl ,
4462
- ctor_id : ast:: node_id , ty_params : [ ast:: ty_param ] ) {
4475
+ ctor_id : ast:: node_id , ty_params : [ ast:: ty_param ] ,
4476
+ param_substs : option < [ ty:: t ] > , llfndecl : ValueRef ) {
4463
4477
// Create a function for the constructor
4464
- let llctor_decl = ccx. item_ids . get ( ctor_id) ;
4465
- let fcx = new_fn_ctxt_w_id ( ccx, path, llctor_decl, ctor_id, none, none) ;
4466
- let ret_t = ty:: ret_ty_of_fn ( ccx. tcx , ctor_id) ;
4478
+ let fcx = new_fn_ctxt_w_id ( ccx, path, llfndecl, ctor_id,
4479
+ param_substs, none) ;
4467
4480
create_llargs_for_fn_args ( fcx, no_self, dtor. inputs , ty_params) ;
4468
- let bcx = new_top_block_ctxt ( fcx, none) ;
4469
- let lltop = bcx. llbb ;
4470
- let arg_t = arg_tys_of_fn ( ccx , ctor_id ) [ 0 ] . ty ;
4481
+ let bcx = new_top_block_ctxt ( fcx, none) , lltop = bcx . llbb ;
4482
+ let fty = node_id_type ( bcx, ctor_id ) ;
4483
+ let arg_t = ty :: ty_fn_args ( fty ) [ 0 ] . ty ;
4471
4484
let tup_t = ty:: mk_tup ( ccx. tcx , [ ty:: mk_int ( ccx. tcx ) , arg_t] ) ;
4472
4485
let arg = alt fcx. llargs . find ( dtor. inputs [ 0 ] . id ) {
4473
4486
some ( local_mem ( x) ) { x }
4474
4487
_ { ccx. sess . bug ( "Someone forgot to document an invariant \
4475
4488
in trans_res_ctor") ; }
4476
4489
} ;
4477
4490
let llretptr = fcx. llretptr ;
4478
- if ty:: type_has_dynamic_size ( ccx. tcx , ret_t ) {
4491
+ if ty:: type_has_dynamic_size ( ccx. tcx , ty :: ty_fn_ret ( fty ) ) {
4479
4492
let llret_t = T_ptr ( T_struct ( [ ccx. int_type , llvm:: LLVMTypeOf ( arg) ] ) ) ;
4480
4493
llretptr = BitCast ( bcx, llretptr, llret_t) ;
4481
4494
}
@@ -4495,11 +4508,8 @@ fn trans_res_ctor(ccx: @crate_ctxt, path: path, dtor: ast::fn_decl,
4495
4508
fn trans_enum_variant ( ccx : @crate_ctxt ,
4496
4509
enum_id : ast:: node_id ,
4497
4510
variant : ast:: variant , disr : int , is_degen : bool ,
4498
- ty_params : [ ast:: ty_param ] ) {
4499
- if vec:: len ( variant. node . args ) == 0 u {
4500
- ret; // nullary constructors are just constants
4501
- }
4502
-
4511
+ ty_params : [ ast:: ty_param ] ,
4512
+ param_substs : option < [ ty:: t ] > , llfndecl : ValueRef ) {
4503
4513
// Translate variant arguments to function arguments.
4504
4514
let fn_args = [ ] , i = 0 u;
4505
4515
for varg in variant. node . args {
@@ -4508,27 +4518,21 @@ fn trans_enum_variant(ccx: @crate_ctxt,
4508
4518
ident: "arg" + uint:: to_str ( i, 10 u) ,
4509
4519
id: varg. id } ] ;
4510
4520
}
4511
- assert ( ccx. item_ids . contains_key ( variant. node . id ) ) ;
4512
- let llfndecl: ValueRef ;
4513
- alt ccx. item_ids . find ( variant. node . id ) {
4514
- some ( x) { llfndecl = x; }
4515
- _ {
4516
- ccx. sess . span_fatal ( variant. span ,
4517
- "unbound variant id in trans_enum_variant" ) ;
4518
- }
4519
- }
4520
- let fcx = new_fn_ctxt_w_id ( ccx, [ ] , llfndecl, variant. node . id , none,
4521
- none) ;
4521
+ let fcx = new_fn_ctxt_w_id ( ccx, [ ] , llfndecl, variant. node . id ,
4522
+ param_substs, none) ;
4522
4523
create_llargs_for_fn_args ( fcx, no_self, fn_args, ty_params) ;
4523
- let ty_param_substs = [ ] , i = 0 u;
4524
- for tp: ast:: ty_param in ty_params {
4525
- ty_param_substs += [ ty:: mk_param ( ccx. tcx , i,
4526
- local_def ( tp. id ) ) ] ;
4527
- i += 1 u;
4528
- }
4529
- let arg_tys = arg_tys_of_fn ( ccx, variant. node . id ) ;
4530
- let bcx = new_top_block_ctxt ( fcx, none) ;
4531
- let lltop = bcx. llbb ;
4524
+ let ty_param_substs = alt param_substs {
4525
+ some( ts) { ts }
4526
+ none {
4527
+ let i = 0 u;
4528
+ vec:: map ( ty_params, { |tp|
4529
+ i += 1 u;
4530
+ ty:: mk_param ( ccx. tcx , i - 1 u, local_def ( tp. id ) )
4531
+ } )
4532
+ }
4533
+ } ;
4534
+ let bcx = new_top_block_ctxt ( fcx, none) , lltop = bcx. llbb ;
4535
+ let arg_tys = ty:: ty_fn_args ( node_id_type ( bcx, variant. node . id ) ) ;
4532
4536
bcx = copy_args_to_allocas ( fcx, bcx, fn_args, arg_tys) ;
4533
4537
4534
4538
// Cast the enum to a type we can GEP into.
@@ -4852,7 +4856,8 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
4852
4856
impl :: trans_impl ( ccx , * path , item . ident, ms , item . id, tps ) ;
4853
4857
}
4854
4858
ast:: item_res ( decl, tps, body, dtor_id, ctor_id) {
4855
- trans_res_ctor ( ccx, * path, decl, ctor_id, tps) ;
4859
+ let llctor_decl = ccx. item_ids . get ( ctor_id) ;
4860
+ trans_res_ctor ( ccx, * path, decl, ctor_id, tps, none, llctor_decl) ;
4856
4861
4857
4862
// Create a function for the destructor
4858
4863
alt ccx. item_ids . find ( item. id ) {
@@ -4873,8 +4878,11 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
4873
4878
let vi = ty:: enum_variants ( ccx. tcx , local_def ( item. id ) ) ;
4874
4879
let i = 0 ;
4875
4880
for variant: ast:: variant in variants {
4876
- trans_enum_variant ( ccx, item. id , variant,
4877
- vi[ i] . disr_val , degen, tps) ;
4881
+ if vec:: len ( variant. node . args ) > 0 u {
4882
+ trans_enum_variant ( ccx, item. id , variant,
4883
+ vi[ i] . disr_val , degen, tps,
4884
+ none, ccx. item_ids . get ( variant. node . id ) ) ;
4885
+ }
4878
4886
i += 1 ;
4879
4887
}
4880
4888
}
0 commit comments