diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 967eb3ff74f..d7a58f4cdd0 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3312,10 +3312,10 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> { variants: Vec>) -> Self { let mut flags = AdtFlags::NO_ADT_FLAGS; let attrs = tcx.get_attrs(did); - if attrs.iter().any(|item| item.check_name("fundamental")) { + if attr::contains_name(&attrs, "fundamental") { flags = flags | AdtFlags::IS_FUNDAMENTAL; } - if attrs.iter().any(|item| item.check_name("simd")) { + if tcx.lookup_simd(did) { flags = flags | AdtFlags::IS_SIMD; } if Some(did) == tcx.lang_items.phantom_data() { @@ -6116,6 +6116,7 @@ impl<'tcx> ctxt<'tcx> { /// Determine whether an item is annotated with `#[simd]` pub fn lookup_simd(&self, did: DefId) -> bool { self.has_attr(did, "simd") + || self.lookup_repr_hints(did).contains(&attr::ReprSimd) } /// Obtain the representation annotation for a struct definition. diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 326d1e2361e..0d34cce919a 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -615,6 +615,9 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp attr::ReprPacked => { cx.tcx().sess.bug("range_to_inttype: found ReprPacked on an enum"); } + attr::ReprSimd => { + cx.tcx().sess.bug("range_to_inttype: found ReprSimd on an enum"); + } } for &ity in attempts { if bounds_usable(cx, ity, bounds) { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bf5d1373d0b..e32964db748 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4421,6 +4421,9 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, "discriminant type specified here"); } } + attr::ReprSimd => { + ccx.tcx.sess.bug("range_to_inttype: found ReprSimd on an enum"); + } attr::ReprPacked => { ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum"); } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 5e16465b4d4..3de9ba51974 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -579,6 +579,7 @@ pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec Some(ReprExtern), "packed" => Some(ReprPacked), + "simd" => Some(ReprSimd), _ => match int_type_of_word(&word) { Some(ity) => Some(ReprInt(item.span, ity)), None => { @@ -628,6 +629,7 @@ pub enum ReprAttr { ReprInt(Span, IntType), ReprExtern, ReprPacked, + ReprSimd, } impl ReprAttr { @@ -636,7 +638,8 @@ impl ReprAttr { ReprAny => false, ReprInt(_sp, ity) => ity.is_ffi_safe(), ReprExtern => true, - ReprPacked => false + ReprPacked => false, + ReprSimd => true, } } } diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 1f4860b7ec1..f8f63e94ee5 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -739,7 +739,7 @@ fn find_repr_type_name(diagnostic: &SpanHandler, for a in type_attrs { for r in &attr::find_repr_attrs(diagnostic, a) { repr_type_name = match *r { - attr::ReprAny | attr::ReprPacked => continue, + attr::ReprAny | attr::ReprPacked | attr::ReprSimd => continue, attr::ReprExtern => "i32", attr::ReprInt(_, attr::SignedInt(ast::TyIs)) => "isize", diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 694a1a43f59..a12291161f7 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -177,6 +177,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ // Allows macros to appear in the type position. ("type_macros", "1.3.0", Active), + + // allow `repr(simd)`, and importing the various simd intrinsics + ("simd_basics", "1.3.0", Active), ]; // (changing above list without updating src/doc/reference.md makes @cmr sad) @@ -359,6 +362,7 @@ pub struct Features { pub allow_box: bool, pub allow_pushpop_unsafe: bool, pub simd_ffi: bool, + pub simd_basics: bool, pub unmarked_api: bool, pub negate_unsigned: bool, /// spans of #![feature] attrs for stable language features. for error reporting @@ -388,6 +392,7 @@ impl Features { allow_box: false, allow_pushpop_unsafe: false, simd_ffi: false, + simd_basics: false, unmarked_api: false, negate_unsigned: false, declared_stable_lang_features: Vec::new(), @@ -660,6 +665,20 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { if attr::contains_name(&i.attrs[..], "simd") { self.gate_feature("simd", i.span, "SIMD types are experimental and possibly buggy"); + self.context.span_handler.span_warn(i.span, + "the `#[simd]` attribute is deprecated, \ + use `#[repr(simd)]` instead"); + } + for attr in &i.attrs { + if attr.name() == "repr" { + for item in attr.meta_item_list().unwrap_or(&[]) { + if item.name() == "simd" { + self.gate_feature("simd_basics", i.span, + "SIMD types are experimental and possibly buggy"); + + } + } + } } } @@ -892,6 +911,7 @@ fn check_crate_inner(cm: &CodeMap, span_handler: &SpanHandler, allow_box: cx.has_feature("box_syntax"), allow_pushpop_unsafe: cx.has_feature("pushpop_unsafe"), simd_ffi: cx.has_feature("simd_ffi"), + simd_basics: cx.has_feature("simd_basics"), unmarked_api: cx.has_feature("unmarked_api"), negate_unsigned: cx.has_feature("negate_unsigned"), declared_stable_lang_features: accepted_features, diff --git a/src/test/compile-fail/feature-gate-repr-simd.rs b/src/test/compile-fail/feature-gate-repr-simd.rs new file mode 100644 index 00000000000..fdafb2ad950 --- /dev/null +++ b/src/test/compile-fail/feature-gate-repr-simd.rs @@ -0,0 +1,14 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[repr(simd)] +struct Foo(u64, u64); //~ error: SIMD types are experimental + +fn main() {}