Skip to content

Commit 2a028c5

Browse files
committed
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.
1 parent 80844f9 commit 2a028c5

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

src/librustc/middle/trans/adt.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,12 @@ fn const_struct_field(ccx: @CrateContext, val: ValueRef, ix: uint)
378378
real_ix = real_ix + 1;
379379
}
380380
}
381+
382+
/// Is it safe to bitcast a value to the one field of its one variant?
383+
pub fn is_newtypeish(r: &Repr) -> bool {
384+
match *r {
385+
Univariant(ref st, DtorAbsent)
386+
| Univariant(ref st, NoDtor) => st.fields.len() == 1,
387+
_ => false
388+
}
389+
}

src/librustc/middle/trans/datum.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ use core::prelude::*;
9090
use lib;
9191
use lib::llvm::ValueRef;
9292
use middle::borrowck::{RootInfo, root_map_key};
93+
use middle::trans::adt;
9394
use middle::trans::base::*;
9495
use middle::trans::build::*;
9596
use middle::trans::callee;
@@ -677,15 +678,17 @@ pub impl Datum {
677678
return (None, bcx);
678679
}
679680

681+
let repr = adt::represent_type(ccx, self.ty);
682+
assert adt::is_newtypeish(&repr);
680683
let ty = ty::subst(ccx.tcx, substs, variants[0].args[0]);
681684
return match self.mode {
682685
ByRef => {
683686
// Recast lv.val as a pointer to the newtype
684687
// rather than a ptr to the enum type.
685-
let llty = T_ptr(type_of::type_of(ccx, ty));
686688
(
687689
Some(Datum {
688-
val: PointerCast(bcx, self.val, llty),
690+
val: adt::trans_GEP(bcx, &repr, self.val,
691+
0, 0),
689692
ty: ty,
690693
mode: ByRef,
691694
source: ZeroMem
@@ -715,6 +718,8 @@ pub impl Datum {
715718
return (None, bcx);
716719
}
717720

721+
let repr = adt::represent_type(ccx, self.ty);
722+
assert adt::is_newtypeish(&repr);
718723
let ty = fields[0].mt.ty;
719724
return match self.mode {
720725
ByRef => {
@@ -724,7 +729,8 @@ pub impl Datum {
724729
// destructors.
725730
(
726731
Some(Datum {
727-
val: GEPi(bcx, self.val, [0, 0, 0]),
732+
val: adt::trans_GEP(bcx, &repr, self.val,
733+
0, 0),
728734
ty: ty,
729735
mode: ByRef,
730736
source: ZeroMem

0 commit comments

Comments
 (0)