Skip to content

Commit

Permalink
Fix bug with associated types and nullable pointer optimization.
Browse files Browse the repository at this point in the history
  • Loading branch information
eefriedman committed Aug 5, 2015
1 parent d034561 commit cab47a3
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/librustc_trans/trans/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
let nonzero_fields = tcx.lookup_struct_fields(did);
assert_eq!(nonzero_fields.len(), 1);
let nonzero_field = tcx.lookup_field_type(did, nonzero_fields[0].id, substs);
let nonzero_field = monomorphize::normalize_associated_type(tcx, &nonzero_field);
match nonzero_field.sty {
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) if !type_is_sized(tcx, ty) => {
path.push_all(&[0, FAT_PTR_ADDR]);
Expand All @@ -466,6 +467,7 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
let fields = tcx.lookup_struct_fields(def_id);
for (j, field) in fields.iter().enumerate() {
let field_ty = tcx.lookup_field_type(def_id, field.id, substs);
let field_ty = monomorphize::normalize_associated_type(tcx, &field_ty);
if let Some(mut fpath) = find_discr_field_candidate(tcx, field_ty, path.clone()) {
fpath.push(j);
return Some(fpath);
Expand Down Expand Up @@ -509,7 +511,22 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
},

// Anything else is not a pointer
_ => None
ty::TyBool |
ty::TyChar |
ty::TyInt(_) |
ty::TyUint(_) |
ty::TyFloat(_) |
ty::TyEnum(..) |
ty::TyStr |
ty::TyArray(..) |
ty::TySlice(_) |
ty::TyRawPtr(_) |
ty::TyTrait(_) => None,

ty::TyError |
ty::TyInfer(_) |
ty::TyParam(_) |
ty::TyProjection(_) => panic!("Unexpected type"),
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/test/run-pass/enum-null-pointer-opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ use std::rc::Rc;
use std::sync::Arc;

trait Trait { fn dummy(&self) { } }
trait Mirror { type Image; }
impl<T> Mirror for T { type Image = T; }
struct ParamTypeStruct<T>(T);
struct AssocTypeStruct<T>(<T as Mirror>::Image);

fn main() {
// Functions
Expand Down Expand Up @@ -66,4 +70,6 @@ fn main() {
// Should apply to types that have NonZero transitively
assert_eq!(size_of::<String>(), size_of::<Option<String>>());

assert_eq!(size_of::<&u8>(), size_of::<Option<ParamTypeStruct<&u8>>>());
assert_eq!(size_of::<&u8>(), size_of::<Option<AssocTypeStruct<&u8>>>());
}

0 comments on commit cab47a3

Please sign in to comment.