diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 733fa0e71b4..d54271b7531 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3179,11 +3179,12 @@ impl<'tcx> TraitDef<'tcx> { bitflags! { flags ADTFlags: u32 { const NO_ADT_FLAGS = 0, - const IS_FUNDAMENTAL = 1 << 0, - const IS_PHANTOM_DATA = 1 << 1, - const IS_DTORCK = 1 << 2, // is this a dtorck type? - const IS_DTORCK_VALID = 1 << 3, - const IS_ENUM = 1 << 4 + const IS_ENUM = 1 << 0, + const IS_DTORCK = 1 << 1, // is this a dtorck type? + const IS_DTORCK_VALID = 1 << 2, + const IS_PHANTOM_DATA = 1 << 3, + const IS_SIMD = 1 << 4, + const IS_FUNDAMENTAL = 1 << 5, } } @@ -3244,9 +3245,13 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> { kind: ADTKind, variants: Vec>) -> Self { let mut flags = ADTFlags::NO_ADT_FLAGS; - if tcx.has_attr(did, "fundamental") { + let attrs = tcx.get_attrs(did); + if attrs.iter().any(|item| item.check_name("fundamental")) { flags = flags | ADTFlags::IS_FUNDAMENTAL; } + if attrs.iter().any(|item| item.check_name("simd")) { + flags = flags | ADTFlags::IS_SIMD; + } if Some(did) == tcx.lang_items.phantom_data() { flags = flags | ADTFlags::IS_PHANTOM_DATA; } @@ -3289,6 +3294,11 @@ impl<'tcx, 'lt> ADTDef_<'tcx, 'lt> { self.flags.get().intersects(ADTFlags::IS_FUNDAMENTAL) } + #[inline] + pub fn is_simd(&self) -> bool { + self.flags.get().intersects(ADTFlags::IS_SIMD) + } + #[inline] pub fn is_phantom_data(&self) -> bool { self.flags.get().intersects(ADTFlags::IS_PHANTOM_DATA) @@ -4203,9 +4213,10 @@ impl<'tcx> TyS<'tcx> { } } - pub fn is_simd(&self, cx: &ctxt) -> bool { + #[inline] + pub fn is_simd(&self) -> bool { match self.sty { - TyStruct(def, _) => cx.lookup_simd(def.did), + TyStruct(def, _) => def.is_simd(), _ => false } } @@ -5979,7 +5990,6 @@ impl<'tcx> ctxt<'tcx> { /// Obtain the representation annotation for a struct definition. pub fn lookup_repr_hints(&self, did: DefId) -> Rc> { - // TODO: remove memoized(&self.repr_hint_cache, did, |did: DefId| { Rc::new(if did.krate == LOCAL_CRATE { self.get_attrs(did).iter().flat_map(|meta| { diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index d119e0006c6..a0dd489cd8a 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -621,7 +621,7 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>( let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0, false); (ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false) } - ty::TyStruct(_, _) if rhs_t.is_simd(cx.tcx()) => { + ty::TyStruct(def, _) if def.is_simd() => { let mut res = C_bool(cx.ccx(), false); for i in 0 .. rhs_t.simd_size(cx.tcx()) { res = Or(cx, res, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 15c81b114d3..7bc6f4c8fe9 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -192,7 +192,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) - let simple = ty.is_scalar() || ty.is_unique() || ty.is_region_ptr() || type_is_newtype_immediate(ccx, ty) || - ty.is_simd(tcx); + ty.is_simd(); if simple && !type_is_fat_ptr(tcx, ty) { return true; } diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 7a9ddf5a99c..7aaed035f21 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -500,7 +500,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, debug!("const_expr_unadjusted: te1={}, ty={:?}", cx.tn().val_to_string(te1), ty); - let is_simd = ty.is_simd(cx.tcx()); + let is_simd = ty.is_simd(); let intype = if is_simd { ty.simd_type(cx.tcx()) } else { @@ -754,7 +754,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, (_, None) => cx.sess().span_bug(e.span, "missing struct field"), } }).collect::>(); - if ety.is_simd(cx.tcx()) { + if ety.is_simd() { C_vector(&cs[..]) } else { adt::trans_const(cx, &*repr, discr, &cs[..]) @@ -850,7 +850,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, const_fn_call(cx, ExprId(callee.id), did, &arg_vals, param_substs) } def::DefStruct(_) => { - if ety.is_simd(cx.tcx()) { + if ety.is_simd() { C_vector(&arg_vals[..]) } else { let repr = adt::represent_type(cx, ety); diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 98188a40e10..3ca639cc367 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -1175,7 +1175,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, StructMDF(StructMemberDescriptionFactory { variant: variant, substs: substs, - is_simd: struct_type.is_simd(cx.tcx()), + is_simd: struct_type.is_simd(), span: span, }) ) diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index baf14df5b80..c5043f867de 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -1453,7 +1453,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // panic occur before the ADT as a whole is ready. let custom_cleanup_scope = fcx.push_custom_cleanup_scope(); - if ty.is_simd(bcx.tcx()) { + if ty.is_simd() { // Issue 23112: The original logic appeared vulnerable to same // order-of-eval bug. But, SIMD values are tuple-structs; // i.e. functional record update (FRU) syntax is unavailable. @@ -1697,7 +1697,7 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("trans_eager_binop"); let tcx = bcx.tcx(); - let is_simd = lhs_t.is_simd(tcx); + let is_simd = lhs_t.is_simd(); let intype = if is_simd { lhs_t.simd_type(tcx) } else { @@ -2502,7 +2502,7 @@ fn build_unchecked_rshift<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // #1877, #10183: Ensure that input is always valid let rhs = shift_mask_rhs(bcx, rhs, binop_debug_loc); let tcx = bcx.tcx(); - let is_simd = lhs_t.is_simd(tcx); + let is_simd = lhs_t.is_simd(); let intype = if is_simd { lhs_t.simd_type(tcx) } else { diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index cafc0be74ba..225ff52a63c 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -449,7 +449,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, fn gate_simd_ffi(tcx: &ty::ctxt, decl: &ast::FnDecl, ty: &ty::BareFnTy) { if !tcx.sess.features.borrow().simd_ffi { let check = |ast_ty: &ast::Ty, ty: ty::Ty| { - if ty.is_simd(tcx) { + if ty.is_simd() { tcx.sess.span_err(ast_ty.span, &format!("use of SIMD type `{}` in FFI is highly experimental and \ may result in invalid code", diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index 30cf6f519fb..cf3cde8907f 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -419,7 +419,7 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in let ccx = bcx.ccx(); // First get the size of all statically known fields. // Don't use type_of::sizing_type_of because that expects t to be sized. - assert!(!t.is_simd(bcx.tcx())); + assert!(!t.is_simd()); let repr = adt::represent_type(ccx, t); let sizing_type = adt::sizing_type_context_of(ccx, &*repr, true); debug!("DST {} sizing_type: {}", t, sizing_type.to_string()); diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 91247ebd791..0b969360f53 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -222,7 +222,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ } ty::TyStruct(..) => { - if t.is_simd(cx.tcx()) { + if t.is_simd() { let llet = type_of(cx, t.simd_type(cx.tcx())); let n = t.simd_size(cx.tcx()) as u64; ensure_array_fits_in_address_space(cx, llet, n, t); @@ -404,7 +404,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> adt::type_of(cx, &*repr) } ty::TyStruct(def, ref substs) => { - if t.is_simd(cx.tcx()) { + if t.is_simd() { let llet = in_memory_type_of(cx, t.simd_type(cx.tcx())); let n = t.simd_size(cx.tcx()) as u64; ensure_array_fits_in_address_space(cx, llet, n, t); @@ -436,7 +436,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> // If this was an enum or struct, fill in the type now. match t.sty { ty::TyEnum(..) | ty::TyStruct(..) | ty::TyClosure(..) - if !t.is_simd(cx.tcx()) => { + if !t.is_simd() => { let repr = adt::represent_type(cx, t); adt::finish_type_of(cx, &*repr, &mut llty); } diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index c6d13d3b0a5..b139cb45bf2 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -21,7 +21,7 @@ use super::{ structurally_resolved_type, }; use middle::traits; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{Ty, HasTypeFlags}; use syntax::ast; use syntax::ast_util; use syntax::parse::token; @@ -41,7 +41,7 @@ pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, let lhs_ty = structurally_resolved_type(fcx, lhs_expr.span, fcx.expr_ty(lhs_expr)); let rhs_ty = structurally_resolved_type(fcx, rhs_expr.span, fcx.expr_ty(rhs_expr)); - if is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op) { + if is_builtin_binop(lhs_ty, rhs_ty, op) { enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op); fcx.write_nil(expr.id); } else { @@ -86,7 +86,7 @@ pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // traits, because their return type is not bool. Perhaps this // should change, but for now if LHS is SIMD we go down a // different path that bypassess all traits. - if lhs_ty.is_simd(fcx.tcx()) { + if lhs_ty.is_simd() { check_expr_coercable_to_type(fcx, rhs_expr, lhs_ty); let rhs_ty = fcx.resolve_type_vars_if_possible(fcx.expr_ty(lhs_expr)); let return_ty = enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op); @@ -123,7 +123,7 @@ pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let rhs_ty = fcx.resolve_type_vars_if_possible(rhs_ty); if !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var() && - is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op) + is_builtin_binop(lhs_ty, rhs_ty, op) { let builtin_return_ty = enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op); @@ -143,7 +143,7 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, op: ast::BinOp) -> Ty<'tcx> { - debug_assert!(is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op)); + debug_assert!(is_builtin_binop(lhs_ty, rhs_ty, op)); let tcx = fcx.tcx(); match BinOpCategory::from(op) { @@ -156,7 +156,7 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, BinOpCategory::Shift => { // For integers, the shift amount can be of any integral // type. For simd, the type must match exactly. - if lhs_ty.is_simd(tcx) { + if lhs_ty.is_simd() { demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty); } @@ -176,7 +176,7 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty); // if this is simd, result is same as lhs, else bool - if lhs_ty.is_simd(tcx) { + if lhs_ty.is_simd() { let unit_ty = lhs_ty.simd_type(tcx); debug!("enforce_builtin_binop_types: lhs_ty={:?} unit_ty={:?}", lhs_ty, @@ -415,8 +415,7 @@ impl BinOpCategory { /// Reason #2 is the killer. I tried for a while to always use /// overloaded logic and just check the types in constants/trans after /// the fact, and it worked fine, except for SIMD types. -nmatsakis -fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>, - lhs: Ty<'tcx>, +fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: ast::BinOp) -> bool @@ -429,28 +428,28 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>, BinOpCategory::Shift => { lhs.references_error() || rhs.references_error() || lhs.is_integral() && rhs.is_integral() || - lhs.is_simd(cx) && rhs.is_simd(cx) + lhs.is_simd() && rhs.is_simd() } BinOpCategory::Math => { lhs.references_error() || rhs.references_error() || lhs.is_integral() && rhs.is_integral() || lhs.is_floating_point() && rhs.is_floating_point() || - lhs.is_simd(cx) && rhs.is_simd(cx) + lhs.is_simd() && rhs.is_simd() } BinOpCategory::Bitwise => { lhs.references_error() || rhs.references_error() || lhs.is_integral() && rhs.is_integral() || lhs.is_floating_point() && rhs.is_floating_point() || - lhs.is_simd(cx) && rhs.is_simd(cx) || + lhs.is_simd() && rhs.is_simd() || lhs.is_bool() && rhs.is_bool() } BinOpCategory::Comparison => { lhs.references_error() || rhs.references_error() || lhs.is_scalar() && rhs.is_scalar() || - lhs.is_simd(cx) && rhs.is_simd(cx) + lhs.is_simd() && rhs.is_simd() } } }