diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 3e041543977..ee4e568a5ca 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -72,6 +72,7 @@ - [proc_macro](language-features/proc-macro.md) - [quote](language-features/quote.md) - [relaxed_adts](language-features/relaxed-adts.md) + - [repr_align](language-features/repr-align.md) - [repr_simd](language-features/repr-simd.md) - [rustc_attrs](language-features/rustc-attrs.md) - [rustc_diagnostic_macros](language-features/rustc-diagnostic-macros.md) diff --git a/src/doc/unstable-book/src/language-features/repr-align.md b/src/doc/unstable-book/src/language-features/repr-align.md new file mode 100644 index 00000000000..deea04f4c51 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/repr-align.md @@ -0,0 +1,11 @@ +# `repr_align` + +The tracking issue for this feature is: [#33626] + +[#33626]: https://github.com/rust-lang/rust/issues/33626 + +------------------------ + + + + diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 442345ceb3c..82492d97627 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -972,19 +972,24 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec } else if let Some((name, value)) = item.name_value_literal() { if name == "align" { recognised = true; - let mut valid_align = false; + let mut align_error = None; if let ast::LitKind::Int(align, ast::LitIntType::Unsuffixed) = value.node { if align.is_power_of_two() { // rustc::ty::layout::Align restricts align to <= 32768 if align <= 32768 { acc.push(ReprAlign(align as u16)); - valid_align = true; + } else { + align_error = Some("larger than 32768"); } + } else { + align_error = Some("not a power of two"); } + } else { + align_error = Some("not an unsuffixed integer"); } - if !valid_align { + if let Some(align_error) = align_error { span_err!(diagnostic, item.span, E0589, - "align representation must be a u16 power of two"); + "invalid `repr(align)` attribute: {}", align_error); } } } diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 775775875a4..01d1277ea62 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -292,5 +292,5 @@ register_diagnostics! { E0556, // malformed feature, expected just one word E0557, // feature has been removed E0584, // file for module `..` found at both .. and .. - E0589, // align representation must be a u16 power of two + E0589, // invalid `repr(align)` attribute } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 175447e1112..9b55a860b35 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -338,6 +338,9 @@ declare_features! ( // Allows the `catch {...}` expression (active, catch_expr, "1.17.0", Some(31436)), + // Allows `repr(align(u16))` struct attribute (RFC 1358) + (active, repr_align, "1.17.0", Some(33626)), + // See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work. (active, rvalue_static_promotion, "1.15.1", Some(38865)), @@ -1189,6 +1192,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { and possibly buggy"); } + if item.check_name("align") { + gate_feature_post!(&self, repr_align, i.span, + "the struct `#[repr(align(u16))]` attribute \ + is experimental"); + } } } } diff --git a/src/test/compile-fail/conflicting-repr-hints.rs b/src/test/compile-fail/conflicting-repr-hints.rs index af38673d365..01fa3ffbaa6 100644 --- a/src/test/compile-fail/conflicting-repr-hints.rs +++ b/src/test/compile-fail/conflicting-repr-hints.rs @@ -10,6 +10,7 @@ #![allow(dead_code)] #![feature(attr_literals)] +#![feature(repr_align)] #[repr(C)] enum A { A } diff --git a/src/test/compile-fail/feature-gate-repr_align.rs b/src/test/compile-fail/feature-gate-repr_align.rs new file mode 100644 index 00000000000..8e986e197f2 --- /dev/null +++ b/src/test/compile-fail/feature-gate-repr_align.rs @@ -0,0 +1,15 @@ +// Copyright 2017 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. +#![feature(attr_literals)] + +#[repr(align(64))] +struct Foo(u64, u64); //~ error: the struct `#[repr(align(u16))]` attribute is experimental + +fn main() {} diff --git a/src/test/compile-fail/repr-align.rs b/src/test/compile-fail/repr-align.rs index 96dfe1c05f9..eb0b27fe9c0 100644 --- a/src/test/compile-fail/repr-align.rs +++ b/src/test/compile-fail/repr-align.rs @@ -9,14 +9,15 @@ // except according to those terms. #![allow(dead_code)] #![feature(attr_literals)] +#![feature(repr_align)] -#[repr(align(16.0))] //~ ERROR: align representation must be a u16 power of two +#[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer struct A(i32); -#[repr(align(15))] //~ ERROR: align representation must be a u16 power of two +#[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two struct B(i32); -#[repr(align(65536))] //~ ERROR: align representation must be a u16 power of tw +#[repr(align(65536))] //~ ERROR: invalid `repr(align)` attribute: larger than 32768 struct C(i32); fn main() {} diff --git a/src/test/compile-fail/repr-packed-contains-align.rs b/src/test/compile-fail/repr-packed-contains-align.rs index 11829dfae8c..c584dcf3e59 100644 --- a/src/test/compile-fail/repr-packed-contains-align.rs +++ b/src/test/compile-fail/repr-packed-contains-align.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(attr_literals)] +#![feature(repr_align)] #![allow(dead_code)] #[repr(align(16))] diff --git a/src/test/run-pass/align-struct.rs b/src/test/run-pass/align-struct.rs index 4793189d366..0b9a3594502 100644 --- a/src/test/run-pass/align-struct.rs +++ b/src/test/run-pass/align-struct.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(attr_literals)] +#![feature(repr_align)] use std::mem; diff --git a/src/test/ui/print_type_sizes/repr-align.rs b/src/test/ui/print_type_sizes/repr-align.rs index ea2910f86c4..e9b43145de4 100644 --- a/src/test/ui/print_type_sizes/repr-align.rs +++ b/src/test/ui/print_type_sizes/repr-align.rs @@ -18,6 +18,7 @@ // aligned (while on most it is 8-byte aligned) and so the resulting // padding and overall computed sizes can be quite different. #![feature(attr_literals)] +#![feature(repr_align)] #![allow(dead_code)] #[repr(align(16))]