/// # Examples
///
/// ```
- /// #![feature(vecdeque_rotate)]
- ///
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<_> = (0..10).collect();
/// }
/// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
/// ```
- #[unstable(feature = "vecdeque_rotate", issue = "56686")]
+ #[stable(feature = "vecdeque_rotate", since = "1.36.0")]
pub fn rotate_left(&mut self, mid: usize) {
assert!(mid <= self.len());
let k = self.len() - mid;
/// # Examples
///
/// ```
- /// #![feature(vecdeque_rotate)]
- ///
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<_> = (0..10).collect();
/// }
/// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
/// ```
- #[unstable(feature = "vecdeque_rotate", issue = "56686")]
+ #[stable(feature = "vecdeque_rotate", since = "1.36.0")]
pub fn rotate_right(&mut self, k: usize) {
assert!(k <= self.len());
let mid = self.len() - k;
#[test]
// Only tests the simple function definition with respect to intersection
fn test_is_disjoint() {
- let one = [1].into_iter().collect::<BTreeSet<_>>();
- let two = [2].into_iter().collect::<BTreeSet<_>>();
+ let one = [1].iter().collect::<BTreeSet<_>>();
+ let two = [2].iter().collect::<BTreeSet<_>>();
assert!(one.is_disjoint(&two));
}
#![feature(repeat_generic_slice)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
-#![feature(vecdeque_rotate)]
#![deny(rust_2018_idioms)]
use std::hash::{Hash, Hasher};
/// [`Layout::from_size_align`](#method.from_size_align).
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[inline]
- pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
+ pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
}
///
/// ```
/// let a = [0, 1, 2, 3, 4, 5];
- /// let mut iter = a.into_iter().step_by(2);
+ /// let mut iter = a.iter().step_by(2);
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&2));
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.into_iter().map(|x| 2 * x);
+ /// let mut iter = a.iter().map(|x| 2 * x);
///
/// assert_eq!(iter.next(), Some(2));
/// assert_eq!(iter.next(), Some(4));
/// ```
/// let a = [0i32, 1, 2];
///
- /// let mut iter = a.into_iter().filter(|x| x.is_positive());
+ /// let mut iter = a.iter().filter(|x| x.is_positive());
///
/// assert_eq!(iter.next(), Some(&1));
/// assert_eq!(iter.next(), Some(&2));
/// ```
/// let a = [0, 1, 2];
///
- /// let mut iter = a.into_iter().filter(|x| **x > 1); // need two *s!
+ /// let mut iter = a.iter().filter(|x| **x > 1); // need two *s!
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [0, 1, 2];
///
- /// let mut iter = a.into_iter().filter(|&x| *x > 1); // both & and *
+ /// let mut iter = a.iter().filter(|&x| *x > 1); // both & and *
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [0, 1, 2];
///
- /// let mut iter = a.into_iter().filter(|&&x| x > 1); // two &s
+ /// let mut iter = a.iter().filter(|&&x| x > 1); // two &s
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [-1i32, 0, 1];
///
- /// let mut iter = a.into_iter().skip_while(|x| x.is_negative());
+ /// let mut iter = a.iter().skip_while(|x| x.is_negative());
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&1));
/// ```
/// let a = [-1, 0, 1];
///
- /// let mut iter = a.into_iter().skip_while(|x| **x < 0); // need two *s!
+ /// let mut iter = a.iter().skip_while(|x| **x < 0); // need two *s!
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&1));
/// ```
/// let a = [-1, 0, 1, -2];
///
- /// let mut iter = a.into_iter().skip_while(|x| **x < 0);
+ /// let mut iter = a.iter().skip_while(|x| **x < 0);
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&1));
/// ```
/// let a = [-1i32, 0, 1];
///
- /// let mut iter = a.into_iter().take_while(|x| x.is_negative());
+ /// let mut iter = a.iter().take_while(|x| x.is_negative());
///
/// assert_eq!(iter.next(), Some(&-1));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [-1, 0, 1];
///
- /// let mut iter = a.into_iter().take_while(|x| **x < 0); // need two *s!
+ /// let mut iter = a.iter().take_while(|x| **x < 0); // need two *s!
///
/// assert_eq!(iter.next(), Some(&-1));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [-1, 0, 1, -2];
///
- /// let mut iter = a.into_iter().take_while(|x| **x < 0);
+ /// let mut iter = a.iter().take_while(|x| **x < 0);
///
/// assert_eq!(iter.next(), Some(&-1));
///
///
/// ```
/// let a = [1, 2, 3, 4];
- /// let mut iter = a.into_iter();
+ /// let mut iter = a.iter();
///
/// let result: Vec<i32> = iter.by_ref()
/// .take_while(|n| **n != 3)
/// ```
/// let a = [1, 2, 3];
///
- /// let iter = a.into_iter();
+ /// let iter = a.iter();
///
/// let sum: i32 = iter.take(5).fold(0, |acc, i| acc + i );
///
/// // let's try that again
/// let a = [1, 2, 3];
///
- /// let mut iter = a.into_iter();
+ /// let mut iter = a.iter();
///
/// // instead, we add in a .by_ref()
/// let sum: i32 = iter.by_ref().take(2).fold(0, |acc, i| acc + i );
/// let a = [1, 2, 3];
///
/// let (even, odd): (Vec<i32>, Vec<i32>) = a
- /// .into_iter()
+ /// .iter()
/// .partition(|&n| n % 2 == 0);
///
/// assert_eq!(even, vec![2]);
///
/// * `src` must be properly aligned.
///
-/// Like [`read`], `read_unaligned` creates a bitwise copy of `T`, regardless of
+/// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
/// value and the value at `*src` can [violate memory safety][read-ownership].
/// However, storing non-[`Copy`] types in volatile memory is almost certainly
--- /dev/null
+use core::alloc::Layout;
+
+#[test]
+fn const_unchecked_layout() {
+ const SIZE: usize = 0x2000;
+ const ALIGN: usize = 0x1000;
+ const LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(SIZE, ALIGN) };
+ assert_eq!(LAYOUT.size(), SIZE);
+ assert_eq!(LAYOUT.align(), ALIGN);
+}
#![feature(slice_partition_dedup)]
#![feature(copy_within)]
#![feature(int_error_matching)]
+#![feature(const_fn)]
#![warn(rust_2018_idioms)]
extern crate test;
+mod alloc;
mod any;
mod array;
mod ascii;
impl serialize::UseSpecializedEncodable for CrateNum {}
impl serialize::UseSpecializedDecodable for CrateNum {}
-/// A DefIndex is an index into the hir-map for a crate, identifying a
-/// particular definition. It should really be considered an interned
-/// shorthand for a particular DefPath.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
-pub struct DefIndex(u32);
-
-/// The crate root is always assigned index 0 by the AST Map code,
-/// thanks to `NodeCollector::new`.
-pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);
+newtype_index! {
+ /// A DefIndex is an index into the hir-map for a crate, identifying a
+ /// particular definition. It should really be considered an interned
+ /// shorthand for a particular DefPath.
+ pub struct DefIndex {
+ DEBUG_FORMAT = "DefIndex({})",
-impl fmt::Debug for DefIndex {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "DefIndex({})", self.as_array_index())
+ /// The crate root is always assigned index 0 by the AST Map code,
+ /// thanks to `NodeCollector::new`.
+ const CRATE_DEF_INDEX = 0,
}
}
impl DefIndex {
- /// Converts this DefIndex into a zero-based array index.
- #[inline]
- pub fn as_array_index(&self) -> usize {
- self.0 as usize
- }
-
- #[inline]
- pub fn from_array_index(i: usize) -> DefIndex {
- DefIndex(i as u32)
- }
-
// Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
// function maps the index of the macro within the crate (which is also the
// index of the macro in the CrateMetadata::proc_macros array) to the
// DefIndex for proc macros start from FIRST_FREE_DEF_INDEX,
// because the first FIRST_FREE_DEF_INDEX indexes are reserved
// for internal use.
- let def_index = DefIndex::from_array_index(
+ let def_index = DefIndex::from(
proc_macro_index.checked_add(FIRST_FREE_DEF_INDEX)
.expect("integer overflow adding `proc_macro_index`"));
assert!(def_index != CRATE_DEF_INDEX);
// This function is the reverse of from_proc_macro_index() above.
pub fn to_proc_macro_index(self: DefIndex) -> usize {
- self.as_array_index().checked_sub(FIRST_FREE_DEF_INDEX)
+ self.index().checked_sub(FIRST_FREE_DEF_INDEX)
.unwrap_or_else(|| {
bug!("using local index {:?} as proc-macro index", self)
})
}
-
- pub fn from_raw_u32(x: u32) -> DefIndex {
- DefIndex(x)
- }
-
- pub fn as_raw_u32(&self) -> u32 {
- self.0
- }
}
impl serialize::UseSpecializedEncodable for DefIndex {}
impl fmt::Debug for DefId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "DefId({}:{}", self.krate, self.index.as_array_index())?;
+ write!(f, "DefId({}:{}", self.krate, self.index.index())?;
ty::tls::with_opt(|opt_tcx| {
if let Some(tcx) = opt_tcx {
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>) {
debug!("hir_map: {:?} => {:?}", id, entry);
- let local_map = &mut self.map[id.owner.as_array_index()];
+ let local_map = &mut self.map[id.owner.index()];
let i = id.local_id.as_u32() as usize;
if local_map.is_none() {
*local_map = Some(IndexVec::with_capacity(i + 1));
def_path_hash: DefPathHash)
-> DefIndex {
let index = {
- let index = DefIndex::from_array_index(self.index_to_key.len());
+ let index = DefIndex::from(self.index_to_key.len());
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
self.index_to_key.push(key);
index
}
pub fn next_id(&self) -> DefIndex {
- DefIndex::from_array_index(self.index_to_key.len())
+ DefIndex::from(self.index_to_key.len())
}
#[inline(always)]
pub fn def_key(&self, index: DefIndex) -> DefKey {
- self.index_to_key[index.as_array_index()].clone()
+ self.index_to_key[index.index()].clone()
}
#[inline(always)]
pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
- let ret = self.def_path_hashes[index.as_array_index()];
+ let ret = self.def_path_hashes[index.index()];
debug!("def_path_hash({:?}) = {:?}", index, ret);
return ret
}
.map(|(index, &hash)| {
let def_id = DefId {
krate: cnum,
- index: DefIndex::from_array_index(index),
+ index: DefIndex::from(index),
};
(hash, def_id)
})
#[inline]
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
if def_id.krate == LOCAL_CRATE {
- let node_id = self.def_index_to_node[def_id.index.as_array_index()];
+ let node_id = self.def_index_to_node[def_id.index.index()];
if node_id != ast::DUMMY_NODE_ID {
return Some(node_id);
}
#[inline]
pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId {
- let node_id = self.def_index_to_node[def_index.as_array_index()];
+ let node_id = self.def_index_to_node[def_index.index()];
self.node_to_hir_id[node_id]
}
// Create the definition.
let index = self.table.allocate(key, def_path_hash);
- assert_eq!(index.as_array_index(), self.def_index_to_node.len());
+ assert_eq!(index.index(), self.def_index_to_node.len());
self.def_index_to_node.push(node_id);
// Some things for which we allocate DefIndices don't correspond to
.position(|k| *k == def_key)
.unwrap();
- DefIndex::from_array_index(index)
+ DefIndex::from(index)
}
fn name(&self) -> Symbol {
impl<'hir> Map<'hir> {
#[inline]
fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> {
- let local_map = self.map.get(id.owner.as_array_index())?;
+ let local_map = self.map.get(id.owner.index())?;
local_map.as_ref()?.get(id.local_id)?.as_ref()
}
local_map.iter_enumerated().filter_map(move |(i, entry)| entry.map(move |_| {
// Reconstruct the HirId based on the 3 indices we used to find it
HirId {
- owner: DefIndex::from_array_index(array_index),
+ owner: DefIndex::from(array_index),
local_id: i,
}
}))
}
let requested_node = env::var("RUST_REGION_GRAPH_NODE")
- .ok().and_then(|s| s.parse().map(DefIndex::from_raw_u32).ok());
+ .ok().and_then(|s| s.parse().map(DefIndex::from_u32).ok());
if requested_node.is_some() && requested_node != Some(context.index) {
return;
let mut new_str = String::new();
for c in output_template.chars() {
if c == '%' {
- new_str.push_str(&context.index.as_raw_u32().to_string());
+ new_str.push_str(&context.index.as_u32().to_string());
} else {
new_str.push(c);
}
.map(|s| &s == "?")
.unwrap_or(false);
let is_from = format!("{}", trait_ref).starts_with("std::convert::From<");
- let message = if is_try && is_from {
- Some(format!(
+ let (message, note) = if is_try && is_from {
+ (Some(format!(
"`?` couldn't convert the error to `{}`",
trait_ref.self_ty(),
+ )), Some(
+ "the question mark operation (`?`) implicitly performs a \
+ conversion on the error value using the `From` trait".to_owned()
))
} else {
- message
+ (message, note)
};
let mut err = struct_span_err!(
// negated `CrateNum` (so remote definitions are visited first) and then
// by a flattened version of the `DefIndex`.
trait_impls.sort_unstable_by_key(|def_id| {
- (-(def_id.krate.as_u32() as i64), def_id.index.as_array_index())
+ (-(def_id.krate.as_u32() as i64), def_id.index.index())
});
for impl_def_id in trait_impls {
// have to be user friendly.
let name = format!(
"hir_id_{}_{}",
- hir_id.owner.as_array_index(),
+ hir_id.owner.index(),
hir_id.local_id.index(),
);
let lcfg = LabelledCFG {
impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
#[inline]
fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
- Ok(DefIndex::from_raw_u32(self.read_u32()?))
+ Ok(DefIndex::from_u32(self.read_u32()?))
}
}
impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
#[inline]
fn specialized_encode(&mut self, def_index: &DefIndex) -> Result<(), Self::Error> {
- self.emit_u32(def_index.as_raw_u32())
+ self.emit_u32(def_index.as_u32())
}
}
pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry<'_>>) {
assert!(entry.position < (u32::MAX as usize));
let position = entry.position as u32;
- let array_index = item.as_array_index();
+ let array_index = item.index();
let positions = &mut self.positions;
assert!(u32::read_from_bytes_at(positions, array_index) == u32::MAX,
def_index,
self.len);
- let position = u32::read_from_bytes_at(bytes, 1 + def_index.as_array_index());
+ let position = u32::read_from_bytes_at(bytes, 1 + def_index.index());
if position == u32::MAX {
debug!("Index::lookup: position=u32::MAX");
None
format!(
"{}_{}",
def_id.krate.index(),
- def_id.index.as_array_index(),
+ def_id.index.index(),
)
}
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
let def_id = DefId {
krate: CrateNum::BuiltinMacros,
- index: DefIndex::from_array_index(self.macro_map.len()),
+ index: DefIndex::from(self.macro_map.len()),
};
let kind = ext.kind();
self.macro_map.insert(def_id, ext);
fn id_from_def_id(id: DefId) -> rls_data::Id {
rls_data::Id {
krate: id.krate.as_u32(),
- index: id.index.as_raw_u32(),
+ index: id.index.as_u32(),
}
}
"passes",
];
- for flag in deprecated_flags.into_iter() {
+ for flag in deprecated_flags.iter() {
if matches.opt_present(flag) {
let mut err = diag.struct_warn(&format!("the '{}' flag is considered deprecated",
flag));
crate_num,
DefId {
krate: crate_num,
- index: DefIndex::from_array_index(def_id.index.as_array_index() + 1),
+ index: DefIndex::from(def_id.index.index() + 1),
},
);
"methods",
"deref-methods",
"implementations",
- ].into_iter().map(|id| (String::from(*id))).collect()
+ ].iter().map(|id| (String::from(*id))).collect()
}
/// Generates the documentation for `crate` into the directory `dst`
fn item_constant(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
c: &clean::Constant) -> fmt::Result {
write!(w, "<pre class='rust const'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "{vis}const \
{name}: {typ}</pre>",
vis = VisSpace(&it.visibility),
fn item_static(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
s: &clean::Static) -> fmt::Result {
write!(w, "<pre class='rust static'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "{vis}static {mutability}\
{name}: {typ}</pre>",
vis = VisSpace(&it.visibility),
f.generics
).len();
write!(w, "{}<pre class='rust fn'>", render_spotlight_traits(it)?)?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w,
"{vis}{constness}{unsafety}{asyncness}{abi}fn \
{name}{generics}{decl}{where_clause}</pre>",
// Output the trait definition
wrap_into_docblock(w, |w| {
write!(w, "<pre class='rust trait'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, true)?;
write!(w, "{}{}{}trait {}{}{}",
VisSpace(&it.visibility),
UnsafetySpace(t.unsafety),
it: &clean::Item,
ty: &clean::Type,
_default: Option<&String>,
- link: AssocItemLink<'_>) -> fmt::Result {
- write!(w, "{}const <a href='{}' class=\"constant\"><b>{}</b></a>: {}",
+ link: AssocItemLink<'_>,
+ extra: &str) -> fmt::Result {
+ write!(w, "{}{}const <a href='{}' class=\"constant\"><b>{}</b></a>: {}",
+ extra,
VisSpace(&it.visibility),
naive_assoc_href(it, link),
it.name.as_ref().unwrap(),
fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item,
bounds: &[clean::GenericBound],
default: Option<&clean::Type>,
- link: AssocItemLink<'_>) -> fmt::Result {
- write!(w, "type <a href='{}' class=\"type\">{}</a>",
+ link: AssocItemLink<'_>,
+ extra: &str) -> fmt::Result {
+ write!(w, "{}type <a href='{}' class=\"type\">{}</a>",
+ extra,
naive_assoc_href(it, link),
it.name.as_ref().unwrap())?;
if !bounds.is_empty() {
} else {
(0, true)
};
- render_attributes(w, meth)?;
+ render_attributes(w, meth, false)?;
write!(w, "{}{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
{generics}{decl}{where_clause}",
if parent == ItemType::Trait { " " } else { "" },
method(w, item, m.header, &m.generics, &m.decl, link, parent)
}
clean::AssociatedConstItem(ref ty, ref default) => {
- assoc_const(w, item, ty, default.as_ref(), link)
+ assoc_const(w, item, ty, default.as_ref(), link,
+ if parent == ItemType::Trait { " " } else { "" })
}
clean::AssociatedTypeItem(ref bounds, ref default) => {
- assoc_type(w, item, bounds, default.as_ref(), link)
+ assoc_type(w, item, bounds, default.as_ref(), link,
+ if parent == ItemType::Trait { " " } else { "" })
}
_ => panic!("render_assoc_item called on non-associated-item")
}
s: &clean::Struct) -> fmt::Result {
wrap_into_docblock(w, |w| {
write!(w, "<pre class='rust struct'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, true)?;
render_struct(w,
it,
Some(&s.generics),
s: &clean::Union) -> fmt::Result {
wrap_into_docblock(w, |w| {
write!(w, "<pre class='rust union'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, true)?;
render_union(w,
it,
Some(&s.generics),
e: &clean::Enum) -> fmt::Result {
wrap_into_docblock(w, |w| {
write!(w, "<pre class='rust enum'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, true)?;
write!(w, "{}enum {}{}{}",
VisSpace(&it.visibility),
it.name.as_ref().unwrap(),
sym::non_exhaustive
];
-fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result {
+// The `top` parameter is used when generating the item declaration to ensure it doesn't have a
+// left padding. For example:
+//
+// #[foo] <----- "top" attribute
+// struct Foo {
+// #[bar] <---- not "top" attribute
+// bar: usize,
+// }
+fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item, top: bool) -> fmt::Result {
let mut attrs = String::new();
for attr in &it.attrs.other_attrs {
}
}
if attrs.len() > 0 {
- write!(w, "<div class=\"docblock attributes\">{}</div>", &attrs)?;
+ write!(w, "<div class=\"docblock attributes{}\">{}</div>",
+ if top { " top-attr" } else { "" }, &attrs)?;
}
Ok(())
}
out.push_str("<span class=\"where fmt-newline\"> ");
assoc_type(&mut out, it, &[],
Some(&tydef.type_),
- AssocItemLink::GotoSource(t_did, &FxHashSet::default()))?;
+ AssocItemLink::GotoSource(t_did, &FxHashSet::default()),
+ "")?;
out.push_str(";</span>");
}
}
if let clean::TypedefItem(ref tydef, _) = it.inner {
write!(w, "<span class=\"where fmt-newline\"> ")?;
assoc_type(w, it, &vec![], Some(&tydef.type_),
- AssocItemLink::Anchor(None))?;
+ AssocItemLink::Anchor(None),
+ "")?;
write!(w, ";</span>")?;
}
}
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
write!(w, "<code id='{}'>", ns_id)?;
- assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id))?;
+ assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id), "")?;
write!(w, "</code></h4>")?;
}
clean::AssociatedConstItem(ref ty, ref default) => {
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
write!(w, "<code id='{}'>", ns_id)?;
- assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?;
+ assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "")?;
write!(w, "</code>")?;
render_stability_since_raw(w, item.stable_since(), outer_version)?;
if let Some(l) = (Item { cx, item }).src_href() {
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
write!(w, "<code id='{}'>", ns_id)?;
- assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id))?;
+ assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id), "")?;
write!(w, "</code></h4>")?;
}
clean::StrippedItem(..) => return Ok(()),
t: &clean::Existential,
) -> fmt::Result {
write!(w, "<pre class='rust existential'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "existential type {}{}{where_clause}: {bounds};</pre>",
it.name.as_ref().unwrap(),
t.generics,
fn item_trait_alias(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
t: &clean::TraitAlias) -> fmt::Result {
write!(w, "<pre class='rust trait-alias'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "trait {}{}{} = {};</pre>",
it.name.as_ref().unwrap(),
t.generics,
fn item_typedef(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
t: &clean::Typedef) -> fmt::Result {
write!(w, "<pre class='rust typedef'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "type {}{}{where_clause} = {type_};</pre>",
it.name.as_ref().unwrap(),
t.generics,
fn item_foreign_type(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item) -> fmt::Result {
writeln!(w, "<pre class='rust foreigntype'>extern {{")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(
w,
" {}type {};\n}}</pre>",
}
var attributesToggle = createToggleWrapper(createSimpleToggle(false));
onEachLazy(main.getElementsByClassName("attributes"), function(i_e) {
- i_e.parentNode.insertBefore(attributesToggle.cloneNode(true), i_e);
+ var attr_tog = attributesToggle.cloneNode(true);
+ if (hasClass(i_e, "top-attr") === true) {
+ addClass(attr_tog, "top-attr");
+ }
+ i_e.parentNode.insertBefore(attr_tog, i_e);
itemAttributesFunc(i_e);
});
}
/* This part is to fix the "Expand attributes" part in the type declaration. */
-.type-decl > pre > :first-child {
+.type-decl > pre > .toggle-wrapper.toggle-attributes.top-attr {
margin-left: 0 !important;
}
-.type-decl > pre > :nth-child(2) {
+.type-decl > pre > .docblock.attributes.top-attr {
margin-left: 1.8em !important;
}
.type-decl > pre > .toggle-attributes {
#[export_name = "bar"]
pub extern "C" fn g() {}
-// @has foo/enum.Foo.html '//*[@class="docblock attributes"]' '#[repr(i64)]'
-// @has foo/enum.Foo.html '//*[@class="docblock attributes"]' '#[must_use]'
+// @has foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' '#[repr(i64)]'
+// @has foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' '#[must_use]'
#[repr(i64)]
#[must_use]
pub enum Foo {
--- /dev/null
+use std::alloc::Layout;
+
+// ok
+const LAYOUT_VALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x08) };
+
+// not ok, since alignment needs to be non-zero.
+const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+//~^ ERROR it is undefined behavior to use this value
+
+fn main() {}
--- /dev/null
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/alloc.rs:7:1
+ |
+LL | const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .align_, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
LL | Err(5)?;
| ^ the trait `std::convert::From<{integer}>` is not implemented for `()`
|
+ = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required by `std::convert::From::from`
error: aborting due to previous error
LL | Err("")?;
| ^ the trait `std::convert::From<&str>` is not implemented for `i32`
|
+ = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following implementations were found:
<i32 as std::convert::From<bool>>
<i32 as std::convert::From<i16>>
LL | x?;
| ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()`
|
+ = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required by `std::convert::From::from`
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
-Subproject commit 11194e3d050f45ff002a775f451ff6222fcd5b2c
+Subproject commit 60a609acaed3bf2b3ec6ab995bccf0f03bc26060