Convert newtype "dereference" to trans::adt.
Note that in the ByValue case (which can't happen? yet?) we're still effectively bitcasting, I think. So this change adds a way to assert that that's safe. Note also, for future reference, that LLVM's instcombine pass will turn a bitcast into a GEP(0, 0, ...) if possible.
This commit is contained in:
parent
80844f993d
commit
2a028c5ab8
@ -378,3 +378,12 @@ fn const_struct_field(ccx: @CrateContext, val: ValueRef, ix: uint)
|
||||
real_ix = real_ix + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Is it safe to bitcast a value to the one field of its one variant?
|
||||
pub fn is_newtypeish(r: &Repr) -> bool {
|
||||
match *r {
|
||||
Univariant(ref st, DtorAbsent)
|
||||
| Univariant(ref st, NoDtor) => st.fields.len() == 1,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ use core::prelude::*;
|
||||
use lib;
|
||||
use lib::llvm::ValueRef;
|
||||
use middle::borrowck::{RootInfo, root_map_key};
|
||||
use middle::trans::adt;
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::build::*;
|
||||
use middle::trans::callee;
|
||||
@ -677,15 +678,17 @@ pub impl Datum {
|
||||
return (None, bcx);
|
||||
}
|
||||
|
||||
let repr = adt::represent_type(ccx, self.ty);
|
||||
assert adt::is_newtypeish(&repr);
|
||||
let ty = ty::subst(ccx.tcx, substs, variants[0].args[0]);
|
||||
return match self.mode {
|
||||
ByRef => {
|
||||
// Recast lv.val as a pointer to the newtype
|
||||
// rather than a ptr to the enum type.
|
||||
let llty = T_ptr(type_of::type_of(ccx, ty));
|
||||
(
|
||||
Some(Datum {
|
||||
val: PointerCast(bcx, self.val, llty),
|
||||
val: adt::trans_GEP(bcx, &repr, self.val,
|
||||
0, 0),
|
||||
ty: ty,
|
||||
mode: ByRef,
|
||||
source: ZeroMem
|
||||
@ -715,6 +718,8 @@ pub impl Datum {
|
||||
return (None, bcx);
|
||||
}
|
||||
|
||||
let repr = adt::represent_type(ccx, self.ty);
|
||||
assert adt::is_newtypeish(&repr);
|
||||
let ty = fields[0].mt.ty;
|
||||
return match self.mode {
|
||||
ByRef => {
|
||||
@ -724,7 +729,8 @@ pub impl Datum {
|
||||
// destructors.
|
||||
(
|
||||
Some(Datum {
|
||||
val: GEPi(bcx, self.val, [0, 0, 0]),
|
||||
val: adt::trans_GEP(bcx, &repr, self.val,
|
||||
0, 0),
|
||||
ty: ty,
|
||||
mode: ByRef,
|
||||
source: ZeroMem
|
||||
|
Loading…
Reference in New Issue
Block a user