+ alt origin {
+ typeck::dict_static(impl_did, tys, sub_origins) {
+ if dict_is_static(bcx_tcx(bcx), origin) {
+ ret rslt(bcx, get_static_dict(bcx, origin));
+ }
+ let {bcx, ptrs} = get_dict_ptrs(bcx, origin);
+ let pty = T_ptr(T_i8()), dict_ty = T_array(pty, vec::len(ptrs));
+ let dict = alloca(bcx, dict_ty), i = 0;
+ for ptr in ptrs {
+ Store(bcx, PointerCast(bcx, ptr, pty), GEPi(bcx, dict, [0, i]));
+ i += 1;
+ }
+ rslt(bcx, PointerCast(bcx, dict, T_ptr(T_dict())))
+ }
+ typeck::dict_param(n_param, n_bound) {
+ rslt(bcx, option::get(bcx.fcx.lltyparams[n_param].dicts)[n_bound])
+ }
+ }
+}
+
+fn dict_id(tcx: ty::ctxt, origin: typeck::dict_origin) -> dict_id {
+ alt origin {
+ typeck::dict_static(did, ts, origs) {
+ let d_params = [], orig = 0u;
+ if vec::len(ts) == 0u { ret @{impl_def: did, params: d_params}; }
+ let impl_params = ty::lookup_item_type(tcx, did).bounds;
+ vec::iter2(ts, *impl_params) {|t, bounds|
+ d_params += [dict_param_ty(t)];
+ for bound in *bounds {
+ alt bound {
+ ty::bound_iface(_) {
+ d_params += [dict_param_dict(dict_id(tcx, origs[orig]))];
+ orig += 1u;
+ }
+ }
+ }
+ }
+ @{impl_def: did, params: d_params}
+ }
+ }
+}
+
+fn get_static_dict(bcx: @block_ctxt, origin: typeck::dict_origin)
+ -> ValueRef {
+ let ccx = bcx_ccx(bcx);
+ let id = dict_id(ccx.tcx, origin);
+ alt ccx.dicts.find(id) {
+ some(d) { ret d; }
+ none. {}
+ }
+ let ptrs = C_struct(get_dict_ptrs(bcx, origin).ptrs);
+ let name = ccx.names.next("dict");
+ let gvar = str::as_buf(name, {|buf|
+ llvm::LLVMAddGlobal(ccx.llmod, val_ty(ptrs), buf)
+ });
+ llvm::LLVMSetGlobalConstant(gvar, lib::llvm::True);
+ llvm::LLVMSetInitializer(gvar, ptrs);
+ llvm::LLVMSetLinkage(gvar,
+ lib::llvm::LLVMInternalLinkage as llvm::Linkage);
+ let cast = llvm::LLVMConstPointerCast(gvar, T_ptr(T_dict()));
+ ccx.dicts.insert(id, cast);
+ cast
+}
+
+fn get_dict_ptrs(bcx: @block_ctxt, origin: typeck::dict_origin)
+ -> {bcx: @block_ctxt, ptrs: [ValueRef]} {
+ let ccx = bcx_ccx(bcx);