Auto merge of #60949 - Centril:rollup-f918e1v, r=Centril

Rollup of 8 pull requests

Successful merges:

 - #60370 (Mark core::alloc::Layout::from_size_align_unchecked const)
 - #60678 (Stabilize vecdeque_rotate)
 - #60924 (Explain that ? converts the error type using From)
 - #60931 (Use iter() for iterating arrays by slice)
 - #60934 (Declare DefIndex with the newtype_index macro)
 - #60943 (fix copy-paste typo in docs for ptr::read_volatile)
 - #60945 (Simplify BufRead::fill_buf doc example using NLL)
 - #60947 (Fix typos in docs of GlobalAlloc)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-05-19 01:56:14 +00:00
commit 26ab32499c
31 changed files with 108 additions and 101 deletions

View File

@ -1948,8 +1948,6 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// #![feature(vecdeque_rotate)]
///
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<_> = (0..10).collect();
@ -1963,7 +1961,7 @@ impl<T> VecDeque<T> {
/// }
/// 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;
@ -1993,8 +1991,6 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// #![feature(vecdeque_rotate)]
///
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<_> = (0..10).collect();
@ -2008,7 +2004,7 @@ impl<T> VecDeque<T> {
/// }
/// 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;

View File

@ -143,8 +143,8 @@ fn test_union() {
#[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));
}

View File

@ -6,7 +6,6 @@
#![feature(repeat_generic_slice)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(vecdeque_rotate)]
#![deny(rust_2018_idioms)]
use std::hash::{Hash, Hasher};

View File

@ -99,7 +99,7 @@ impl Layout {
/// [`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) }
}
@ -480,7 +480,7 @@ pub unsafe trait GlobalAlloc {
/// this allocator,
///
/// * `layout` must be the same layout that was used
/// to allocated that block of memory,
/// to allocate that block of memory,
#[stable(feature = "global_alloc", since = "1.28.0")]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
@ -535,7 +535,7 @@ pub unsafe trait GlobalAlloc {
/// * `ptr` must be currently allocated via this allocator,
///
/// * `layout` must be the same layout that was used
/// to allocated that block of memory,
/// to allocate that block of memory,
///
/// * `new_size` must be greater than zero.
///

View File

@ -356,7 +356,7 @@ pub trait Iterator {
///
/// ```
/// 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));
@ -531,7 +531,7 @@ pub trait Iterator {
/// ```
/// 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));
@ -620,7 +620,7 @@ pub trait Iterator {
/// ```
/// 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));
@ -634,7 +634,7 @@ pub trait Iterator {
/// ```
/// 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);
@ -646,7 +646,7 @@ pub trait Iterator {
/// ```
/// 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);
@ -657,7 +657,7 @@ pub trait Iterator {
/// ```
/// 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);
@ -837,7 +837,7 @@ pub trait Iterator {
/// ```
/// 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));
@ -851,7 +851,7 @@ pub trait Iterator {
/// ```
/// 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));
@ -863,7 +863,7 @@ pub trait Iterator {
/// ```
/// 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));
@ -898,7 +898,7 @@ pub trait Iterator {
/// ```
/// 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);
@ -911,7 +911,7 @@ pub trait Iterator {
/// ```
/// 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);
@ -922,7 +922,7 @@ pub trait Iterator {
/// ```
/// 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));
///
@ -937,7 +937,7 @@ pub trait Iterator {
///
/// ```
/// 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)
@ -1321,7 +1321,7 @@ pub trait Iterator {
/// ```
/// 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 );
///
@ -1334,7 +1334,7 @@ pub trait Iterator {
/// // 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 );
@ -1479,7 +1479,7 @@ pub trait Iterator {
/// 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]);

View File

@ -837,7 +837,7 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
///
/// * `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

View File

@ -0,0 +1,10 @@
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);
}

View File

@ -31,10 +31,12 @@
#![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;

View File

@ -96,34 +96,20 @@ impl fmt::Display for CrateNum {
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);
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({})",
/// 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);
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
@ -132,7 +118,7 @@ impl DefIndex {
// 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);
@ -141,19 +127,11 @@ impl DefIndex {
// 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 {}
@ -169,7 +147,7 @@ pub struct DefId {
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 {

View File

@ -226,7 +226,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
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));

View File

@ -38,7 +38,7 @@ impl DefPathTable {
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
@ -49,17 +49,17 @@ impl DefPathTable {
}
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
}
@ -74,7 +74,7 @@ impl DefPathTable {
.map(|(index, &hash)| {
let def_id = DefId {
krate: cnum,
index: DefIndex::from_array_index(index),
index: DefIndex::from(index),
};
(hash, def_id)
})
@ -387,7 +387,7 @@ impl Definitions {
#[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);
}
@ -417,7 +417,7 @@ impl Definitions {
#[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]
}
@ -508,7 +508,7 @@ impl Definitions {
// 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
@ -653,7 +653,7 @@ macro_rules! define_global_metadata_kind {
.position(|k| *k == def_key)
.unwrap();
DefIndex::from_array_index(index)
DefIndex::from(index)
}
fn name(&self) -> Symbol {

View File

@ -189,7 +189,7 @@ pub struct Map<'hir> {
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()
}
@ -1023,7 +1023,7 @@ impl<'hir> Map<'hir> {
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,
}
}))

View File

@ -56,7 +56,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
}
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;
@ -90,7 +90,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
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);
}

View File

@ -643,13 +643,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.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!(

View File

@ -298,7 +298,7 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
// 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 {

View File

@ -648,7 +648,7 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
// 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 {

View File

@ -264,7 +264,7 @@ impl<'a, 'tcx> SpecializedDecoder<DefId> for DecodeContext<'a, 'tcx> {
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()?))
}
}

View File

@ -134,7 +134,7 @@ impl<'a, 'tcx> SpecializedEncoder<DefId> for EncodeContext<'a, 'tcx> {
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())
}
}

View File

@ -93,7 +93,7 @@ impl Index {
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,
@ -126,7 +126,7 @@ impl<'tcx> LazySeq<Index> {
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

View File

@ -27,7 +27,7 @@ pub fn graphviz_safe_def_name(def_id: DefId) -> String {
format!(
"{}_{}",
def_id.krate.index(),
def_id.index.as_array_index(),
def_id.index.index(),
)
}

View File

@ -172,7 +172,7 @@ impl<'a> base::Resolver for Resolver<'a> {
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);

View File

@ -1170,7 +1170,7 @@ fn generated_code(span: Span) -> bool {
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(),
}
}

View File

@ -538,7 +538,7 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &errors::Handler)
"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));

View File

@ -143,7 +143,7 @@ impl<'tcx> DocContext<'tcx> {
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),
},
);

View File

@ -506,7 +506,7 @@ pub fn initial_ids() -> Vec<String> {
"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`

View File

@ -1579,18 +1579,13 @@ pub trait BufRead: Read {
/// let stdin = io::stdin();
/// let mut stdin = stdin.lock();
///
/// // we can't have two `&mut` references to `stdin`, so use a block
/// // to end the borrow early.
/// let length = {
/// let buffer = stdin.fill_buf().unwrap();
/// let buffer = stdin.fill_buf().unwrap();
///
/// // work with buffer
/// println!("{:?}", buffer);
///
/// buffer.len()
/// };
/// // work with buffer
/// println!("{:?}", buffer);
///
/// // ensure the bytes we worked with aren't returned again later
/// let length = buffer.len();
/// stdin.consume(length);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]

View File

@ -0,0 +1,10 @@
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() {}

View File

@ -0,0 +1,11 @@
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`.

View File

@ -4,6 +4,7 @@ error[E0277]: `?` couldn't convert the error to `()`
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

View File

@ -4,6 +4,7 @@ error[E0277]: `?` couldn't convert the error to `i32`
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>>

View File

@ -4,6 +4,7 @@ error[E0277]: `?` couldn't convert the error to `()`
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`)