kandi background
kandi background
Explore Kits
kandi background
Explore Kits
Rust is a multi-paradigm, general-purpose language designed for performance, safety, and safe concurrency. Rust is syntactically similar to C++, but can guarantee memory safety. In Rust there are 2 modes of writing code, Safe Rust and Unsafe Rust.

Popular New Releases in Rust

v1.20.6

Rust 1.60.0

Alacritty Version 0.10.1

tauri-driver v0.1.2

v0.20.0

deno

v1.20.6

rust

Rust 1.60.0

alacritty

Alacritty Version 0.10.1

tauri

tauri-driver v0.1.2

bat

v0.20.0

Popular Libraries in Rust

996.ICU

by 996icu rust

star image 258630 NOASSERTION

Repo for counting stars and contributing. Press F to pay respect to glorious developers.

deno

by denoland rust

star image 81698 MIT

A modern runtime for JavaScript and TypeScript.

rust

by rust-lang rust

star image 65482 NOASSERTION

Empowering everyone to build reliable and efficient software.

alacritty

by alacritty rust

star image 37538 Apache-2.0

A cross-platform, OpenGL terminal emulator.

tauri

by tauri-apps rust

star image 36698 Apache-2.0

Build smaller, faster, and more secure desktop applications with a web frontend.

bat

by sharkdp rust

star image 33294 NOASSERTION

A cat(1) clone with wings.

ripgrep

by BurntSushi rust

star image 27048 NOASSERTION

ripgrep recursively searches directories for a regex pattern while respecting your gitignore

meilisearch

by meilisearch rust

star image 25990 MIT

Powerful, fast, and an easy to use search engine

starship

by starship rust

star image 24749 ISC

☄🌌️ The minimal, blazing-fast, and infinitely customizable prompt for any shell!

996.ICU

by 996icu rust

star image 258630 NOASSERTION

Repo for counting stars and contributing. Press F to pay respect to glorious developers.

deno

by denoland rust

star image 81698 MIT

A modern runtime for JavaScript and TypeScript.

rust

by rust-lang rust

star image 65482 NOASSERTION

Empowering everyone to build reliable and efficient software.

alacritty

by alacritty rust

star image 37538 Apache-2.0

A cross-platform, OpenGL terminal emulator.

tauri

by tauri-apps rust

star image 36698 Apache-2.0

Build smaller, faster, and more secure desktop applications with a web frontend.

bat

by sharkdp rust

star image 33294 NOASSERTION

A cat(1) clone with wings.

ripgrep

by BurntSushi rust

star image 27048 NOASSERTION

ripgrep recursively searches directories for a regex pattern while respecting your gitignore

meilisearch

by meilisearch rust

star image 25990 MIT

Powerful, fast, and an easy to use search engine

starship

by starship rust

star image 24749 ISC

☄🌌️ The minimal, blazing-fast, and infinitely customizable prompt for any shell!

Trending New libraries in Rust

AppFlowy

by AppFlowy-IO rust

star image 20428 AGPL-3.0

AppFlowy is an open-source alternative to Notion. You are in charge of your data and customizations. Built with Flutter and Rust.

tools

by rome rust

star image 18488 MIT

The Rome Toolchain. A linter, compiler, bundler, and more for JavaScript, TypeScript, HTML, Markdown, and CSS.

appflowy

by AppFlowy-IO rust

star image 16821 AGPL-3.0

AppFlowy is an open-source alternative to Notion. You are in charge of your data and customizations. Built with Flutter and Rust.

bevy

by bevyengine rust

star image 15512 NOASSERTION

A refreshingly simple data-driven game engine built in Rust

rustdesk

by rustdesk rust

star image 11657 GPL-3.0

Yet another remote desktop software

helix

by helix-editor rust

star image 8142 MPL-2.0

A post-modern modal text editor.

gitui

by extrawurst rust

star image 7791 MIT

Blazing 💥 fast terminal-ui for git written in rust 🦀

czkawka

by qarmin rust

star image 6600 NOASSERTION

Multi functional app to find duplicates, empty folders, similar images etc.

RustScan

by RustScan rust

star image 6109 GPL-3.0

🤖 The Modern Port Scanner 🤖

AppFlowy

by AppFlowy-IO rust

star image 20428 AGPL-3.0

AppFlowy is an open-source alternative to Notion. You are in charge of your data and customizations. Built with Flutter and Rust.

tools

by rome rust

star image 18488 MIT

The Rome Toolchain. A linter, compiler, bundler, and more for JavaScript, TypeScript, HTML, Markdown, and CSS.

appflowy

by AppFlowy-IO rust

star image 16821 AGPL-3.0

AppFlowy is an open-source alternative to Notion. You are in charge of your data and customizations. Built with Flutter and Rust.

bevy

by bevyengine rust

star image 15512 NOASSERTION

A refreshingly simple data-driven game engine built in Rust

rustdesk

by rustdesk rust

star image 11657 GPL-3.0

Yet another remote desktop software

helix

by helix-editor rust

star image 8142 MPL-2.0

A post-modern modal text editor.

gitui

by extrawurst rust

star image 7791 MIT

Blazing 💥 fast terminal-ui for git written in rust 🦀

czkawka

by qarmin rust

star image 6600 NOASSERTION

Multi functional app to find duplicates, empty folders, similar images etc.

RustScan

by RustScan rust

star image 6109 GPL-3.0

🤖 The Modern Port Scanner 🤖

Top Authors in Rust

1

119 Libraries

21460

2

107 Libraries

4

3

103 Libraries

2802

4

96 Libraries

1179

5

88 Libraries

4414

6

87 Libraries

12

7

86 Libraries

12617

8

86 Libraries

134

9

78 Libraries

34

10

78 Libraries

171439

1

119 Libraries

21460

2

107 Libraries

4

3

103 Libraries

2802

4

96 Libraries

1179

5

88 Libraries

4414

6

87 Libraries

12

7

86 Libraries

12617

8

86 Libraries

134

9

78 Libraries

34

10

78 Libraries

171439

Trending Kits in Rust

Web3 has the underpinnings to provide for a genuinely democratic and privacy-focused World Wide Web! The early web was democratic and provided unprecedented access to information. However, given the nascent state, it was highly disorganized and provided inconsistent collaboration experiences. This led to the evolution of hyper-scale providers in Web 2.0, which brought in organization, and exciting ways of social and mobile collaboration. The downside of Web 2.0 is a very disproportionate imbalance in power resting with the big tech and social media companies and zero control with the consumers, who surprisingly are the content and data creators. These global concerns around the absolute dominance of tech platforms over consumers and privacy are driving Web 3. The core concepts of Web 3 that I found most defining are 1. A fully decentralized web, based on blockchain principles 2. The users generate tokens and in many ways are empowered to influence the platform 3. The users own and control their data While the Web 3.0 concept is a continuous work in progress, the recent focus on control, privacy, and the general prevalence of blockchain are making it closer to reality. Get ready and get started! The kandi kit on Getting Started with Web3 showcases Web3 libraries to interface with the blockchain easily.

Web3 Starter Libraries

Web3 has the underpinnings to provide for a genuinely democratic and privacy-focused World Wide Web! The early web was democratic and provided unprecedented access to information. However, given the nascent state, it was highly disorganized and provided inconsistent collaboration experiences. This led to the evolution of hyper-scale providers in Web 2.0, which brought in organization, and exciting ways of social and mobile collaboration. The downside of Web 2.0 is a very disproportionate imbalance in power resting with the big tech and social media companies and zero control with the consumers, who surprisingly are the content and data creators. These global concerns around the absolute dominance of tech platforms over consumers and privacy are driving Web 3. The core concepts of Web 3 that I found most defining are 1. A fully decentralized web, based on blockchain principles 2. The users generate tokens and in many ways are empowered to influence the platform 3. The users own and control their data While the Web 3.0 concept is a continuous work in progress, the recent focus on control, privacy, and the general prevalence of blockchain are making it closer to reality. Get ready and get started! The kandi kit on Getting Started with Web3 showcases Web3 libraries to interface with the blockchain easily.

Web3 Starter Libraries

Trending Discussions on Rust

    Why is Rust NLL not working for multiple borrows in the same statement?
    Next failed to load SWC binary
    Emulate BTreeMap::pop_last in stable Rust
    Match ergonomics and & pattern
    What is the built-in `#[main]` attribute?
    Difference between `cargo doc` and `cargo rustdoc`
    Unable to specify `edition2021` in order to use unstable packages in Rust
    What is the idiomatic way to do something when an Option is either None, or the inner value meets some condition?
    What is the official Rust guidance for interoperability with C++, in particular passing and returning structs as arguments?
    Why does iteration over an inclusive range generate longer assembly in Rust?

QUESTION

Why is Rust NLL not working for multiple borrows in the same statement?

Asked 2022-Apr-12 at 00:43

First, I tried something like this:

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3

It can't be compiled because:

error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable

I thought that the Rust borrow checker could be smarter than this, so I found something called NLL, and it should solve this problem.

I tried the sample:

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5

It could work, but why is it not working with rotate_right? Both of them take a &mut self. What's going on?

ANSWER

Answered 2022-Apr-12 at 00:43

It is definitely an interesting one.

They are similar - but not quite the same. resize() is a member of Vec. rotate_right(), on the other hand, is a method of slices.

Vec<T> derefs to [T], so most of the time this does not matter. But actually, while this call:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6

Desugars to something like:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7

This call:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8

Is more like:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8&lt;[i32]&gt;::rotate_right(
9    &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(&amp;mut vec),
10    &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec),
11);
12

But in what order?

This is the MIR for rotate_right() (simplified a lot):

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8&lt;[i32]&gt;::rotate_right(
9    &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(&amp;mut vec),
10    &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec),
11);
12fn foo() -&gt; () {
13    _4 = &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(move _5);
14    _6 = Vec::&lt;i32&gt;::len(move _7);
15    _2 = core::slice::&lt;impl [i32]&gt;::rotate_right(move _3, move _6);
16}
17

And this is the MIR for resize() (again, simplified a lot):

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8&lt;[i32]&gt;::rotate_right(
9    &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(&amp;mut vec),
10    &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec),
11);
12fn foo() -&gt; () {
13    _4 = &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(move _5);
14    _6 = Vec::&lt;i32&gt;::len(move _7);
15    _2 = core::slice::&lt;impl [i32]&gt;::rotate_right(move _3, move _6);
16}
17fn foo() -&gt; () {
18    _4 = Vec::&lt;i32&gt;::len(move _5);
19    _2 = Vec::&lt;i32&gt;::resize(move _3, move _4, const 0_i32);
20}
21

In the resize() example, we first call Vec::len() with a reference to vec. This returns usize. Then we call Vec::resize(), when we have no outstanding references to vec, so mutably borrowing it is fine!

However, with rotate_right(), first we call <Vec<i32> as DerefMut>::deref_mut(&mut vec). This returns &mut [i32], with its lifetime tied to vec. That is, as long as this reference (mutable reference!) is alive, we are not allowed to use have any other reference to vec. But then we try to borrow vec in order to pass the (shared, but it doesn't matter) reference to Vec::len(), while we still need to use the mutable reference from deref_mut() later, in the call to <[i32]>::rotate_right()! This is an error.

This is because Rust defines an evaluation order for operands:

Expressions taking multiple operands are evaluated left to right as written in the source code.

Because vec.resize() is actually (&mut *vec).rotate_right(), we first evaluate the dereference+reference, then the arguments:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8&lt;[i32]&gt;::rotate_right(
9    &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(&amp;mut vec),
10    &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec),
11);
12fn foo() -&gt; () {
13    _4 = &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(move _5);
14    _6 = Vec::&lt;i32&gt;::len(move _7);
15    _2 = core::slice::&lt;impl [i32]&gt;::rotate_right(move _3, move _6);
16}
17fn foo() -&gt; () {
18    _4 = Vec::&lt;i32&gt;::len(move _5);
19    _2 = Vec::&lt;i32&gt;::resize(move _3, move _4, const 0_i32);
20}
21let dereferenced_vec = &amp;mut *vec;
22let len = vec.len();
23dereferencec_vec.rotate_right(len);
24

Which is obviously a violation of the borrow rules.

On the other hand, vec.resize(vec.len()) has no work to do on the callee (vec), and so we first evaluate vec.len(), and then the call itself.

Solving this is as easy as extracting the vec.len() to a new line (new statement, to be precise), and the compiler also suggests that.

Source https://stackoverflow.com/questions/71823410

Community Discussions contain sources that include Stack Exchange Network

    Why is Rust NLL not working for multiple borrows in the same statement?
    Next failed to load SWC binary
    Emulate BTreeMap::pop_last in stable Rust
    Match ergonomics and &amp; pattern
    What is the built-in `#[main]` attribute?
    Difference between `cargo doc` and `cargo rustdoc`
    Unable to specify `edition2021` in order to use unstable packages in Rust
    What is the idiomatic way to do something when an Option is either None, or the inner value meets some condition?
    What is the official Rust guidance for interoperability with C++, in particular passing and returning structs as arguments?
    Why does iteration over an inclusive range generate longer assembly in Rust?

QUESTION

Why is Rust NLL not working for multiple borrows in the same statement?

Asked 2022-Apr-12 at 00:43

First, I tried something like this:

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3

It can't be compiled because:

error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable

I thought that the Rust borrow checker could be smarter than this, so I found something called NLL, and it should solve this problem.

I tried the sample:

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5

It could work, but why is it not working with rotate_right? Both of them take a &mut self. What's going on?

ANSWER

Answered 2022-Apr-12 at 00:43

It is definitely an interesting one.

They are similar - but not quite the same. resize() is a member of Vec. rotate_right(), on the other hand, is a method of slices.

Vec<T> derefs to [T], so most of the time this does not matter. But actually, while this call:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6

Desugars to something like:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7

This call:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8

Is more like:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8&lt;[i32]&gt;::rotate_right(
9    &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(&amp;mut vec),
10    &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec),
11);
12

But in what order?

This is the MIR for rotate_right() (simplified a lot):

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8&lt;[i32]&gt;::rotate_right(
9    &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(&amp;mut vec),
10    &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec),
11);
12fn foo() -&gt; () {
13    _4 = &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(move _5);
14    _6 = Vec::&lt;i32&gt;::len(move _7);
15    _2 = core::slice::&lt;impl [i32]&gt;::rotate_right(move _3, move _6);
16}
17

And this is the MIR for resize() (again, simplified a lot):

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8&lt;[i32]&gt;::rotate_right(
9    &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(&amp;mut vec),
10    &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec),
11);
12fn foo() -&gt; () {
13    _4 = &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(move _5);
14    _6 = Vec::&lt;i32&gt;::len(move _7);
15    _2 = core::slice::&lt;impl [i32]&gt;::rotate_right(move _3, move _6);
16}
17fn foo() -&gt; () {
18    _4 = Vec::&lt;i32&gt;::len(move _5);
19    _2 = Vec::&lt;i32&gt;::resize(move _3, move _4, const 0_i32);
20}
21

In the resize() example, we first call Vec::len() with a reference to vec. This returns usize. Then we call Vec::resize(), when we have no outstanding references to vec, so mutably borrowing it is fine!

However, with rotate_right(), first we call <Vec<i32> as DerefMut>::deref_mut(&mut vec). This returns &mut [i32], with its lifetime tied to vec. That is, as long as this reference (mutable reference!) is alive, we are not allowed to use have any other reference to vec. But then we try to borrow vec in order to pass the (shared, but it doesn't matter) reference to Vec::len(), while we still need to use the mutable reference from deref_mut() later, in the call to <[i32]>::rotate_right()! This is an error.

This is because Rust defines an evaluation order for operands:

Expressions taking multiple operands are evaluated left to right as written in the source code.

Because vec.resize() is actually (&mut *vec).rotate_right(), we first evaluate the dereference+reference, then the arguments:

copy icondownload icon

1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6&lt;Vec&lt;i32&gt;&gt;::resize(&amp;mut vec, &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec), 0);
7vec.rotate_right(vec.len());
8&lt;[i32]&gt;::rotate_right(
9    &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(&amp;mut vec),
10    &lt;Vec&lt;i32&gt;&gt;::len(&amp;vec),
11);
12fn foo() -&gt; () {
13    _4 = &lt;Vec&lt;i32&gt; as DerefMut&gt;::deref_mut(move _5);
14    _6 = Vec::&lt;i32&gt;::len(move _7);
15    _2 = core::slice::&lt;impl [i32]&gt;::rotate_right(move _3, move _6);
16}
17fn foo() -&gt; () {
18    _4 = Vec::&lt;i32&gt;::len(move _5);
19    _2 = Vec::&lt;i32&gt;::resize(move _3, move _4, const 0_i32);
20}
21let dereferenced_vec = &amp;mut *vec;
22let len = vec.len();
23dereferencec_vec.rotate_right(len);
24

Which is obviously a violation of the borrow rules.

On the other hand, vec.resize(vec.len()) has no work to do on the callee (vec), and so we first evaluate vec.len(), and then the call itself.

Solving this is as easy as extracting the vec.len() to a new line (new statement, to be precise), and the compiler also suggests that.

Source https://stackoverflow.com/questions/71823410

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in Rust

Tutorials and Learning Resources are not available at this moment for Rust

Share this Page

share link

Get latest updates on Rust

  • © 2022 Open Weaver Inc.