]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #60945 - blkerby:fill_buf_nll_doc_example, r=shepmaster
authorMazdak Farrokhzad <twingoow@gmail.com>
Sun, 19 May 2019 00:31:44 +0000 (02:31 +0200)
committerGitHub <noreply@github.com>
Sun, 19 May 2019 00:31:44 +0000 (02:31 +0200)
Simplify BufRead::fill_buf doc example using NLL

With non-lexical lifetimes, in this example it is no longer necessary to use a block to end the borrow early.

34 files changed:
src/liballoc/collections/vec_deque.rs
src/liballoc/tests/btree/set.rs
src/liballoc/tests/lib.rs
src/libcore/alloc.rs
src/libcore/iter/traits/iterator.rs
src/libcore/ptr.rs
src/libcore/tests/alloc.rs [new file with mode: 0644]
src/libcore/tests/lib.rs
src/librustc/hir/def_id.rs
src/librustc/hir/map/collector.rs
src/librustc/hir/map/definitions.rs
src/librustc/hir/map/mod.rs
src/librustc/infer/lexical_region_resolve/graphviz.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/specialize/mod.rs
src/librustc_driver/pretty.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/index.rs
src/librustc_mir/util/graphviz.rs
src/librustc_resolve/macros.rs
src/librustc_save_analysis/lib.rs
src/librustdoc/config.rs
src/librustdoc/core.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/html/static/rustdoc.css
src/test/rustdoc/attributes.rs
src/test/ui/consts/std/alloc.rs [new file with mode: 0644]
src/test/ui/consts/std/alloc.stderr [new file with mode: 0644]
src/test/ui/issues/issue-32709.stderr
src/test/ui/try-block/try-block-bad-type.stderr
src/test/ui/try-on-option.stderr
src/tools/clippy

index 9a8d48083e67c676e2fffbfc7f32f9ef53e461ef..31e49d06a7b5a963d3701ed6123ea50f8c792bf8 100644 (file)
@@ -1948,8 +1948,6 @@ pub fn resize_with(&mut self, new_len: usize, generator: impl FnMut()->T) {
     /// # Examples
     ///
     /// ```
-    /// #![feature(vecdeque_rotate)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = (0..10).collect();
@@ -1963,7 +1961,7 @@ pub fn resize_with(&mut self, new_len: usize, generator: impl FnMut()->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 @@ pub fn rotate_left(&mut self, mid: usize) {
     /// # Examples
     ///
     /// ```
-    /// #![feature(vecdeque_rotate)]
-    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = (0..10).collect();
@@ -2008,7 +2004,7 @@ pub fn rotate_left(&mut self, mid: usize) {
     /// }
     /// 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;
index d52814118b3c7de7c74c47f1d8700a6299be55f6..989beb3b1bfd90afbfd55626953080d31016bb39 100644 (file)
@@ -143,8 +143,8 @@ fn check_union(a: &[i32], b: &[i32], expected: &[i32]) {
 #[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));
 }
 
index b736750c57601e5b1798d871837b90910f1bad40..ddb3120e89d781635645c424a9eba34d803e85d2 100644 (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};
index c124457118cb97768a98b181f70be07ad85e7dd9..302a9d89e5854009b50908a38e914c965c297412 100644 (file)
@@ -99,7 +99,7 @@ pub fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
     /// [`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) }
     }
 
index 403f3358105325c917fae4fa0277f4dc7be5700e..38c7c9bc4d086c53e9e27eed48168dff5670b4ef 100644 (file)
@@ -356,7 +356,7 @@ fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
     ///
     /// ```
     /// 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 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> where
     /// ```
     /// 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 @@ fn for_each<F>(self, mut f: F) where
     /// ```
     /// 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 @@ fn for_each<F>(self, mut f: F) where
     /// ```
     /// 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 @@ fn for_each<F>(self, mut f: F) where
     /// ```
     /// 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 @@ fn for_each<F>(self, mut f: F) where
     /// ```
     /// 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 @@ fn peekable(self) -> Peekable<Self> where Self: Sized {
     /// ```
     /// 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 @@ fn peekable(self) -> Peekable<Self> where Self: Sized {
     /// ```
     /// 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 @@ fn peekable(self) -> Peekable<Self> where Self: Sized {
     /// ```
     /// 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 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
     /// ```
     /// 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 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
     /// ```
     /// 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 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
     /// ```
     /// 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 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
     ///
     /// ```
     /// 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 @@ fn inspect<F>(self, f: F) -> Inspect<Self, F> where
     /// ```
     /// 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 @@ fn inspect<F>(self, f: F) -> Inspect<Self, F> where
     /// // 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 @@ fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized {
     /// 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]);
index b6de9f57b0110439227d2ba8ae5797761595b922..ada784e9ce70504171dadec906a592d59e66e991 100644 (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
diff --git a/src/libcore/tests/alloc.rs b/src/libcore/tests/alloc.rs
new file mode 100644 (file)
index 0000000..63537ba
--- /dev/null
@@ -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);
+}
index b8075ef2942e083d67d7af6f5778b68fcb7b648a..c617596aba80159af2ecb5f3c4967bc099897f8f 100644 (file)
 #![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;
index b268a1a494d107cc92b1996b51374f89e61fd2e9..0c4f5fb3fc167bd701087e504c7fa5feab06c876 100644 (file)
@@ -96,34 +96,20 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 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
@@ -132,7 +118,7 @@ pub fn from_proc_macro_index(proc_macro_index: usize) -> 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 @@ pub fn from_proc_macro_index(proc_macro_index: usize) -> 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 {
index a1cf338bf12ea991e6199dc2363cafc34ffe6723..eeba628b3bf2168ad943ac41fe4cca076ed5bf72 100644 (file)
@@ -226,7 +226,7 @@ pub(super) fn finalize_and_compute_crate_hash(mut self,
 
     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));
index 9cb85c4db47579f8403de8d8369a5de6138226cd..1cc9a2c0e8a1b9d875b7f9a31520c5644f727e76 100644 (file)
@@ -38,7 +38,7 @@ fn allocate(&mut self,
                 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 @@ fn allocate(&mut self,
     }
 
     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 @@ pub fn add_def_path_hashes_to(&self,
                 .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 @@ pub fn local_def_id(&self, node: ast::NodeId) -> DefId {
     #[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 @@ pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
 
     #[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 @@ pub fn create_def_with_parent(&mut self,
 
         // 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 @@ pub fn def_index(&self, def_path_table: &DefPathTable) -> DefIndex {
                                           .position(|k| *k == def_key)
                                           .unwrap();
 
-                DefIndex::from_array_index(index)
+                DefIndex::from(index)
             }
 
             fn name(&self) -> Symbol {
index b8ee98551a20e758f4b025f7fc54167a87bd2309..4b94f772554e76910aa228856853fe0ad3e65cb0 100644 (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 @@ fn all_ids<'a>(&'a self) -> impl Iterator<Item = HirId> + 'a {
             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,
                 }
             }))
index 073a3f74422c6ff2bdf82ca62f0e3fe2f7b4ecc6..1878afd581dd48746bc6fd4a2512f39ba2848d00 100644 (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);
                 }
index df2688397102299ab0c1602a27fd53a27e714cea..9019c4a0575d40b9c5c12df1aa7fb6335cd946cf 100644 (file)
@@ -643,13 +643,16 @@ pub fn report_selection_error(
                             .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!(
index fc20735eb0f6726b90ee705e0f5dfe32719b1400..fdd1a821e31b56964bae3db7af15581bc05fd1a7 100644 (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 {
index c74ed5ec30c3cade8d6b7b91cbf1dedc92a4af44..812321ff5e6c36f8fd16f772752f03b6d25eb5c2 100644 (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 {
index e950c2815e9b4547f60a0ecf25b4a9b0964bad76..d882fe6f27ecc7a8f115306a43066b0a428cbb73 100644 (file)
@@ -264,7 +264,7 @@ fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
 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()?))
     }
 }
 
index 0ac03526832b7506c969c00e20318f4008c64157..939aadcc9ec9bfeefd0b44d1fca11df5060d0298 100644 (file)
@@ -134,7 +134,7 @@ fn specialized_encode(&mut self, def_id: &DefId) -> Result<(), Self::Error> {
 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())
     }
 }
 
index 4c1e39cd0a9e1a945c1ed3c18ebc8e8cdd1f0f45..934e871559c79939010ffb30377007afc5b96ba6 100644 (file)
@@ -93,7 +93,7 @@ pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry<'_>>) {
     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 @@ pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tc
                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
index 188da9a82dc995a07c85e1119c51b3a3894a3807..fc4c6b3fd3f244afc5a41d37239e39c31ba8f987 100644 (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(),
     )
 }
 
index 9f3e1c308f6379e9c591b7530381098459057b0a..e34a33ef8fad9b2a7476e2d8a096e11b5e610ceb 100644 (file)
@@ -172,7 +172,7 @@ fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFra
     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);
index e03da2ed608be02f02d3137dd1d9af17412ac6bb..d34f5633946bfa281773da81d21cab2b44013bcc 100644 (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(),
     }
 }
 
index 72421c9decc6febf4c10e40cfd56a42aec037783..4fae7e080b14aef046cf68e4c73af475a0bc436a 100644 (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));
index 428f4f328b907987356c418a09511b582e205c3b..2a3bc5e99617f468375a834110a7e7cf45e431ed 100644 (file)
@@ -143,7 +143,7 @@ pub fn next_def_id(&self, crate_num: CrateNum) -> DefId {
             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),
             },
         );
 
index 0207fcda9e880ea6525550ae6b8f3d8a176ca0b3..36ce89558db7b81edc6eb0fd10c099ef5096ba81 100644 (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`
@@ -2992,7 +2992,7 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
 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),
@@ -3004,7 +3004,7 @@ fn item_constant(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
 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),
@@ -3027,7 +3027,7 @@ fn item_function(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
         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>",
@@ -3116,7 +3116,7 @@ fn item_trait(
     // 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),
@@ -3379,8 +3379,10 @@ fn assoc_const(w: &mut fmt::Formatter<'_>,
                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(),
@@ -3391,8 +3393,10 @@ fn assoc_const(w: &mut fmt::Formatter<'_>,
 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() {
@@ -3469,7 +3473,7 @@ fn method(w: &mut fmt::Formatter<'_>,
         } 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 { "" },
@@ -3503,10 +3507,12 @@ fn method(w: &mut fmt::Formatter<'_>,
             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")
     }
@@ -3516,7 +3522,7 @@ fn item_struct(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::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),
@@ -3567,7 +3573,7 @@ fn item_union(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                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),
@@ -3612,7 +3618,7 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
              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(),
@@ -3773,7 +3779,15 @@ fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
     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 {
@@ -3785,7 +3799,8 @@ fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result {
         }
     }
     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(())
 }
@@ -4118,7 +4133,8 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
                             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>");
                         }
                     }
@@ -4158,7 +4174,8 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
                     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>")?;
                     }
                 }
@@ -4228,7 +4245,7 @@ fn doc_impl_item(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item,
                 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) => {
@@ -4236,7 +4253,7 @@ fn doc_impl_item(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item,
                 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() {
@@ -4250,7 +4267,7 @@ fn doc_impl_item(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item,
                 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(()),
@@ -4338,7 +4355,7 @@ fn item_existential(
     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,
@@ -4357,7 +4374,7 @@ fn item_existential(
 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,
@@ -4376,7 +4393,7 @@ fn item_trait_alias(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
 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,
@@ -4394,7 +4411,7 @@ fn item_typedef(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
 
 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>",
index 85ab0855f05e9511de9bbead3d194429f9b37c00..72a01a49bc66dc2d8ddaf1cda6195062f2bea2eb 100644 (file)
@@ -2325,7 +2325,11 @@ if (!DOMTokenList.prototype.remove) {
     }
     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);
     });
 
index 880b824335517a63f76f98104c66836d1b62a110..522b6d60a18d82facc2d3a32d394fde68eb2dd01 100644 (file)
@@ -1587,10 +1587,10 @@ div.name.expand::before {
 }
 
 /* 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 {
index eb0e3f065c7b3b50a4066fb4ed0b3cf7689e0039..6ecdad3ec0000aa04592ec1b0354e132198d5113 100644 (file)
@@ -8,8 +8,8 @@ pub extern "C" fn f() {}
 #[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 {
diff --git a/src/test/ui/consts/std/alloc.rs b/src/test/ui/consts/std/alloc.rs
new file mode 100644 (file)
index 0000000..65ac7e4
--- /dev/null
@@ -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() {}
diff --git a/src/test/ui/consts/std/alloc.stderr b/src/test/ui/consts/std/alloc.stderr
new file mode 100644 (file)
index 0000000..74a8f3d
--- /dev/null
@@ -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`.
index 84cca5b20af472d800fcc13e5c2ce366ec000683..04b8c3aa35396374ba058fc471b989d485ae34eb 100644 (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
index 7c7366df1dc3ed6b59eac7c13fbf3b20c8ee6f18..e1c2c6b675e9bb1d1dd2d7a2ae56d7f1b73f9801 100644 (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>>
index 4465fbe14b75cd39f2f9b3265dd245f4738b9f8a..db5046f8c151af029bc24d9f3b3a59b5b8c39c55 100644 (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`)
index 11194e3d050f45ff002a775f451ff6222fcd5b2c..60a609acaed3bf2b3ec6ab995bccf0f03bc26060 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 11194e3d050f45ff002a775f451ff6222fcd5b2c
+Subproject commit 60a609acaed3bf2b3ec6ab995bccf0f03bc26060