profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/the8472/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.

the8472/mldht 107

Bittorrent Mainline DHT implementation in java

the8472/fastar 86

Fast tar archiver

the8472/ffcnt 18

Fast file counting on HDDs

the8472/platter-walk 12

Rust library for HDD-aware directory traversal

the8472/reapfrog 8

Rust library for multi-file readahead / dropbehind

the8472/stitch-animation 5

Extraction of panning shots from videos for stitching/composite images

the8472/defrag-dirs 3

Directory index defragmentation tool for linux

the8472/greasemonkey 2

Greasemonkey is a user script manager for Firefox.

the8472/ipfs-jail 1

wrap ipfs daemon in firejail, run as systemd service

the8472/latex-to-unicode.js 1

Convert LaTeX strings to unicode.

push eventthe8472/rust

The8472

commit sha 688452c244315e2a5be1022bf5a7b0e8feb3d7c7

fix doc examples

view details

push time in 3 hours

Pull request review commentrust-lang/rust

add module-level documentation for vec's in-place iteration

+///! Inplace iterate-and-collect specialization for `Vec`

🤦‍♂️ And there I was wondering why my IDE was confused again and wouldn't render the comment. Fixed.

the8472

comment created time in 3 hours

PullRequestReviewEvent

push eventthe8472/rust

The8472

commit sha b66c9aa1bc5cd7d35d4f413cdca6951a73282b34

remove redundant column of slashes

view details

push time in 3 hours

PR opened rust-lang/rust

Add convenience for handling ipv4-mapped addresses by canonicalizing them

This simplifies checking common properties in an address-family-agnostic way since since #86335 commits to not checking IPv4 semantics of IPv4-mapped addresses in the Ipv6Addr property methods.

+45 -0

0 comment

1 changed file

pr created time in 3 hours

create barnchthe8472/rust

branch : canonical_v6

created branch time in 3 hours

issue closedintellij-rust/intellij-rust

Adding a new line to a module comment prefixes the next line with `///` instead of `///!`

<!-- Hello and thank you for the issue! If you would like to report a bug, we have added some points below that you can fill out. Feel free to remove all the irrelevant text to request a new feature. -->

Environment

  • IntelliJ Rust plugin version: 0.4.151.3997-211
  • Rust toolchain version: 1.55.0-nightly (952fdf2a1 2021-07-05) x86_64-unknown-linux-gnu
  • IDE name and version: IntelliJ IDEA 2021.1.3 Community Edition (IC-211.7628.21)
  • Operating system: Linux 5.13.4-arch1-1
  • Macro expansion engine: new
  • Name resolution engine: new

Problem description

When editing a module comment and adding a new line it is only prefixed with /// instead of ///!.

Steps to reproduce

  1. go to the first line of a file
  2. start writing a module comment
  3. press enter
  4. observe incorrect comment format

<!-- Please include as much of your codebase as needed to reproduce the error. If the relevant files are large, please provide a link to a public repository or a Gist. -->

closed time in 14 hours

the8472

Pull request review commentrust-lang/rust

BTree: add drain and split_off_range methods

 impl<K, V> Clone for Values<'_, K, V> {     } } +/// An iterator produced by calling `drain` on BTreeMap.+#[unstable(feature = "btree_drain", issue = "81074")]+#[derive(Debug)]+pub struct Drain<K, V> {+    inner: IntoIter<K, V>,+}++#[unstable(feature = "btree_drain", issue = "81074")]+impl<K, V> Iterator for Drain<K, V> {+    type Item = (K, V);++    fn next(&mut self) -> Option<(K, V)> {+        self.inner.next()+    }++    fn size_hint(&self) -> (usize, Option<usize>) {+        self.inner.size_hint()+    }+}++#[stable(feature = "rust1", since = "1.0.0")]+impl<K, V> ExactSizeIterator for Drain<K, V> {

I imagine it's legal and might even be beneficial to declare a DrainFilter iterator as ExactSizeIterator

From a safety perspective it is. From an API contract perspective it is not.

When doing so, the implementation of Iterator::size_hint must return the exact size of the iterator.

ssomers

comment created time in a day

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/rust

STD support for the ESP-IDF framework

 const fn max_iov() -> usize {     16 // The minimum value required by POSIX. } +// ESP-IDF does not (yet) support duplication of file descriptors, so we are emulating it here

Yeah, you're right. I guess I was thinking of the mechanism that reopens a file via procfs, which isn't relevant here.

Ignore everything I have said here. 😔

ivmarkov

comment created time in a day

Pull request review commentrust-lang/rust

BTreeMap/BTreeSet: add drain and split_off_range methods

 impl<K, V> Clone for Values<'_, K, V> {     } } +/// An iterator produced by calling `drain` on BTreeMap.+#[unstable(feature = "btree_drain", issue = "81074")]+#[derive(Debug)]+pub struct Drain<K, V> {+    inner: IntoIter<K, V>,+}++#[unstable(feature = "btree_drain", issue = "81074")]+impl<K, V> Iterator for Drain<K, V> {+    type Item = (K, V);++    fn next(&mut self) -> Option<(K, V)> {+        self.inner.next()+    }++    fn size_hint(&self) -> (usize, Option<usize>) {+        self.inner.size_hint()+    }+}++#[stable(feature = "rust1", since = "1.0.0")]+impl<K, V> ExactSizeIterator for Drain<K, V> {

but you probably mean #37306.

Yes.

But in BTree, none is, so I probably don't.

So is there any reason not to trust it, can it be wrong?

ssomers

comment created time in a day

PullRequestReviewEvent

pull request commentrust-lang/rust

STD support for the ESP-IDF framework

Note that as part of only supporting fallible allocation in the linux kernel (https://github.com/rust-lang/rfcs/pull/3140) there is ongoing discussion around making std features optional and how to support that on the cargo side. https://github.com/rust-lang/rfcs/pull/3146

I'm not sure what exactly the roadmap on those parts are but it sounds like it would be appropriate here if you only want to support a subset of the standard library in the beginning. But putting whole module behind feature gates that have yet to be introduced instead of stubbing them could require some work.

ivmarkov

comment created time in 2 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

STD support for the ESP-IDF framework

+#![stable(feature = "metadata_ext", since = "1.1.0")]++use crate::fs::Metadata;+use crate::sys_common::AsInner;++#[allow(deprecated)]+use crate::os::espidf::raw;++/// OS-specific extensions to [`fs::Metadata`].+///+/// [`fs::Metadata`]: crate::fs::Metadata+#[stable(feature = "metadata_ext", since = "1.1.0")]+pub trait MetadataExt {+    #[stable(feature = "metadata_ext", since = "1.1.0")]+    #[rustc_deprecated(+        since = "1.8.0",+        reason = "deprecated in favor of the accessor \+                  methods of this trait"+    )]+    #[allow(deprecated)]+    fn as_raw_stat(&self) -> &raw::stat;++    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_dev(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ino(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mode(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_nlink(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_uid(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_gid(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_rdev(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_size(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_atime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_atime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mtime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mtime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ctime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ctime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_crtime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_crtime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_blksize(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_blocks(&self) -> u64;+}++#[stable(feature = "metadata_ext", since = "1.1.0")]+impl MetadataExt for Metadata {+    #[allow(deprecated)]+    fn as_raw_stat(&self) -> &raw::stat {+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }+    }+    fn st_dev(&self) -> u64 {+        self.as_inner().as_inner().st_dev as u64+    }+    fn st_ino(&self) -> u64 {+        self.as_inner().as_inner().st_ino as u64+    }+    fn st_mode(&self) -> u32 {+        self.as_inner().as_inner().st_mode as u32+    }+    fn st_nlink(&self) -> u64 {+        self.as_inner().as_inner().st_nlink as u64+    }+    fn st_uid(&self) -> u32 {+        self.as_inner().as_inner().st_uid as u32+    }+    fn st_gid(&self) -> u32 {+        self.as_inner().as_inner().st_gid as u32+    }+    fn st_rdev(&self) -> u64 {+        self.as_inner().as_inner().st_rdev as u64+    }+    fn st_size(&self) -> u64 {+        self.as_inner().as_inner().st_size as u64+    }+    fn st_atime(&self) -> i64 {+        self.as_inner().as_inner().st_atime as i64+    }+    fn st_atime_nsec(&self) -> i64 {+        //self.as_inner().as_inner().st_atime_nsec as i64+        0+    }

Oh wait, that's for the raw types, not the metadata extensions? I guess those are important and should be stable with the the first release.

ivmarkov

comment created time in 2 days

Pull request review commentrust-lang/rust

STD support for the ESP-IDF framework

+#![stable(feature = "metadata_ext", since = "1.1.0")]++use crate::fs::Metadata;+use crate::sys_common::AsInner;++#[allow(deprecated)]+use crate::os::espidf::raw;++/// OS-specific extensions to [`fs::Metadata`].+///+/// [`fs::Metadata`]: crate::fs::Metadata+#[stable(feature = "metadata_ext", since = "1.1.0")]+pub trait MetadataExt {+    #[stable(feature = "metadata_ext", since = "1.1.0")]+    #[rustc_deprecated(+        since = "1.8.0",+        reason = "deprecated in favor of the accessor \+                  methods of this trait"+    )]+    #[allow(deprecated)]+    fn as_raw_stat(&self) -> &raw::stat;++    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_dev(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ino(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mode(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_nlink(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_uid(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_gid(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_rdev(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_size(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_atime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_atime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mtime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mtime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ctime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ctime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_crtime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_crtime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_blksize(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_blocks(&self) -> u64;+}++#[stable(feature = "metadata_ext", since = "1.1.0")]+impl MetadataExt for Metadata {+    #[allow(deprecated)]+    fn as_raw_stat(&self) -> &raw::stat {+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }+    }+    fn st_dev(&self) -> u64 {+        self.as_inner().as_inner().st_dev as u64+    }+    fn st_ino(&self) -> u64 {+        self.as_inner().as_inner().st_ino as u64+    }+    fn st_mode(&self) -> u32 {+        self.as_inner().as_inner().st_mode as u32+    }+    fn st_nlink(&self) -> u64 {+        self.as_inner().as_inner().st_nlink as u64+    }+    fn st_uid(&self) -> u32 {+        self.as_inner().as_inner().st_uid as u32+    }+    fn st_gid(&self) -> u32 {+        self.as_inner().as_inner().st_gid as u32+    }+    fn st_rdev(&self) -> u64 {+        self.as_inner().as_inner().st_rdev as u64+    }+    fn st_size(&self) -> u64 {+        self.as_inner().as_inner().st_size as u64+    }+    fn st_atime(&self) -> i64 {+        self.as_inner().as_inner().st_atime as i64+    }+    fn st_atime_nsec(&self) -> i64 {+        //self.as_inner().as_inner().st_atime_nsec as i64+        0+    }

Current nightly is 1.56, so if it were to land now and you wanted the new platform features to be instantly stable with the the first release you can put that version there. If those traits are not critical for the platform to be usable and you have some reason to iterate on them you could mark them unstable instead.

ivmarkov

comment created time in 2 days

PullRequestReviewEvent

pull request commentrust-lang/rust

Recommend `swap_remove` in `Vec::remove` docs

LGTM

@bors r+ rollup

Flying-Toast

comment created time in 2 days

Pull request review commentrust-lang/rust

STD support for the ESP-IDF framework

+#![stable(feature = "metadata_ext", since = "1.1.0")]++use crate::fs::Metadata;+use crate::sys_common::AsInner;++#[allow(deprecated)]+use crate::os::espidf::raw;++/// OS-specific extensions to [`fs::Metadata`].+///+/// [`fs::Metadata`]: crate::fs::Metadata+#[stable(feature = "metadata_ext", since = "1.1.0")]+pub trait MetadataExt {+    #[stable(feature = "metadata_ext", since = "1.1.0")]+    #[rustc_deprecated(+        since = "1.8.0",+        reason = "deprecated in favor of the accessor \+                  methods of this trait"+    )]+    #[allow(deprecated)]+    fn as_raw_stat(&self) -> &raw::stat;++    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_dev(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ino(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mode(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_nlink(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_uid(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_gid(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_rdev(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_size(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_atime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_atime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mtime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mtime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ctime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ctime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_crtime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_crtime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_blksize(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_blocks(&self) -> u64;+}++#[stable(feature = "metadata_ext", since = "1.1.0")]+impl MetadataExt for Metadata {+    #[allow(deprecated)]+    fn as_raw_stat(&self) -> &raw::stat {+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }+    }+    fn st_dev(&self) -> u64 {+        self.as_inner().as_inner().st_dev as u64+    }+    fn st_ino(&self) -> u64 {+        self.as_inner().as_inner().st_ino as u64+    }+    fn st_mode(&self) -> u32 {+        self.as_inner().as_inner().st_mode as u32+    }+    fn st_nlink(&self) -> u64 {+        self.as_inner().as_inner().st_nlink as u64+    }+    fn st_uid(&self) -> u32 {+        self.as_inner().as_inner().st_uid as u32+    }+    fn st_gid(&self) -> u32 {+        self.as_inner().as_inner().st_gid as u32+    }+    fn st_rdev(&self) -> u64 {+        self.as_inner().as_inner().st_rdev as u64+    }+    fn st_size(&self) -> u64 {+        self.as_inner().as_inner().st_size as u64+    }+    fn st_atime(&self) -> i64 {+        self.as_inner().as_inner().st_atime as i64+    }+    fn st_atime_nsec(&self) -> i64 {+        //self.as_inner().as_inner().st_atime_nsec as i64+        0+    }

either is fine. in the latter case you can rewrite the history before merge.

ivmarkov

comment created time in 2 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

STD support for the ESP-IDF framework

+#![stable(feature = "metadata_ext", since = "1.1.0")]++use crate::fs::Metadata;+use crate::sys_common::AsInner;++#[allow(deprecated)]+use crate::os::espidf::raw;++/// OS-specific extensions to [`fs::Metadata`].+///+/// [`fs::Metadata`]: crate::fs::Metadata+#[stable(feature = "metadata_ext", since = "1.1.0")]+pub trait MetadataExt {+    #[stable(feature = "metadata_ext", since = "1.1.0")]+    #[rustc_deprecated(+        since = "1.8.0",+        reason = "deprecated in favor of the accessor \+                  methods of this trait"+    )]+    #[allow(deprecated)]+    fn as_raw_stat(&self) -> &raw::stat;++    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_dev(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ino(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mode(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_nlink(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_uid(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_gid(&self) -> u32;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_rdev(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_size(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_atime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_atime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mtime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_mtime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ctime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_ctime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_crtime(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_crtime_nsec(&self) -> i64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_blksize(&self) -> u64;+    #[stable(feature = "metadata_ext2", since = "1.8.0")]+    fn st_blocks(&self) -> u64;+}++#[stable(feature = "metadata_ext", since = "1.1.0")]+impl MetadataExt for Metadata {+    #[allow(deprecated)]+    fn as_raw_stat(&self) -> &raw::stat {+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }+    }+    fn st_dev(&self) -> u64 {+        self.as_inner().as_inner().st_dev as u64+    }+    fn st_ino(&self) -> u64 {+        self.as_inner().as_inner().st_ino as u64+    }+    fn st_mode(&self) -> u32 {+        self.as_inner().as_inner().st_mode as u32+    }+    fn st_nlink(&self) -> u64 {+        self.as_inner().as_inner().st_nlink as u64+    }+    fn st_uid(&self) -> u32 {+        self.as_inner().as_inner().st_uid as u32+    }+    fn st_gid(&self) -> u32 {+        self.as_inner().as_inner().st_gid as u32+    }+    fn st_rdev(&self) -> u64 {+        self.as_inner().as_inner().st_rdev as u64+    }+    fn st_size(&self) -> u64 {+        self.as_inner().as_inner().st_size as u64+    }+    fn st_atime(&self) -> i64 {+        self.as_inner().as_inner().st_atime as i64+    }+    fn st_atime_nsec(&self) -> i64 {+        //self.as_inner().as_inner().st_atime_nsec as i64+        0+    }

Since this trait is platform-specific it doesn't need to have methods it can't implement properly.

ivmarkov

comment created time in 2 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

STD support for the ESP-IDF framework

 const fn max_iov() -> usize {     16 // The minimum value required by POSIX. } +// ESP-IDF does not (yet) support duplication of file descriptors, so we are emulating it here

That kind of emulation seems dicy since duped file descriptors normally don't share a seek position, nonblocking status and various other properties. Here they would.

How much would break if duplicate always returned an error?

ivmarkov

comment created time in 2 days

PullRequestReviewEvent

push eventthe8472/rust

The8472

commit sha 32fa9edd06ddd57e51bf4fdd1d89f275d5ab7cb7

add link to open issue about the O(1) optimization being fickle

view details

push time in 2 days

issue commentrust-lang/rust

Loop without side-effect is not eliminated. Leads to O(n) instead of O(1) runtime

Something that was brought up on Zulip is that this case also fails for Copy, i.e. with the TrustedRandomAccess specialization is when the wrapper type is repr(C)

https://rust.godbolt.org/z/54n7o9KKn

the8472

comment created time in 2 days

Pull request review commentrust-lang/rust

add module-level documentation for vec's in-place iteration

+///! Inplace iterate-and-collect specialization for `Vec`+///!+///! This applies to iterators in the shape of+///! `source.adapter().adapter().adapter().collect::<Vec<U>>()`+///! where `source` is a `Vec`, `Box<[]>` or `BinaryHeap`, the adapters each+///! consume one or more items per step (represented by `InPlaceIterable`), provide+///! transitive access to `source` (via `SourceIter`) and thus the underlying allocation.+///! And finally the layouts of `source::Item` and `U` must have the same size and alignment,+///! this is currently ensured via const eval instead of trait bounds.+///! By extension some other collections which use `collect::Vec<_>()` internally in their+///! `FromIterator` implementation benefit from this too.+///!+///! Access to the underlying source goes through a further layer of indirection via the private+///! trait `AsIntoIter` to hide the implementation detail that other collections may use+///! `vec::IntoIter` internally.+///!+///! In-place iteration performs the following steps+///!+///! 1. obtain the capacity and a write *pointer* to the start of the underlying allocation+///!    via `SourceIter`. This allows writing into the allocation while it is still owned by `source`.+///!    For this to be sound the source has to use pointers too to perform its reads, otherwise there+///!    would be aliasing conflicts.+///! 2. loop through the iterator, for each step the source is required to have advanced+///!    its read pointer at least once so that the result can be written into the allocation+///!    without overwriting yet-to-be-iterated items. Also counts the number of items written.+///! 3. on panic the written items must be dropped before the iterator is dropped which will+///!    then drop any unread items. This requires the write count to be accurate when the panic occurs.+///! 4. on success the source is accessed again, any unread items are dropped and then the allocation+///!    is stolen so it doesn't get dropped with the iterator.+///!    Since this changes the state of the source while still being owned by the iterator adapters+///!    they must be able to handle this situation in their drop impl.+///!    This is a safety requirement of `SourceIter`.+///! 5. assemble a new vec from From the capacity, count of written items and the allocation pointer+///!+///!+///! Additionally step 2 is further specialized when the iterator implements+///! `TrustedRandomAccessNoCoerce` to let the optimizer see that it is a counted loop with a single+///! induction variable. This can turn some iterators into a noop, i.e. it reduces them from O(n) to+///! O(1). Since unchecked accesses through that trait do not advance the read pointer of `IntoIter`+///! this would interact unsoundly with steps 3 and 4. But since the normal `Drop` implementation of+///! `IntoIter` would suffer from the same problem it is only correct for `TrustedRandomAccessNoCoerce`+///! to be implemented when the items don't have a destructor. Thus that implicit requirement+///! also makes the specialization safe to use for in-place collection.+///!+///! The combined requirements of all these unsafe traits and the need to implement them on each+///! part of the iterator pipeline - since there is no central struct evaluating an iterator+///! holistically - leads to the need for non-local reasoning, i.e. the safety has to be evaluated+///! taking the behavior of `IntoIter`, the adapters and this specialization into account.+///! Interactions with other features such as clonable iterators, panics inside user-provided closures+///! and partially consumed (including reverse iteration) ones also have to be considered.+///! For example a previous implementation of `InPlaceIterable` on `Peek` turned out to be unsound+///! due to `IntoIter`'s `Clone` implementation shortening the underlying allocation while retaining+///! the extra peeked item which then causes the iterator to yield more items than the allocation can+///! hold.+///!+///!+///! Some examples that are optimized by this specialization, more can be found in the `Vec`+///! benchmarks:+///!+///! ```rust+///! /// Converts a usize vec into an isize one.+///! fn cast(vec: Vec<usize>) -> Vec<isize> {+///!   // Does not allocate, free or panic. On optlevel>=2 it does not loop.

Oh, yeah, there already is #79308 for that. I can link to it.

the8472

comment created time in 2 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

add module-level documentation for vec's in-place iteration

+///! Inplace iterate-and-collect specialization for `Vec`+///!+///! This applies to iterators in the shape of+///! `source.adapter().adapter().adapter().collect::<Vec<U>>()`+///! where `source` is a `Vec`, `Box<[]>` or `BinaryHeap`, the adapters each

I went with calling source the respective IntoIters since that'll be what holds the allocation which the rest of the text talks about. The original collection will have ceased to exist at that point.

the8472

comment created time in 2 days