From cab47a3361678f438a1d7967c66ed9159b6aabeb Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 5 Aug 2015 11:27:36 -0700 Subject: [PATCH] Fix bug with associated types and nullable pointer optimization. Fixes #27532. --- src/librustc_trans/trans/adt.rs | 19 ++++++++++++++++++- src/test/run-pass/enum-null-pointer-opt.rs | 6 ++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index e79618893c7f8..079dabba62cb5 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -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]); @@ -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); @@ -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"), } } diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs index dd88dc11ea70e..905317f91097e 100644 --- a/src/test/run-pass/enum-null-pointer-opt.rs +++ b/src/test/run-pass/enum-null-pointer-opt.rs @@ -18,6 +18,10 @@ use std::rc::Rc; use std::sync::Arc; trait Trait { fn dummy(&self) { } } +trait Mirror { type Image; } +impl Mirror for T { type Image = T; } +struct ParamTypeStruct(T); +struct AssocTypeStruct(::Image); fn main() { // Functions @@ -66,4 +70,6 @@ fn main() { // Should apply to types that have NonZero transitively assert_eq!(size_of::(), size_of::>()); + assert_eq!(size_of::<&u8>(), size_of::>>()); + assert_eq!(size_of::<&u8>(), size_of::>>()); }