diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-08-07 01:09:00 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2016-09-03 13:37:25 +0300 |
| commit | cbd912babab4b8cebe9e90a632117913ca192743 (patch) | |
| tree | 4e59815e06c47d9c278a575f8634de4066025145 | |
| parent | 35d52a003bf0997d31378796bf59cc66c3ae7683 (diff) | |
| download | rust-cbd912babab4b8cebe9e90a632117913ca192743.tar.gz rust-cbd912babab4b8cebe9e90a632117913ca192743.zip | |
Add union types
29 files changed, 124 insertions, 69 deletions
diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index f793d489cab..8aeb0757f5d 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -168,6 +168,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::TyFnPtr(_) | ty::TyTrait(..) | ty::TyStruct(..) | + ty::TyUnion(..) | ty::TyClosure(..) | ty::TyNever | ty::TyTuple(..) | diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index a5a415dd27c..f856e110ea2 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -261,7 +261,8 @@ fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)-> } ty::TyEnum(def, _) | - ty::TyStruct(def, _) => { + ty::TyStruct(def, _) | + ty::TyUnion(def, _) => { def.did.is_local() } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 6d6d7c2b3ba..95e83d404a7 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -166,6 +166,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::TyParam(..) => Some(14), ty::TyAnon(..) => Some(15), ty::TyNever => Some(16), + ty::TyUnion(..) => Some(17), ty::TyInfer(..) | ty::TyError => None } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 0573f0c5bba..f8f10d9c265 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1780,7 +1780,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Where(ty::Binder(tys.last().into_iter().cloned().collect())) } - ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => { + ty::TyStruct(def, substs) | ty::TyUnion(def, substs) | + ty::TyEnum(def, substs) => { let sized_crit = def.sized_constraint(self.tcx()); // (*) binder moved here Where(ty::Binder(match sized_crit.sty { @@ -1836,7 +1837,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Where(ty::Binder(tys.to_vec())) } - ty::TyStruct(..) | ty::TyEnum(..) | + ty::TyStruct(..) | ty::TyUnion(..) | ty::TyEnum(..) | ty::TyProjection(..) | ty::TyParam(..) | ty::TyAnon(..) => { // Fallback to whatever user-defined impls exist in this case. None @@ -1933,7 +1934,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { substs.types().collect() } - ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => { + ty::TyStruct(def, substs) | ty::TyUnion(def, substs) | ty::TyEnum(def, substs) => { def.all_fields() .map(|f| f.ty(self.tcx(), substs)) .collect() diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs index 53bf046d6b5..d7d4693c116 100644 --- a/src/librustc/ty/contents.rs +++ b/src/librustc/ty/contents.rs @@ -224,7 +224,8 @@ impl<'a, 'tcx> ty::TyS<'tcx> { |ty| tc_ty(tcx, *ty, cache)) } - ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => { + ty::TyStruct(def, substs) | ty::TyUnion(def, substs) | + ty::TyEnum(def, substs) => { let mut res = TypeContents::union(&def.variants, |v| { TypeContents::union(&v.fields, |f| { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 725bbf6adfd..8dd7bc562d7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1032,8 +1032,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { pub fn print_debug_stats(self) { sty_debug_print!( self, - TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, - TyTrait, TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon); + TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, TyTrait, + TyStruct, TyUnion, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon); println!("Substs interner: #{}", self.interners.substs.borrow().len()); println!("BareFnTy interner: #{}", self.interners.bare_fn.borrow().len()); diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 3d60d326b2b..0e33e396f7e 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -247,6 +247,9 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::TyStruct(def, _) => { format!("struct `{}`", tcx.item_path_str(def.did)) } + ty::TyUnion(def, _) => { + format!("union `{}`", tcx.item_path_str(def.did)) + } ty::TyClosure(..) => "closure".to_string(), ty::TyTuple(_) => "tuple".to_string(), ty::TyInfer(ty::TyVar(_)) => "inferred type".to_string(), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index f7472d611be..23678d1e377 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -66,6 +66,9 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::TyStruct(def, _) => { Some(StructSimplifiedType(def.did)) } + ty::TyUnion(..) => { + unimplemented_unions!(); + } ty::TyRef(_, mt) => { // since we introduce auto-refs during method lookup, we // just treat &T and T as equivalent from the point of diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 1afd49ab47f..ce6e4d6516e 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -102,7 +102,7 @@ impl FlagComputation { } } - &ty::TyEnum(_, substs) | &ty::TyStruct(_, substs) => { + &ty::TyEnum(_, substs) | &ty::TyStruct(_, substs) | &ty::TyUnion(_, substs) => { self.add_substs(substs); } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 62bd30e2555..42ec2b18fb0 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -320,6 +320,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> { match ty.sty { ty::TyStruct(adt_def, _) | + ty::TyUnion(adt_def, _) | ty::TyEnum(adt_def, _) => Some(adt_def.did), ty::TyTrait(ref data) => Some(data.principal.def_id()), diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 1ede8545e08..622966ca5ab 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -896,6 +896,9 @@ impl<'a, 'gcx, 'tcx> Layout { non_zero: Some(def.did) == tcx.lang_items.non_zero() } } + ty::TyUnion(..) => { + unimplemented_unions!(); + } ty::TyEnum(def, substs) => { let hint = *tcx.lookup_repr_hints(def.did).get(0) .unwrap_or(&attr::ReprAny); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e9c01f5bad6..ddf25538ee4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1421,6 +1421,7 @@ bitflags! { const IS_PHANTOM_DATA = 1 << 3, const IS_SIMD = 1 << 4, const IS_FUNDAMENTAL = 1 << 5, + const IS_UNION = 1 << 7, } } @@ -1818,7 +1819,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> { } } - TyEnum(adt, substs) | TyStruct(adt, substs) => { + TyEnum(adt, substs) | TyStruct(adt, substs) | TyUnion(adt, substs) => { // recursive case let adt = tcx.lookup_adt_def_master(adt.did); adt.calculate_sized_constraint_inner(tcx, stack); diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index 4d5b38212f6..a7bb0374b75 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -174,6 +174,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::TyNever | // ... ty::TyEnum(..) | // OutlivesNominalType ty::TyStruct(..) | // OutlivesNominalType + ty::TyUnion(..) | // OutlivesNominalType ty::TyBox(..) | // OutlivesNominalType (ish) ty::TyAnon(..) | // OutlivesNominalType (ish) ty::TyStr | // OutlivesScalar (ish) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index ad3769605ab..952641f6832 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -495,6 +495,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyRef(r.fold_with(folder), tm.fold_with(folder)) } ty::TyStruct(did, substs) => ty::TyStruct(did, substs.fold_with(folder)), + ty::TyUnion(did, substs) => ty::TyUnion(did, substs.fold_with(folder)), ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)), ty::TyProjection(ref data) => ty::TyProjection(data.fold_with(folder)), ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)), @@ -524,6 +525,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyFnPtr(ref f) => f.visit_with(visitor), ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor), ty::TyStruct(_did, ref substs) => substs.visit_with(visitor), + ty::TyUnion(_did, ref substs) => substs.visit_with(visitor), ty::TyClosure(_did, ref substs) => substs.visit_with(visitor), ty::TyProjection(ref data) => data.visit_with(visitor), ty::TyAnon(_, ref substs) => substs.visit_with(visitor), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 0e3f18c4474..b023cdad9ee 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -120,6 +120,11 @@ pub enum TypeVariants<'tcx> { /// See warning about substitutions for enumerated types. TyStruct(AdtDef<'tcx>, &'tcx Substs<'tcx>), + /// A union type, defined with `union`. + /// + /// See warning about substitutions for enumerated types. + TyUnion(AdtDef<'tcx>, &'tcx Substs<'tcx>), + /// `Box<T>`; this is nominally a struct in the documentation, but is /// special-cased internally. For example, it is possible to implicitly /// move the contents of a box out of that box, and methods of any type @@ -1227,6 +1232,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } TyEnum(_, substs) | TyStruct(_, substs) | + TyUnion(_, substs) | TyAnon(_, substs) => { substs.regions().collect() } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 77d16287fed..971fc2cee80 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -430,6 +430,7 @@ impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> { TyUint(u) => self.hash(u), TyFloat(f) => self.hash(f), TyStruct(d, _) | + TyUnion(d, _) | TyEnum(d, _) => self.def_id(d.did), TyArray(_, n) => self.hash(n), TyRawPtr(m) | @@ -558,7 +559,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { }) => Some(true), TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) | - TyClosure(..) | TyEnum(..) | TyStruct(..) | TyAnon(..) | + TyClosure(..) | TyEnum(..) | TyStruct(..) | TyUnion(..) | TyAnon(..) | TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None }.unwrap_or_else(|| !self.impls_bound(tcx, param_env, ty::BoundCopy, span)); @@ -598,7 +599,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { TyStr | TyTrait(..) | TySlice(_) => Some(false), - TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) | + TyEnum(..) | TyStruct(..) | TyUnion(..) | TyProjection(..) | TyParam(..) | TyInfer(..) | TyAnon(..) | TyError => None }.unwrap_or_else(|| self.impls_bound(tcx, param_env, ty::BoundSized, span)); diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 409f5a85997..cea3bd6348d 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -95,6 +95,7 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) { } ty::TyEnum(_, ref substs) | ty::TyStruct(_, ref substs) | + ty::TyUnion(_, ref substs) | ty::TyAnon(_, ref substs) => { stack.extend(substs.types().rev()); } diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index aef646a7aac..599e2be4db2 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -337,7 +337,8 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } ty::TyEnum(def, substs) | - ty::TyStruct(def, substs) => { + ty::TyStruct(def, substs) | + ty::TyUnion(def, substs) => { // WfNominalType let obligations = self.nominal_obligations(def.did, substs); self.out.extend(obligations); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 7e2cc2938ca..d0e02f2e8ac 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use hir::def_id::DefId; use ty::subst::{self, Subst, Substs}; use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; -use ty::{TyBool, TyChar, TyStruct, TyEnum}; +use ty::{TyBool, TyChar, TyStruct, TyUnion, TyEnum}; use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; use ty::TyClosure; @@ -869,7 +868,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { TyInfer(infer_ty) => write!(f, "{}", infer_ty), TyError => write!(f, "[type error]"), TyParam(ref param_ty) => write!(f, "{}", param_ty), - TyEnum(def, substs) | TyStruct(def, substs) => { + TyEnum(def, substs) | TyStruct(def, substs) | TyUnion(def, substs) => { ty::tls::with(|tcx| { if def.did.is_local() && !tcx.tcache.borrow().contains_key(&def.did) { diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 40e78c007cc..54cec3fd7e1 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -377,7 +377,8 @@ enum FfiResult { FfiSafe, FfiUnsafe(&'static str), FfiBadStruct(DefId, &'static str), - FfiBadEnum(DefId, &'static str) + FfiBadUnion(DefId, &'static str), + FfiBadEnum(DefId, &'static str), } /// Check if this enum can be safely exported based on the @@ -452,12 +453,32 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let r = self.check_type_for_ffi(cache, field_ty); match r { FfiSafe => {} - FfiBadStruct(..) | FfiBadEnum(..) => { return r; } + FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; } FfiUnsafe(s) => { return FfiBadStruct(def.did, s); } } } FfiSafe } + ty::TyUnion(def, substs) => { + if !cx.lookup_repr_hints(def.did).contains(&attr::ReprExtern) { + return FfiUnsafe( + "found union without foreign-function-safe \ + representation annotation in foreign module, \ + consider adding a #[repr(C)] attribute to \ + the type"); + } + + for field in &def.struct_variant().fields { + let field_ty = cx.normalize_associated_type(&field.ty(cx, substs)); + let r = self.check_type_for_ffi(cache, field_ty); + match r { + FfiSafe => {} + FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; } + FfiUnsafe(s) => { return FfiBadUnion(def.did, s); } + } + } + FfiSafe + } ty::TyEnum(def, substs) => { if def.variants.is_empty() { // Empty enums are okay... although sort of useless. @@ -507,7 +528,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let r = self.check_type_for_ffi(cache, arg); match r { FfiSafe => {} - FfiBadStruct(..) | FfiBadEnum(..) => { return r; } + FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => { return r; } FfiUnsafe(s) => { return FfiBadEnum(def.did, s); } } } @@ -614,6 +635,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { &format!("found non-foreign-function-safe member in \ struct marked #[repr(C)]: {}", s)); } + FfiResult::FfiBadUnion(_, s) => { + // FIXME: This diagnostic is difficult to read, and doesn't + // point at the relevant field. + self.cx.span_lint(IMPROPER_CTYPES, sp, + &format!("found non-foreign-function-safe member in \ + union marked #[repr(C)]: {}", s)); + } FfiResult::FfiBadEnum(_, s) => { // FIXME: This diagnostic is difficult to read, and doesn't // point at the relevant variant. diff --git a/src/librustc_metadata/tyencode.rs b/src/librustc_metadata/tyencode.rs index 954ca878c01..b334a21c07c 100644 --- a/src/librustc_metadata/tyencode.rs +++ b/src/librustc_metadata/tyencode.rs @@ -170,6 +170,11 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx enc_substs(w, cx, substs); write!(w, "]"); } + ty::TyUnion(def, substs) => { + write!(w, "u[{}|", (cx.ds)(cx.tcx, def.did)); + enc_substs(w, cx, substs); + write!(w, "]"); + } ty::TyClosure(def, substs) => { write!(w, "k[{}|", (cx.ds)(cx.tcx, def)); enc_substs(w, cx, substs.func_substs); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index bea6f30faec..47b3bb36cb9 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -798,6 +798,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, /* nothing to do */ } ty::TyStruct(ref adt_def, substs) | + ty::TyUnion(ref adt_def, substs) | ty::TyEnum(ref adt_def, substs) => { for field in adt_def.all_fields() { let field_type = monomorphize::apply_param_substs(scx, diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index f757578e695..bd839243e20 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -45,6 +45,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty::TyUint(uint_ty) => output.push_str(uint_ty.ty_to_string()), ty::TyFloat(float_ty) => output.push_str(float_ty.ty_to_string()), ty::TyStruct(def, substs) | + ty::TyUnion(def, substs) | ty::TyEnum(def, substs) => { push_item_name(cx, def.did, qualified, output); push_type_params(cx, substs, output); diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 8a0f37230c8..deef0b09a17 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -397,6 +397,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TyFloat(ast::FloatTy::F32) => output.push_str("f32"), ty::TyFloat(ast::FloatTy::F64) => output.push_str("f64"), ty::TyStruct(adt_def, substs) | + ty::TyUnion(adt_def, substs) | ty::TyEnum(adt_def, substs) => { push_item_name(tcx, adt_def.did, output); push_type_params(tcx, substs, &[], output); diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 6605d12e2e1..d5d8f049681 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -89,27 +89,23 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ Type::nil(cx) } - ty::TyTuple(..) | ty::TyEnum(..) | ty::TyClosure(..) => { - let repr = adt::represent_type(cx, t); - adt::sizing_type_of(cx, &repr, false) + ty::TyStruct(..) if t.is_simd() => { + let e = t.simd_type(cx.tcx()); + if !e.is_machine() { + cx.sess().fatal(&format!("monomorphising SIMD type `{}` with \ + a non-machine element type `{}`", + t, e)) + } + let llet = type_of(cx, e); + let n = t.simd_size(cx.tcx()) as u64; + ensure_array_fits_in_address_space(cx, llet, n, t); + Type::vector(&llet, n) } - ty::TyStruct(..) => { - if t.is_simd() { - let e = t.simd_type(cx.tcx()); - if !e.is_machine() { - cx.sess().fatal(&format!("monomorphising SIMD type `{}` with \ - a non-machine element type `{}`", - t, e)) - } - let llet = type_of(cx, e); - let n = t.simd_size(cx.tcx()) as u64; - ensure_array_fits_in_address_space(cx, llet, n, t); - Type::vector(&llet, n) - } else { - let repr = adt::represent_type(cx, t); - adt::sizing_type_of(cx, &repr, false) - } + ty::TyTuple(..) | ty::TyStruct(..) | ty::TyUnion(..) | + ty::TyEnum(..) | ty::TyClosure(..) => { + let repr = adt::represent_type(cx, t); + adt::sizing_type_of(cx, &repr, false) } ty::TyProjection(..) | ty::TyInfer(..) | ty::TyParam(..) | @@ -244,15 +240,6 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> ty::TyUint(t) => Type::uint_from_ty(cx, t), ty::TyFloat(t) => Type::float_from_ty(cx, t), ty::TyNever => Type::nil(cx), - ty::TyEnum(def, ref substs) => { - // Only create the named struct, but don't fill it in. We - // fill it in *after* placing it into the type cache. This - // avoids creating more than one copy of the enum when one - // of the enum's variants refers to the enum itself. - let repr = adt::represent_type(cx, t); - let name = llvm_type_name(cx, def.did, substs); - adt::incomplete_type_of(cx, &repr, &name[..]) - } ty::TyClosure(..) => { // Only create the named struct, but don't fill it in. We // fill it in *after* placing it into the type cache. @@ -307,26 +294,28 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> let repr = adt::represent_type(cx, t); adt::type_of(cx, &repr) } - ty::TyStruct(def, ref substs) => { - if t.is_simd() { - let e = t.simd_type(cx.tcx()); - if !e.is_machine() { - cx.sess().fatal(&format!("monomorphising SIMD type `{}` with \ - a non-machine element type `{}`", - t, e)) - } - let llet = in_memory_type_of(cx, e); - let n = t.simd_size(cx.tcx()) as u64; - ensure_array_fits_in_address_space(cx, llet, n, t); - Type::vector(&llet, n) - } else { - // Only create the named struct, but don't fill it in. We fill it - // in *after* placing it into the type cache. This prevents - // infinite recursion with recursive struct types. - let repr = adt::represent_type(cx, t); - let name = llvm_type_name(cx, def.did, substs); - adt::incomplete_type_of(cx, &repr, &name[..]) + ty::TyStruct(..) if t.is_simd() => { + let e = t.simd_type(cx.tcx()); + if !e.is_machine() { + cx.sess().fatal(&format!("monomorphising SIMD type `{}` with \ + a non-machine element type `{}`", + t, e)) } + let llet = in_memory_type_of(cx, e); + let n = t.simd_size(cx.tcx()) as u64; + ensure_array_fits_in_address_space(cx, llet, n, t); + Type::vector(&llet, n) + } + ty::TyStruct(def, ref substs) | + ty::TyUnion(def, ref substs) | + ty::TyEnum(def, ref substs) => { + // Only create the named struct, but don't fill it in. We + // fill it in *after* placing it into the type cache. This + // avoids creating more than one copy of the enum when one + // of the enum's variants refers to the enum itself. + let repr = adt::represent_type(cx, t); + let name = llvm_type_name(cx, def.did, substs); + adt::incomplete_type_of(cx, &repr, &name[..]) } ty::TyInfer(..) | diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 3a607677433..b73b8b99887 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -439,7 +439,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>( cx, context, ity, depth+1) } - ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => { + ty::TyStruct(def, substs) | ty::TyUnion(def, substs) | ty::TyEnum(def, substs) => { let did = def.did; for variant in &def.variants { for field in variant.fields.iter() { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index f743ef21875..a20195bd801 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -24,7 +24,7 @@ use rustc::ty::{ImplOrTraitItemId, ConstTraitItemId}; use rustc::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment}; use rustc::ty::{Ty, TyBool, TyChar, TyEnum, TyError}; use rustc::ty::{TyParam, TyRawPtr}; -use rustc::ty::{TyRef, TyStruct, TyTrait, TyNever, TyTuple}; +use rustc::ty::{TyRef, TyStruct, TyUnion, TyTrait, TyNever, TyTuple}; use rustc::ty::{TyStr, TyArray, TySlice, TyFloat, TyInfer, TyInt}; use rustc::ty::{TyUint, TyClosure, TyBox, TyFnDef, TyFnPtr}; use rustc::ty::{TyProjection, TyAnon}; @@ -70,7 +70,8 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { fn get_base_type_def_id(&self, span: Span, ty: Ty<'tcx>) -> Option<DefId> { match ty.sty { TyEnum(def, _) | - TyStruct(def, _) => { + TyStruct(def, _) | + TyUnion(def, _) => { Some(def.did) } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 888709d2572..e20e74be67c 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -344,7 +344,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } ty::TyEnum(def, substs) | - ty::TyStruct(def, substs) => { + ty::TyStruct(def, substs) | + ty::TyUnion(def, substs) => { let item_type = self.tcx().lookup_item_type(def.did); // This edge is actually implied by the call to diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e4b6a30d5bc..92bb265ca99 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1801,6 +1801,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> { decl: (cx.map.local_def_id(0), &fty.sig).clean(cx), abi: fty.abi, }), + ty::TyUnion(..) => unimplemented_unions!(), ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => { let did = def.did; |
