profile
viewpoint

tmandry/AXSwift 115

Swift wrapper for accessibility clients

tmandry/lavender 46

Generate Visual Studio projects for Bazel (experimental)

tmandry/great-start 2

Great starting point for Rails projects. Includes Mongoid, Devise, RSpec, Spork, Guard, Slim, and Bootstrap.

tmandry/django-fresh 1

Auto-refreshes your browser after updating files in your project in a development environment.

kickasstimus/IOBoard 0

IOBoard is a simple in/out board that shows who is in or out of the office and whether they are available.

tmandry/adage 0

2D game and AI engine built using Qt/C++ (high school side project)

tmandry/agent 0

The configuration application of the Ultimate Hacking Keyboard

tmandry/alloy 0

Toy OS project in Rust

tmandry/askbot-devel 0

ASKBOT is a StackOverflow-like Q&A forum, based on CNPROG.

push eventtmandry/rust

Tyler Mandry

commit sha 0587ec9b00f2348f7184c5a3fd377596f484c02d

Remove skip_only_host_steps And make tests explicitly list their hosts and targets.

view details

Tyler Mandry

commit sha 2826235da4fe790c31c0b5f117428271ef036425

Update CI scripts to accommodate --host change

view details

push time in 14 hours

pull request commentrust-lang/rust

bootstrap: Always build for host, even when target is given

Right, and because these changes are "live" as soon as they merge, I think we're always going to have the issue of there being only a single change for each version. Which means we might want to tweak the changelog format a bit. Maybe grouping them by month would make sense?

I do like the idea of sticking the change text in check_version(), i.e. a programmatic changelog to match the text one. One other idea: it would be nice if there were a flag or command to bump the version in your config.toml for you =)

tmandry

comment created time in 14 hours

push eventtmandry/rust

Tyler Mandry

commit sha 2b423e1ae6491514a0f69b746516ffe212d4a764

Remove skip_only_host_steps And make tests explicitly list their hosts and targets.

view details

Tyler Mandry

commit sha 631bd067559a3f4d056f6aecef222527b0020ce1

Update CI scripts to accommodate --host change

view details

push time in 14 hours

pull request commentrust-lang/rust

bootstrap: Always build for host, even when target is given

Do you mean in the changelog? Or in check_version()?

A changelog entry would probably look something like:

host now defaults to the value of build in all cases. Previously we defaulted host to an empty list when target was overridden and to build otherwise.

tmandry

comment created time in 15 hours

push eventtmandry/rust

Ivan Tham

commit sha c5975e9b6c5781b3b7300b7921c14b060086e1c1

Reduce duplicate in liballoc reserve error handling

view details

Federico Ponzi

commit sha 27c90b881df93b53fd3f24dcbfed116379c2fc69

initial implementation of OpenOptions to c_int

view details

Federico Ponzi

commit sha eb3906be4ad375cc6b83cd6a6e0116817db22575

Fix typo get openoptions function name Co-authored-by: Ivan Tham <pickfire@riseup.net>

view details

Federico Ponzi

commit sha 1bc0627607262cc60a7692b16e205f30fc88b89f

Add as_flag function to the OpenOptionsExt struct

view details

Federico Ponzi

commit sha 2c9e27b759a9e9feeb943fb855e32d7383d1dcc6

Merge branch 'convert-openoptions-cint' of github.com:FedericoPonzi/rust into convert-openoptions-cint

view details

Federico Ponzi

commit sha 7c1e5c1dcd25c945f619eda289f639dbe2b002da

Update OpenOptions::as_flags docs, and minor styling

view details

Federico Ponzi

commit sha 321b680fe66d1be04cd67fac75ff7f148fd117fe

Update docs of OpenOptions::as_flags

view details

Federico Ponzi

commit sha 28db5214d2c48e7a58cf79b9e272097260910a33

More implementations of Write for immutable refs Fixes #73836

view details

Guillaume Gomez

commit sha 69ffed763d1540c387db3b578848184026da0484

Add error explanation for E0755

view details

Tavian Barnes

commit sha a06edda3ad9abd4f07d07bbe46cb488efeebbbd0

Fix segfault if pthread_getattr_np fails glibc destroys[1] the passed pthread_attr_t if pthread_getattr_np() fails. Destroying it again leads to a segfault. Fix it by only destroying it on success for glibc. [1]: https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/pthread_getattr_np.c;h=ce437205e41dc05653e435f6188768cccdd91c99;hb=HEAD#l205

view details

Tavian Barnes

commit sha a684153f2920729f9fc3ea27ddb77d7cc3543214

Only call pthread_attr_destroy() after getattr_np() succeeds on all libcs The calling convention of pthread_getattr_np() is to initialize the pthread_attr_t, so _destroy() is only necessary on success (and _init() isn't necessary beforehand). On the other hand, FreeBSD wants the attr_t to be initialized before pthread_attr_get_np(), and therefore it should always be destroyed afterwards.

view details

Federico Ponzi

commit sha ec7f9b927f1896c7f29c602d6b0f961c891d0941

Deduplicates io::Write implementations

view details

Christiaan Dirkx

commit sha 8f27e3cb1b4140d9124d60df0850ef734e73b884

Make some methods of `Pin` unstable const Make the following methods unstable const under the `const_pin` feature: - `new` - `new_unchecked` - `into_inner` - `into_inner_unchecked` - `get_ref` - `into_ref` Also adds tests for these methods in a const context. Tracking issue: #76654

view details

Simon Vandel Sillesen

commit sha e5447a22222ecc6a650e75282cb9931b910854b2

Fix #76432 Only insert StorageDeads if we actually removed one. Fixes an issue where we added StorageDead to a place with no StorageLive

view details

Manish Goregaokar

commit sha c100e726c10fe9d212a58a5494126409e7d0e10b

Stabilize intra-doc links

view details

Manish Goregaokar

commit sha 63d5beec43ff7721928821cd83f9790188b03276

Move intra-doc-links documentation out of unstable section

view details

Manish Goregaokar

commit sha bc06674774e6457046e41a48dc3e8be8c5496f11

Mention super/crate/self in docs

view details

Manish Goregaokar

commit sha f072e4a7322e8e2b16410e3225e1afc15d132e36

Mention URL fragments

view details

Manish Goregaokar

commit sha 2a98409634ec38547d03512898192b5bdce15f3d

Fill out docs on intra-doc resolution failure lint

view details

Manish Goregaokar

commit sha 4e0eb0b73ba2defaf0f3c2152e9daa5c18d1603f

Update src/doc/rustdoc/src/linking-to-items-by-name.md Co-authored-by: Joshua Nelson <joshua@yottadb.com>

view details

push time in 15 hours

pull request commentrust-lang/rust

bootstrap: Always build for host, even when target is given

Hmm, thinking about this more and I'm pretty on the fence about what to do.

For config.toml it seems like we're reverting back to what we had 1-2 weeks ago, so having people bump changelog-seen feels like overkill.

For the command line we could consider it a breaking change, but we could also say that building more than we used to in some cases isn't actually breaking. Still, we do want people who might be impacted to know about it.

tmandry

comment created time in 15 hours

pull request commentrust-lang/rust

bootstrap: Always build for host, even when target is given

No need to add a new version, just append to the list of changes.

Should we consider it a breaking change though?

tmandry

comment created time in 15 hours

Pull request review commentrust-lang/rust

bootstrap: Always build for host, even when target is given

 impl Config {          let build = toml.build.unwrap_or_default(); -        // If --target was specified but --host wasn't specified, don't run any host-only tests.-        let has_hosts = build.host.is_some() || flags.host.is_some();-        let has_targets = build.target.is_some() || flags.target.is_some();-        config.skip_only_host_steps = !has_hosts && has_targets;-         config.hosts = if let Some(arg_host) = flags.host {             arg_host         } else if let Some(file_host) = build.host {             file_host.iter().map(|h| TargetSelection::from_user(h)).collect()         } else {             vec![config.build]         };+        // If host was explicitly given an empty list, don't run any host-only steps.+        config.skip_only_host_steps = config.hosts.is_empty();

Ah that makes sense, done. I also made them list all their targets explicitly for consistency.

tmandry

comment created time in 16 hours

PullRequestReviewEvent

push eventtmandry/rust

Tyler Mandry

commit sha 114c806b0db0ea6ac06c46bb742fdde4b5e0e6f6

Remove skip_only_host_steps And make tests explicitly list their hosts and targets.

view details

push time in 16 hours

issue commentrust-lang/rust

Move the doc directory to separate repo

@steveklabnik This section in the guide has the commands we use for clippy. I'm not too familiar with it but @oli-obk and @Manishearth probably have the most hands-on experience.

arijit79

comment created time in a day

Pull request review commentrust-lang/rust

bootstrap: Always build for host, even when target is given

 impl Config {          let build = toml.build.unwrap_or_default(); -        // If --target was specified but --host wasn't specified, don't run any host-only tests.-        let has_hosts = build.host.is_some() || flags.host.is_some();-        let has_targets = build.target.is_some() || flags.target.is_some();-        config.skip_only_host_steps = !has_hosts && has_targets;-         config.hosts = if let Some(arg_host) = flags.host {             arg_host         } else if let Some(file_host) = build.host {             file_host.iter().map(|h| TargetSelection::from_user(h)).collect()         } else {             vec![config.build]         };+        // If host was explicitly given an empty list, don't run any host-only steps.+        config.skip_only_host_steps = config.hosts.is_empty();

I tried that at first but it changed the dist behavior in the test: it causes us to distribute a rustc for the build target ("A" in the test) as well as sources. Is that desirable?

tmandry

comment created time in 2 days

PullRequestReviewEvent

pull request commentrust-lang/rfcs

RFC: Promote aarch64-unknown-linux-gnu to a Tier-1 Rust target

At most, I'd call it a known soundness issue, of which there are many even on Tier 1.

Yes, but I would wager that most of those (at least, the ones that have been open for awhile) are fairly limited in scope. If not, they'd be P-critical and we'd be fixing it immediately.

What's the scope of this? Stack overflows can happen in many programs, and I've seen Rust functions with some very large stack frames. It's not uncommon for programs to have a recursion level dictated by user input (e.g. parsers). So my question is about whether that can be exploited in the wild.

"Relaxing the guarantee" sounds like we would never intend to fix this, but really it would just be a pragmatic choice to say that this is not a hard blocker.

Fair enough. What I was trying to get across is that Rust programmers on Tier 1 targets enjoy freedom in practice from memory exploits when writing safe code. I'm just trying to make sure that remains the case.

Stack clashing - the primary scenario for which stack probing is the mitigation - is an arguably pathological scenario to exploit.

This may be true and I think it's an important point. Despite some of my earlier phrasing, my concern isn't about UB existing in the abstract, but about UB that can lead to high-severity exploits in reality. If it matters, I think it's also fair to consider any mitigations (like ASLR) that Linux enables by default, since this RFC is about Linux.

I'm not a security expert and I'd be happy to learn that this is pretty much impossible to exploit in practice :)

Personally speaking, I would rather not have this promotion blocked on known technical details, as I see tier-labels rather as a statement of support and quality levels.

I tend to agree with this. A statement of support I have no problem with, and I personally would like to see arm64 get promoted as soon as possible. It's clear that this is a platform of significant interest to Rust users and I count myself as one of them!

It's the quality level that I'm double checking here. I'd note that users' expectations around quality are shaped by the state of other Tier 1 targets. Even if they used to have this problem, most people have probably forgotten this, and Rust is more mature and stable overall than it was 3 years ago.

raw-bin

comment created time in 2 days

PR opened rust-lang/rust

bootstrap: Always build for host, even when target is given

This changes the behavior from not building for host whenever an explicit target is specified. I find this much less confusing.

You can still disable host steps by passing an explicit empty list for host.

Fixes #76990.

r? @Mark-Simulacrum

+9 -17

0 comment

2 changed files

pr created time in 2 days

create barnchtmandry/rust

branch : bootstrap-host

created branch time in 2 days

issue commentrust-lang/rust

x.py install does nothing when `target` is set but `host` is not

Okay, I'm working on a change to do that.

tmandry

comment created time in 2 days

issue commentrust-lang/rust

x.py install does nothing

Maybe I'm confused about the role of host and target. Let's say I want the compiler to run only on linux x64, and be able to target linux-x64, fuchsia-x64, fuchsia-arm64. What should my configuration be?

tmandry

comment created time in 2 days

issue commentrust-lang/rust

x.py install does nothing

I only need one host, multiple targets. It's surprising to me that specifying a target appears to override the default host?

tmandry

comment created time in 2 days

issue commentrust-lang/rust

x.py install does nothing

Yes, or at least that's what happened in the past.

For what it's worth we normally specify more targets than just the one, but this was enough to show the issue.

tmandry

comment created time in 2 days

issue commentrust-lang/rust

x.py install does nothing

Here's a config.toml:

[build]
target = ["x86_64-unknown-linux-gnu"]
docs = false
extended = true
tools = ["cargo", "clippy", "src"]

[install]
prefix = "/absolute/path/to/some/existing/but/empty/dir"

Oddly if I remove target, docs, or tools it starts building std. Also oddly, extended seems to have no impact even though I think it should.

tmandry

comment created time in 2 days

pull request commentrust-lang/rust

Rename `core::future::poll_fn` to `core::future::from_fn`

from_poll_fn returns a Future given a poll function.

What about the name do you find confusing? The type of the future we can name however we want. People don't usually write the name of the type directly, so it's not as important as making the function name clear in my opinion.

yoshuawuyts

comment created time in 2 days

pull request commentrust-lang/rust

Rename `core::future::poll_fn` to `core::future::from_fn`

Based on my own experience and others I've asked, I think a lot of people find the poll_fn name to be confusing.

At the same time, I can see that from_fn is ambiguous.

A modest proposal: What about from_poll_fn?

yoshuawuyts

comment created time in 2 days

pull request commentrust-lang/rust

Rename `core::future::poll_fn` to `core::future::from_fn`

@carllerche told me he was -1 on this change but can't post right now for technical reasons.

He asked me to post this on his behalf:

the short is, the poll terminology is already well established and it matches Future::poll from_fn is ambigious, and as hinted at, there are multiple ways to take a "fn" and turn it into a future being more specific is better

yoshuawuyts

comment created time in 2 days

Pull request review commentrust-lang/rust

[generator] Special cases for match guard when analyzing interior types in generators

 struct InteriorVisitor<'a, 'tcx> {     expr_count: usize,     kind: hir::GeneratorKind,     prev_unresolved_span: Option<Span>,+    /// Match arm guards have temporary borrows from the pattern bindings.+    /// In case there is a yield point in a guard with a reference to such bindings,+    /// such borrows can span across this yield point.+    /// As such, we need to track these borrows and record them despite of the fact+    /// that they may succeed the said yield point in the post-order.+    nested_scope_of_guards: SmallVec<[SmallVec<[HirId; 4]>; 4]>,

The outer SmallVec could probably be of len 1, since nesting these would be extremely rare in practice.

dingxiangfei2009

comment created time in 3 days

Pull request review commentrust-lang/rust

[generator] Special cases for match guard when analyzing interior types in generators

 pub fn resolve_interior<'a, 'tcx>(         expr_count: 0,         kind,         prev_unresolved_span: None,+        nested_scope_of_guards: <_>::default(),

naming suggestion: guard_bindings

dingxiangfei2009

comment created time in 3 days

Pull request review commentrust-lang/rust

[generator] Special cases for match guard when analyzing interior types in generators

 pub fn resolve_interior<'a, 'tcx>(         expr_count: 0,         kind,         prev_unresolved_span: None,+        nested_scope_of_guards: <_>::default(),+        current_scope_of_guards: <_>::default(),

naming suggestion: guard_bindings_set

dingxiangfei2009

comment created time in 3 days

Pull request review commentrust-lang/rust

[generator] Special cases for match guard when analyzing interior types in generators

 impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {         NestedVisitorMap::None     } +    fn visit_arm(&mut self, arm: &'tcx Arm<'tcx>) {+        if arm.guard.is_some() {+            self.nested_scope_of_guards.push(<_>::default());+            self.arm_has_guard = true;+        }+        self.visit_pat(&arm.pat);+        if let Some(ref g) = arm.guard {+            match g {+                Guard::If(ref e) => {+                    self.visit_expr(e);+                }+            }+            let mut scope_var_ids =+                self.nested_scope_of_guards.pop().expect("should have pushed at least one earlier");+            for var_id in scope_var_ids.drain(..) {+                assert!(+                    self.current_scope_of_guards.remove(&var_id),+                    "variable should be placed in scope earlier"+                );+            }+            self.arm_has_guard = false;+        }+        self.visit_expr(&arm.body);+    }+     fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {         intravisit::walk_pat(self, pat);          self.expr_count += 1; -        if let PatKind::Binding(..) = pat.kind {+        if let PatKind::Binding(_, id, ..) = pat.kind {             let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);             let ty = self.fcx.typeck_results.borrow().pat_ty(pat);-            self.record(ty, Some(scope), None, pat.span);+            self.record(ty, Some(scope), None, pat.span, false);+            if self.arm_has_guard {

We may want to check that this binding is actually introduced by the if guard, instead of by some arbitrary expression inside it.

That said, it's okay if we overapproximate the set of types inside our generator. Since it's very rare to have other bindings introduced inside a match guard, we could leave this as is. If we do that we should leave a comment explaining that this is an overapproximation.

dingxiangfei2009

comment created time in 3 days

Pull request review commentrust-lang/rust

[generator] Special cases for match guard when analyzing interior types in generators

 impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {         NestedVisitorMap::None     } +    fn visit_arm(&mut self, arm: &'tcx Arm<'tcx>) {+        if arm.guard.is_some() {+            self.nested_scope_of_guards.push(<_>::default());+            self.arm_has_guard = true;+        }+        self.visit_pat(&arm.pat);+        if let Some(ref g) = arm.guard {+            match g {+                Guard::If(ref e) => {+                    self.visit_expr(e);+                }+            }+            let mut scope_var_ids =+                self.nested_scope_of_guards.pop().expect("should have pushed at least one earlier");+            for var_id in scope_var_ids.drain(..) {+                assert!(+                    self.current_scope_of_guards.remove(&var_id),+                    "variable should be placed in scope earlier"+                );+            }+            self.arm_has_guard = false;

We should reset back to the original value, which won't always be false (if there were a match nested inside the guard). Here's a (very contrived) example..

match x {
  Some(y) if match y.len() { 0 => false, l if l % 2 == 0 => true, _ => false } => (),
  _ => (),
}

In fact, I'm tempted to say this flag is redundant and we should remove it. We can query current_scope_of_guards every time, and only find a way to optimize that if it's slow.

dingxiangfei2009

comment created time in 3 days

Pull request review commentrust-lang/rust

[generator] Special cases for match guard when analyzing interior types in generators

 impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {         NestedVisitorMap::None     } +    fn visit_arm(&mut self, arm: &'tcx Arm<'tcx>) {+        if arm.guard.is_some() {+            self.nested_scope_of_guards.push(<_>::default());+            self.arm_has_guard = true;

It seems like we'd only want to set this while visiting the guard if expression, not the pattern.

dingxiangfei2009

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

delete branch tmandry/rust

delete branch : perf-72412

delete time in 3 days

PR closed rust-lang/rust

Perf run for #72412

Just creating this to run perf for #72412 without the last commit.

cc @VFLashM

r? @ghost

+342 -80

13 comments

22 changed files

tmandry

pr closed time in 3 days

Pull request review commentrust-lang/wg-async-foundations

Draft RFC to add a `must_not_await` lint

+# RFC: Must not await lint++# Summary++Introduce a `#[must_not_await]` lint in the compiler that will warn the user when they are incorrectly holding a struct across an await boundary.++# Motivation++Enable users to fearlessly write concurrent async code without the need to understand the internals of runtimes and how their code will be affected. The goal is to provide a best effort warning that will let the user know of a possible side effect that is not visible by reading the code right away. Some examples of these side effects are holding a `MutexGuard` across an await bound in a single threaded runtime. In this case the resulting generated future will resolve to `!Send` but could still hold the lock when the future yields back to the executor. This opens up for the possibility of causing a deadlock since the future holding onto the lock did not relinquish it back before it yielded control. This can become even more problematic for futures that run on single-threaded runtimes (`!Send`) where holding a local after a yield will result in a deadlock.++The big reason for including a lint like this is because under the hood the compiler will automatically transform async fn into a state machine which can store locals. This process is invisible to users and will produce code that is different than what is in the actual rust file. Due to this it is important to inform users that their code may not do what they expect.++# Guide-level explanation++Provide a lint that can be attached to structs to let the compiler know that this struct can not be held across an await boundary.++```rust+    #[must_not_await]+    struct MyStruct {}+```++This struct if held across an await boundary would cause a warning:++```rust+    async fn foo() {+      let my_struct = MyStruct {};+      my_async_op.await;+      println!("{:?}", my_struct);+    }+```++The compiler might output something along the lines of:++TODO: Write a better error message.+```+warning: Holding `MyStruct` across the await bound on line 3 might cause side effects.+```++Example use cases for this lint:++- `MutexGuard` holding this across a yield boundary in a single threaded executor could cause deadlocks. In a multi-threaded runtime the resulting future would become `!Send` which will stop the user from spawning this future and causing issues. But in a single threaded runtime which accepts `!Send` futures deadlocks could happen.++- The same applies to other such synchronization primitives such as locks from `parking-lot`.++- `tracing::Span` has the ability to enter the span via the `tracing::span::Entered` guard. While entering a span is totally normal, during an async fn the span only needs to be entered once before the `.await` call, which might potentially yield the execution.++- Any RAII guard might possibly create unintended behavior if held across an await boundary.++This lint will enable the compiler to warn the user that the generated MIR could produce unforeseen side effects. Some examples of this are:++- [`std::sync::MutexGuard`](https://doc.rust-lang.org/std/sync/struct.MutexGuard.html)+- [`tracing::span::Entered`](https://docs.rs/tracing/0.1.15/tracing/span/struct.Entered.html)++This will be a best effort lint to signal to the user about unintended side-effects of using certain types across an await boundary.++# Reference-level explanation++Going throuogh the prior are we see two systems currently which provide simailar/semantically similar behavior:++## Clippy `#[await_holding_lock]` lint+This lint goes through all types in `generator_interior_types` looking for `MutexGuard`, `RwLockReadGuard` and `RwLockWriteGuard`. While this is a first great step, we think that this can be further extended to handle not only the hardcoded lock guards, but any type which is should not be held across an await point. By marking a type as `#[must_not_await]` we can warn when any arbitrary type is being held across an await boundary. An additional benefit to this approach is that this behaviour can be extended to any type which holds a `#[must_not_await]` type inside of it.++## `#[must_use]` attribute+The `#[must_use]` attribute ensures that if a type or the result of a function is not used, a warning is displayed. This ensures that the user is notified about the importance of said value. Currently the attribute does not automatically get applied to any type which contains a type declared as `#[must_use]`, but the implementation for both `#[must_not_await]` and `#[must_use]` should be similar in their behavior.++### Auto trait vs attribute+`#[must_use]` is implemented as an attribute, and from prior art and [other literature][linear-types], we can gather that the decision was made due to the complexity of implementing true linear types in Rust. [`std::panic::UnwindSafe`][UnwindSafe] on the other hand is implemented as a marker trait with structural composition.+++## High level design overview+++The main body of finding the types which are captured in the state machine for an async block are done during the [typechecking][typechk] phase. From a 10000ft view, generators currently analyze the body of the async block to [build the list of values][resolve-interior] which live across a yield point. We can use this list of types to check whether or not any of them have been marked as `#[must_not_await]`. In order to do so, we can leverage the HIR definition of the types which would include the annotation.++The attribute can be found by querying the session by the `DefId` of each of the captured type, and a warning can issued based on whether or not the types captured in the generator have the attribute associated with them.++We also have the option of precomputing the presence of an attribute on a type during parsing and storing this information on the type flags for the type. In my opinion this would be the more efficient way of implementing this check as queriying the `Session` object for a large list of types could become an expensive operation.++[linear-types]: https://gankra.github.io/blah/linear-rust/+[UnwindSafe]: https://doc.rust-lang.org/std/panic/trait.UnwindSafe.html+[resolve-interior]: https://github.com/rust-lang/rust/blob/master/src/librustc_typeck/check/generator_interior.rs#L122+[typechk]: https://github.com/rust-lang/rust/blob/3e041cec75c45e78730972194db3401af06b72ef/src/librustc_typeck/check/mod.rs#L1113++ - Reference link on how mir transfroms async fn https://tmandry.gitlab.io/blog/posts/optimizing-await-2/++# Drawbacks+- There is a possibility it can produce a false positive warning and it could get noisy. We likely want to allow overriding via some sort of module level `allow` attribute.++# Rationale and alternatives+++# Prior art++* [Clippy lint for holding locks across await points](https://github.com/rust-lang/rust-clippy/pull/5439)+* [Must use for functions](https://github.com/iopq/rfcs/blob/f4b68532206f0a3e0664877841b407ab1302c79a/text/1940-must-use-functions.md)++# Future possibilities++- Propagate the lint in nested structs/enums. Similar to the use case for the `must_use` attribute. These likely should be solved together.

Maybe for now we can add an "Unresolved questions" section and add this to it?

LucioFranco

comment created time in 3 days

Pull request review commentrust-lang/wg-async-foundations

Draft RFC to add a `must_not_await` lint

+# RFC: Must not await lint++# Summary++Introduce a `#[must_not_await]` lint in the compiler that will warn the user when they are incorrectly holding a struct across an await boundary.++# Motivation++Enable users to fearlessly write concurrent async code without the need to understand the internals of runtimes and how their code will be affected. The goal is to provide a best effort warning that will let the user know of a possible side effect that is not visible by reading the code right away.++One example of these side effects is holding a `MutexGuard` across an await bound. This opens up the possibility of causing a deadlock since the future holding onto the lock did not relinquish it back before it yielded control. This is a problem for futures that run on single-threaded runtimes (`!Send`) where holding a local after a yield will result in a deadlock. Even on multi-threaded runtimes, it would be nice to provide a custom error message that explains why the user doesn't want to do this instead of only a generic message about their future not being `Send`. Any other kind of RAII guard which depends on behavior similar to that of a `MutexGuard` will have the same issue.++The big reason for including a lint like this is because under the hood the compiler will automatically transform async fn into a state machine which can store locals. This process is invisible to users and will produce code that is different than what is in the actual rust file. Due to this it is important to inform users that their code may not do what they expect.++# Guide-level explanation++Provide a lint that can be attached to structs to let the compiler know that this struct can not be held across an await boundary.++```rust+#[must_not_await = "Your error message here"]+struct MyStruct {}+```++This struct if held across an await boundary would cause a deny-by-default warning:++```rust+async fn foo() {+  let my_struct = MyStruct {};+  my_async_op.await;+  println!("{:?}", my_struct);+}+```++The compiler might output something along the lines of:++TODO: Write a better error message.+```+warning: Holding `MyStruct` across the await bound on line 3 might cause side effects.+```++Example use cases for this lint:++- `MutexGuard` holding this across a yield boundary in a single threaded executor could cause deadlocks. In a multi-threaded runtime the resulting future would become `!Send` which will stop the user from spawning this future and causing issues. But in a single threaded runtime which accepts `!Send` futures deadlocks could happen.++- The same applies to other such synchronization primitives such as locks from `parking-lot`.++- `tracing::Span` has the ability to enter the span via the `tracing::span::Entered` guard. While entering a span is totally normal, during an async fn the span only needs to be entered once before the `.await` call, which might potentially yield the execution.++- Any RAII guard might possibly create unintended behavior if held across an await boundary.++This lint will enable the compiler to warn the user that the generated MIR could produce unforeseen side effects. Some examples of this are:++- [`std::sync::MutexGuard`](https://doc.rust-lang.org/std/sync/struct.MutexGuard.html)+- [`tracing::span::Entered`](https://docs.rs/tracing/0.1.15/tracing/span/struct.Entered.html)++This will be a best effort lint to signal the user about unintended side-effects of using certain types across an await boundary.++# Reference-level explanation++The `must_not_await` attribute is used to issue a diagnostic warning when a value is not "used". It can be applied to user-defined composite types (structs, enums and unions), functions and traits.++The `must_not_await` attribute may include a message by using the [`MetaNameValueStr`] syntax such as `#[must_not_await = "example message"]`.  The message will be given alongside the warning.++When used on a user-defined composite type, if the [expression] of an [expression statement] has this type and is used across an await point, then this lint is violated.+++```rust+#[must_not_await = "Your error message here"]+struct MyStruct {}++async fn foo() {+  let my_struct = MyStruct {};+  my_async_op.await;+  println!("{:?}", my_struct);+}+```++When used on a function, if the [expression] of an [expression statement] is a [call expression] to that function, and the expression is held across an await point, this lint is violated.++```rust+#[must_not_await]+fn foo() -> i32 { 5i32 }++async fn foo() {+  let bar = foo();+  my_async_op.await;+  println!("{:?}", bar);+}+```++When used on a [trait declaration], a [call expression] of an [expression statement] to a function that returns an [impl trait] of that trait and if the value is held across an await point, the lint is violated.++```rust+trait Trait {+    #[must_not_await]+    fn foo(&self) -> i32;+}++impl Trait for i32 {+    fn foo(&self) -> i32 { 0i32 }+}++async fn foo() {+  let bar = 5i32.foo();+  my_async_op.await;+  println!("{:?}", bar);+}+```++When used on a function in a trait implementation, the attribute does nothing.++[`MetaNameValueStr`]: https://doc.rust-lang.org/reference/attributes.html#meta-item-attribute-syntax+[expression]: https://doc.rust-lang.org/reference/expressions.html+[expression statement]: https://doc.rust-lang.org/reference/statements.html#expression-statements+[call expression]: https://doc.rust-lang.org/reference/expressions/call-expr.html+[trait declaration]: https://doc.rust-lang.org/reference/items/traits.html+[impl trait]: https://doc.rust-lang.org/reference/types/impl-trait.html++### Auto trait vs attribute

I'm not sure this belongs in the reference section. Is this an open question, or does it belong in the rational section?

LucioFranco

comment created time in 3 days

Pull request review commentrust-lang/wg-async-foundations

Draft RFC to add a `must_not_await` lint

+# RFC: Must not await lint++# Summary++Introduce a `#[must_not_await]` lint in the compiler that will warn the user when they are incorrectly holding a struct across an await boundary.++# Motivation++Enable users to fearlessly write concurrent async code without the need to understand the internals of runtimes and how their code will be affected. The goal is to provide a best effort warning that will let the user know of a possible side effect that is not visible by reading the code right away. Some examples of these side effects are holding a `MutexGuard` across an await bound in a single threaded runtime. In this case the resulting generated future will resolve to `!Send` but could still hold the lock when the future yields back to the executor. This opens up for the possibility of causing a deadlock since the future holding onto the lock did not relinquish it back before it yielded control. This can become even more problematic for futures that run on single-threaded runtimes (`!Send`) where holding a local after a yield will result in a deadlock.++The big reason for including a lint like this is because under the hood the compiler will automatically transform async fn into a state machine which can store locals. This process is invisible to users and will produce code that is different than what is in the actual rust file. Due to this it is important to inform users that their code may not do what they expect.++# Guide-level explanation++Provide a lint that can be attached to structs to let the compiler know that this struct can not be held across an await boundary.++```rust+    #[must_not_await]+    struct MyStruct {}+```++This struct if held across an await boundary would cause a warning:++```rust+    async fn foo() {+      let my_struct = MyStruct {};+      my_async_op.await;+      println!("{:?}", my_struct);+    }+```++The compiler might output something along the lines of:++TODO: Write a better error message.+```+warning: Holding `MyStruct` across the await bound on line 3 might cause side effects.+```++Example use cases for this lint:++- `MutexGuard` holding this across a yield boundary in a single threaded executor could cause deadlocks. In a multi-threaded runtime the resulting future would become `!Send` which will stop the user from spawning this future and causing issues. But in a single threaded runtime which accepts `!Send` futures deadlocks could happen.++- The same applies to other such synchronization primitives such as locks from `parking-lot`.++- `tracing::Span` has the ability to enter the span via the `tracing::span::Entered` guard. While entering a span is totally normal, during an async fn the span only needs to be entered once before the `.await` call, which might potentially yield the execution.++- Any RAII guard might possibly create unintended behavior if held across an await boundary.++This lint will enable the compiler to warn the user that the generated MIR could produce unforeseen side effects. Some examples of this are:++- [`std::sync::MutexGuard`](https://doc.rust-lang.org/std/sync/struct.MutexGuard.html)+- [`tracing::span::Entered`](https://docs.rs/tracing/0.1.15/tracing/span/struct.Entered.html)++This will be a best effort lint to signal to the user about unintended side-effects of using certain types across an await boundary.++# Reference-level explanation

looks good!

LucioFranco

comment created time in 3 days

PullRequestReviewEvent

Pull request review commentrust-lang/wg-async-foundations

Draft RFC to add a `must_not_await` lint

+# RFC: Must not await lint++# Summary++Introduce a `#[must_not_await]` lint in the compiler that will warn the user when they are incorrectly holding a struct across an await boundary.++# Motivation++Enable users to fearlessly write concurrent async code without the need to understand the internals of runtimes and how their code will be affected. The goal is to provide a best effort warning that will let the user know of a possible side effect that is not visible by reading the code right away.++One example of these side effects is holding a `MutexGuard` across an await bound. This opens up the possibility of causing a deadlock since the future holding onto the lock did not relinquish it back before it yielded control. This is a problem for futures that run on single-threaded runtimes (`!Send`) where holding a local after a yield will result in a deadlock. Even on multi-threaded runtimes, it would be nice to provide a custom error message that explains why the user doesn't want to do this instead of only a generic message about their future not being `Send`. Any other kind of RAII guard which depends on behavior similar to that of a `MutexGuard` will have the same issue.++The big reason for including a lint like this is because under the hood the compiler will automatically transform async fn into a state machine which can store locals. This process is invisible to users and will produce code that is different than what is in the actual rust file. Due to this it is important to inform users that their code may not do what they expect.++# Guide-level explanation++Provide a lint that can be attached to structs to let the compiler know that this struct can not be held across an await boundary.++```rust+#[must_not_await = "Your error message here"]+struct MyStruct {}+```++This struct if held across an await boundary would cause a deny-by-default warning:++```rust+async fn foo() {+  let my_struct = MyStruct {};+  my_async_op.await;+  println!("{:?}", my_struct);+}+```++The compiler might output something along the lines of:++TODO: Write a better error message.

You can show your custom error message here.

The generic default could be as straightforward as "MyStruct should not be held across an await"

LucioFranco

comment created time in 3 days

PullRequestReviewEvent

pull request commentrust-lang/rust

cache types during normalization

Other than perf (which looks neutral to positive for existing cases), the only possible side effects I see here are

  • Lower recursion levels
  • Fewer duplicate obligations recorded

Which all seem like a good thing!

+1 to adding a case to rustc-perf. I don't think we have to wait on that to merge this, though.

@bors r+

lcnr

comment created time in 3 days

issue commentrust-lang/rust

Async/.await and const-generics causes "Broken MIR:"

Great! Leaving open to track adding a regression test.

rot256

comment created time in 3 days

pull request commentrust-lang/rfcs

RFC: Promote aarch64-unknown-linux-gnu to a Tier-1 Rust target

I opened #77071 to track stack probing on arm64 specifically so people have an issue to watch. This is something I'd very much like to see.

As for whether it should block Tier 1: I think there's value in holding all of our Tier 1 targets to the safety guarantees of the others. It would create less confusion and less risk for Rust's brand. That said, I don't necessarily think stack probing itself should be required. I think it really hinges on the bad things that could actually happen for a particular target.

Apologies if I'm being sensationalist: Is it accurate to say that if we move to Tier 1 without stack probing support, we are effectively relaxing the guarantee of no UB without unsafe? Is there a more bounded statement we could make about what's possible in practice that's less scary?

raw-bin

comment created time in 3 days

issue openedrust-lang/rust

Support stack probing for arm64 (aarch64)

Background: #43241

This issue is to track implementation of stack probing on arm64. Most of the work necessary is in in LLVM, but this is a convenient place to track progress and final support in the Rust compiler.

Implementation: @cuviper has suggested using LLVM's inline-asm support for stack probing: https://github.com/rust-lang/rust/issues/43241#issuecomment-594099684. It does not yet support arm64.

External trackers:

  • https://projects.linaro.org/browse/LLVM-618

created time in 3 days

issue commentrust-lang/rust

Move the doc directory to separate repo

Agreed with @petrochenkov, I think we should pursue a subtree approach (#70651 has more details). This gives us the best of both worlds for contributors: people who only care about docs get to clone only that repo, and people working in the compiler get to make coordinated changes easily.

arijit79

comment created time in 3 days

pull request commentrust-lang/rust

Rename `core::future::poll_fn` to `core::future::from_fn`

I find from_fn to be a clearer name than poll_fn. From a very unscientific poll of Fuchsia developers, it seems like most people agree; at least I couldn't find anyone who disagreed. So I'm in support of this change.

yoshuawuyts

comment created time in 3 days

issue commentrust-lang/rust

Superfluous errors for missing lifetime in async function argument

We could behave as if the elided lifetime were explicit in lowering. Is there anything preventing that?

I also don't think this is problem is very specific to async-await.

djc

comment created time in 3 days

Pull request review commentrust-lang/wg-async-foundations

Draft RFC to add a `must_not_await` lint

+# RFC: Must not await lint++# Summary++Introduce a `#[must_not_await]` lint in the compiler that will warn the user when they are incorrectly holding a struct across an await boundary.++# Motivation++Enable users to fearlessly write concurrent async code without the need to understand the internals of runtimes and how their code will be affected. The goal is to provide a best effort warning that will let the user know of a possible side effect that is not visible by reading the code right away. Some examples of these side effects are holding a `MutexGuard` across an await bound in a single threaded runtime. In this case the resulting generated future will resolve to `!Send` but could still hold the lock when the future yields back to the executor. This opens up for the possibility of causing a deadlock since the future holding onto the lock did not relinquish it back before it yielded control. This can become even more problematic for futures that run on single-threaded runtimes (`!Send`) where holding a local after a yield will result in a deadlock.++The big reason for including a lint like this is because under the hood the compiler will automatically transform async fn into a state machine which can store locals. This process is invisible to users and will produce code that is different than what is in the actual rust file. Due to this it is important to inform users that their code may not do what they expect.++# Guide-level explanation++Provide a lint that can be attached to structs to let the compiler know that this struct can not be held across an await boundary.++```rust+    #[must_not_await]+    struct MyStruct {}+```++This struct if held across an await boundary would cause a warning:++```rust+    async fn foo() {+      let my_struct = MyStruct {};+      my_async_op.await;+      println!("{:?}", my_struct);+    }+```++The compiler might output something along the lines of:++TODO: Write a better error message.+```+warning: Holding `MyStruct` across the await bound on line 3 might cause side effects.+```++Example use cases for this lint:++- `MutexGuard` holding this across a yield boundary in a single threaded executor could cause deadlocks. In a multi-threaded runtime the resulting future would become `!Send` which will stop the user from spawning this future and causing issues. But in a single threaded runtime which accepts `!Send` futures deadlocks could happen.++- The same applies to other such synchronization primitives such as locks from `parking-lot`.++- `tracing::Span` has the ability to enter the span via the `tracing::span::Entered` guard. While entering a span is totally normal, during an async fn the span only needs to be entered once before the `.await` call, which might potentially yield the execution.++- Any RAII guard might possibly create unintended behavior if held across an await boundary.++This lint will enable the compiler to warn the user that the generated MIR could produce unforeseen side effects. Some examples of this are:++- [`std::sync::MutexGuard`](https://doc.rust-lang.org/std/sync/struct.MutexGuard.html)+- [`tracing::span::Entered`](https://docs.rs/tracing/0.1.15/tracing/span/struct.Entered.html)++This will be a best effort lint to signal to the user about unintended side-effects of using certain types across an await boundary.++# Reference-level explanation++Going throuogh the prior are we see two systems currently which provide simailar/semantically similar behavior:++## Clippy `#[await_holding_lock]` lint+This lint goes through all types in `generator_interior_types` looking for `MutexGuard`, `RwLockReadGuard` and `RwLockWriteGuard`. While this is a first great step, we think that this can be further extended to handle not only the hardcoded lock guards, but any type which is should not be held across an await point. By marking a type as `#[must_not_await]` we can warn when any arbitrary type is being held across an await boundary. An additional benefit to this approach is that this behaviour can be extended to any type which holds a `#[must_not_await]` type inside of it.++## `#[must_use]` attribute+The `#[must_use]` attribute ensures that if a type or the result of a function is not used, a warning is displayed. This ensures that the user is notified about the importance of said value. Currently the attribute does not automatically get applied to any type which contains a type declared as `#[must_use]`, but the implementation for both `#[must_not_await]` and `#[must_use]` should be similar in their behavior.++### Auto trait vs attribute+`#[must_use]` is implemented as an attribute, and from prior art and [other literature][linear-types], we can gather that the decision was made due to the complexity of implementing true linear types in Rust. [`std::panic::UnwindSafe`][UnwindSafe] on the other hand is implemented as a marker trait with structural composition.+++## High level design overview+++The main body of finding the types which are captured in the state machine for an async block are done during the [typechecking][typechk] phase. From a 10000ft view, generators currently analyze the body of the async block to [build the list of values][resolve-interior] which live across a yield point. We can use this list of types to check whether or not any of them have been marked as `#[must_not_await]`. In order to do so, we can leverage the HIR definition of the types which would include the annotation.++The attribute can be found by querying the session by the `DefId` of each of the captured type, and a warning can issued based on whether or not the types captured in the generator have the attribute associated with them.++We also have the option of precomputing the presence of an attribute on a type during parsing and storing this information on the type flags for the type. In my opinion this would be the more efficient way of implementing this check as queriying the `Session` object for a large list of types could become an expensive operation.++[linear-types]: https://gankra.github.io/blah/linear-rust/+[UnwindSafe]: https://doc.rust-lang.org/std/panic/trait.UnwindSafe.html+[resolve-interior]: https://github.com/rust-lang/rust/blob/master/src/librustc_typeck/check/generator_interior.rs#L122+[typechk]: https://github.com/rust-lang/rust/blob/3e041cec75c45e78730972194db3401af06b72ef/src/librustc_typeck/check/mod.rs#L1113++ - Reference link on how mir transfroms async fn https://tmandry.gitlab.io/blog/posts/optimizing-await-2/++# Drawbacks+- There is a possibility it can produce a false positive warning and it could get noisy. We likely want to allow overriding via some sort of module level `allow` attribute.++# Rationale and alternatives+++# Prior art++* [Clippy lint for holding locks across await points](https://github.com/rust-lang/rust-clippy/pull/5439)+* [Must use for functions](https://github.com/iopq/rfcs/blob/f4b68532206f0a3e0664877841b407ab1302c79a/text/1940-must-use-functions.md)++# Future possibilities++- Propagate the lint in nested structs/enums. Similar to the use case for the `must_use` attribute. These likely should be solved together.

If we do that it'll be inconsistent with #[must_use]. If that's the end goal we want we should explain why they should be different, or discuss the possibility of changing #[must_use] in the future.

Strawman: This is about what types are safe to include (transitively or not) in a Future object. #[must_use] is more about how individual values are handled in the code. The state of things today is that new types already have to think about #[must_use], but rarely do they think about yielding and async/await, and we shouldn't expect them to.

LucioFranco

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentrust-lang/wg-async-foundations

Draft RFC to add a `must_not_await` lint

+# RFC: Must not await lint++# Summary++Introduce a `#[must_not_await]` lint in the compiler that will warn the user when they are incorrectly holding a struct across an await boundary.++# Motivation++Enable users to fearlessly write concurrent async code without the need to understand the internals of runtimes and how their code will be affected. The goal is to provide a best effort warning that will let the user know of a possible side effect that is not visible by reading the code right away. Some examples of these side effects are holding a `MutexGuard` across an await bound in a single threaded runtime. In this case the resulting generated future will resolve to `!Send` but could still hold the lock when the future yields back to the executor. This opens up for the possibility of causing a deadlock since the future holding onto the lock did not relinquish it back before it yielded control. This can become even more problematic for futures that run on single-threaded runtimes (`!Send`) where holding a local after a yield will result in a deadlock.++The big reason for including a lint like this is because under the hood the compiler will automatically transform async fn into a state machine which can store locals. This process is invisible to users and will produce code that is different than what is in the actual rust file. Due to this it is important to inform users that their code may not do what they expect.++# Guide-level explanation++Provide a lint that can be attached to structs to let the compiler know that this struct can not be held across an await boundary.++```rust+    #[must_not_await]+    struct MyStruct {}+```++This struct if held across an await boundary would cause a warning:

https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html

They are basically errors that you can disable with #[allow].

LucioFranco

comment created time in 4 days

PullRequestReviewEvent

pull request commentrust-lang/rust

Reduce boilerplate with the matches! macro

@lzutao It's only a macro expansion, I doubt it would have any measurable effect on the compiler build.

LingMan

comment created time in 4 days

issue commentrust-lang/rust

x.py install does nothing

It looks like this regressed in #76415, cc @Mark-Simulacrum

tmandry

comment created time in 5 days

issue openedrust-lang/rust

x.py install does nothing

With a valid install prefix under install.prefix in config.toml, I see this:

./x.py install --stage 2
Updating only changed submodules
Submodules updated in 0.04 seconds
    Finished dev [unoptimized + debuginfo] target(s) in 0.17s
Build completed successfully in 0:00:00

But nothing is installed. This is a recent regression.

created time in 5 days

PR opened rust-lang/measureme

stack-collapse -> stack_collapse in README

Fix naming

+2 -2

0 comment

1 changed file

pr created time in 5 days

push eventtmandry/measureme

Tyler Mandry

commit sha 440331eed5adbef2529b6825ed1248646e041054

stack-collapse -> stack_collapse in README Fix naming

view details

push time in 5 days

fork tmandry/measureme

Support crate for rustc's self-profiling feature

fork in 5 days

issue commentrust-lang/rust

Exponential compile-time and type_length_limit blowup when nesting closure wrappers

Ah sorry for the confusion, we only walk each unique type once when measuring the type length now, so it will have an effect on that too.

vorner

comment created time in 6 days

issue commentrust-lang/rust

Bulk-initialization of contiguous enums with memset

That isn't guaranteed, no, but it frequently happens.

The point is that when you happen to be zeroing a bunch of discriminants with uninitialized bytes in between, we want to be able to optimize it to a memset of the entire object.

bprosnitz

comment created time in 7 days

issue commentrust-lang/rust

Exponential compile-time and type_length_limit blowup when nesting closure wrappers

The compile-time aspect of this was fixed in #72412.

vorner

comment created time in 7 days

pull request commentrust-lang/rust

Issue 72408 nested closures exponential

@rustbot modify labels: +beta-nominated

Nominating because it fixes part of the fallout from #75443, which was backported to appear in 1.46. While #72408 and #54540 predate this version of Rust, a lot of people weren't hitting these issues until then (see their comments).

Crucially, this was code that compiled fine prior to 1.46. As I understand it, people will still have to increase type length limits that they didn't have to before (already a pain), but as a result of this change fewer of them will then be hit with an unmanageable compile time.

VFLashM

comment created time in 7 days

pull request commentrust-lang/rust

Issue 72408 nested closures exponential

I took the liberty of pushing a final cleanup so we can get this in.

I think this fixes both #72408 and #54540. I just checked and while it does not fix #75992, I think a similar strategy can be applied there in a follow-up.

This is a great speedup, thanks for your diligent work!

@bors r+ rollup=never

VFLashM

comment created time in 7 days

Pull request review commentrust-lang/rust

Issue 72408 nested closures exponential

 impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {     fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {         assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be == +        let cache_key = (t, t2);

Fixed in latest commit

VFLashM

comment created time in 7 days

PullRequestReviewEvent

push eventVFLashM/rust

Tyler Mandry

commit sha 3ccb1c37e6f37070b090b63acb3751438c152ed4

Remove redundancy in cache key

view details

push time in 7 days

pull request commentrust-lang/rust

Perf run for #72412

Moved to the latest commit from #72412 and removed the extra Ty in the key just to see if that helps. Not sure it will matter too much for instruction counts though. Maybe we should tweak the SSO size a bit?

@bors try @rust-timer queue

tmandry

comment created time in 7 days

push eventtmandry/rust

Valerii Lashmanov

commit sha 2f3296192bb5be5fcb02975395052ee8c3b2bd68

Only visit types once when walking the type tree This fixes #72408. Nested closures were resulting in exponential compilation time. As a performance optimization this change introduces MiniSet, which is a simple small storage optimized set.

view details

Valerii Lashmanov

commit sha 17d2e3b5d208d29d156ff94f112b5bc95acee351

Better handling for exponential-sized types in misc places Mostly to fix ui/issues/issue-37311-type-length-limit/issue-37311.rs. Most parts of the compiler can handle deeply nested types with a lot of duplicates just fine, but some parts still attempt to naively traverse type tree. Before such problems were caught by type length limit check, but now these places will have to be changed to handle duplicated types gracefully.

view details

Valerii Lashmanov

commit sha f583513dc2ad48076665505a1418db6053657f0b

Intorduced MiniMap - a tiny small storage optimized map implementation This makes everything about 1% faster in rustc-perf, mostly negating performance hit of previous commit.

view details

Tyler Mandry

commit sha 4f7233f9f64f1c3b21b5181e0b3a0edbed9d681b

Remove redundancy in cache key

view details

push time in 7 days

Pull request review commentrust-lang/rust

Issue 72408 nested closures exponential

  use crate::ty; use crate::ty::subst::{GenericArg, GenericArgKind};+use arrayvec::ArrayVec;+use rustc_data_structures::fx::FxHashSet; use smallvec::{self, SmallVec};+use std::hash::Hash;++/// Small-storage-optimized implementation of a set+/// made specifically for walking type tree.+///+/// Stores elements in a small array up to a certain length+/// and switches to `HashSet` when that lenght is exceeded.
/// and switches to `HashSet` when that length is exceeded.
VFLashM

comment created time in 9 days

Pull request review commentrust-lang/rust

Issue 72408 nested closures exponential

 impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {     fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {         assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be == +        let cache_key = (t, t2);

Actually there's no need to include both t and t2 in the key since they're both equal! (see above assertion)

This could help performance even more..

VFLashM

comment created time in 7 days

Pull request review commentrust-lang/rust

Issue 72408 nested closures exponential

 pub trait Printer<'tcx>: Sized { /// function tries to find a "characteristic `DefId`" for a /// type. It's just a heuristic so it makes some questionable /// decisions and we may want to adjust it later.-pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {+///+/// Visited set is needed in to avoid full iteration over
/// Visited set is needed to avoid full iteration over
VFLashM

comment created time in 9 days

PullRequestReviewEvent
PullRequestReviewEvent

pull request commentrust-lang/rust

Perf run for #72412

@bors try @rust-timer queue

tmandry

comment created time in 8 days

PR opened rust-lang/rust

Perf run for #72412

Just creating this to run perf for #72412 without the last commit.

cc @VFLashM

r? @ghost

+193 -39

0 comment

10 changed files

pr created time in 8 days

create barnchtmandry/rust

branch : perf-72412

created branch time in 8 days

pull request commentrust-lang/rust

BTreeMap: avoid slices even more

@bors retry

ssomers

comment created time in 8 days

pull request commentrust-lang/rust

Issue 72408 nested closures exponential

@bors try @rust-timer queue

VFLashM

comment created time in 9 days

pull request commentrust-lang/rust

Add core::task::yield_now

My impression so far is that this can be useful in some cases, but it doesn't seem like they come up very often. That makes me question whether we should be adding it to the standard library now.

I'm also concerned that even if we document that its effect depends on the behavior of executors, people are going to start relying on the behavior in tests and such. Even though this utility is analogous to std::thread::yield_now, I think people have internalized that you can't rely on the behavior of your OS more than they have internalized that you can't rely on the behavior of your executor.

This is moot if we add such behavior as a requirement as @cramertj mentioned. Though that seems like a larger discussion.

Otherwise, I'd personally want to start with adding this to one of the futures-rs crates.

yoshuawuyts

comment created time in 9 days

pull request commentrust-lang/async-book

More beginner-friendly TCP server example

Merged. Thank you!

lbernick

comment created time in 9 days

push eventrust-lang/async-book

Lee Bernick

commit sha 87015e2183d1a4a1b7e66d4dd5030ee3ef7d6722

More beginner-friendly TCP server example (#102) I wanted to write an example to help guide people new to asynchronous programming, with fewer external dependencies (as some people requested in #66). The example starts with the [single threaded TCP server from the Rust book](https://doc.rust-lang.org/book/ch20-01-single-threaded.html) and uses async functionality to add concurrency. The example goes through: - some examples of blocking code and how to make them non blocking (should address #64 as well) - spawning tasks vs using combinators to run them concurrently on a single thread - testing code by creating mocks and implementing async read/write traits for the mocks

view details

push time in 9 days

PR merged rust-lang/async-book

More beginner-friendly TCP server example

I wanted to write an example to help guide people new to asynchronous programming, with fewer external dependencies (as some people requested in #66). The example starts with the single threaded TCP server from the Rust book and uses async functionality to add concurrency. The example goes through:

  • some examples of blocking code and how to make them non blocking (should address #64 as well)
  • spawning tasks vs using combinators to run them concurrently on a single thread
  • testing code by creating mocks and implementing async read/write traits for the mocks

Happy to receive any feedback.

+597 -199

0 comment

27 changed files

lbernick

pr closed time in 9 days

Pull request review commentrust-lang/rust

Make it more clear what an about async fn's returns when referring to what it returns

 error[E0623]: lifetime mismatch LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {    |                                           ------                ^^^^^^^^^^^^^^    |                                           |                     |-   |                                           |                     ...but data from `b` is returned here-   |                                           this parameter and the return type are declared with different lifetimes...+   |                                           |                     ...but data from `b` is held across an await point here

Hmm, this wording doesn't really work if the error is in the function signature itself. I'm confused why the span is pointing here, but one way to make the diagnostic less wrong is to remove the word "here". Then we're just telling you what's happening and providing a span that might help.

guswynn

comment created time in 9 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

Make it more clear what an about async fn's returns when referring to what it returns

 error[E0623]: lifetime mismatch LL |     async fn ref_self(&self, f: &u32) -> &u32 {    |                       -----              ----    |                       |-   |                       this parameter and the return type are declared with different lifetimes...+   |                       this parameter and the returned future are declared with different lifetimes... LL |         f-   |         ^ ...but data from `f` is returned here+   |         ^ ...but data from `f` is held across an await point here+   |+note: `async fn`s return an `impl Future<Output={return type}`+  --> $DIR/ref-self-async.rs:22:42+   |+LL |     async fn ref_self(&self, f: &u32) -> &u32 {+   |                                          ^^^^  error[E0623]: lifetime mismatch   --> $DIR/ref-self-async.rs:29:9    | LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {    |                             -----              ----    |                             |-   |                             this parameter and the return type are declared with different lifetimes...+   |                             this parameter and the returned future are declared with different lifetimes... LL |         f-   |         ^ ...but data from `f` is returned here+   |         ^ ...but data from `f` is held across an await point here+   |+note: `async fn`s return an `impl Future<Output={return type}`+  --> $DIR/ref-self-async.rs:28:48+   |+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {+   |                                                ^^^^  error[E0623]: lifetime mismatch   --> $DIR/ref-self-async.rs:33:9    | LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {    |                                     -----               ----    |                                     |-   |                                     this parameter and the return type are declared with different lifetimes...+   |                                     this parameter and the returned future are declared with different lifetimes... LL |         f-   |         ^ ...but data from `f` is returned here+   |         ^ ...but data from `f` is held across an await point here+   |+note: `async fn`s return an `impl Future<Output={return type}`+  --> $DIR/ref-self-async.rs:32:57+   |+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {+   |                                                         ^^^^  error[E0623]: lifetime mismatch   --> $DIR/ref-self-async.rs:37:9    | LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {    |                                     -----               ----    |                                     |-   |                                     this parameter and the return type are declared with different lifetimes...+   |                                     this parameter and the returned future are declared with different lifetimes... LL |         f-   |         ^ ...but data from `f` is returned here+   |         ^ ...but data from `f` is held across an await point here+   |+note: `async fn`s return an `impl Future<Output={return type}`+  --> $DIR/ref-self-async.rs:36:57+   |+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {+   |                                                         ^^^^  error[E0623]: lifetime mismatch   --> $DIR/ref-self-async.rs:41:9    | LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {    |                                             -----                ----    |                                             |-   |                                             this parameter and the return type are declared with different lifetimes...+   |                                             this parameter and the returned future are declared with different lifetimes... LL |         f-   |         ^ ...but data from `f` is returned here+   |         ^ ...but data from `f` is held across an await point here+   |+note: `async fn`s return an `impl Future<Output={return type}`+  --> $DIR/ref-self-async.rs:40:66+   |+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {+   |                                                                  ^^^^  error[E0623]: lifetime mismatch   --> $DIR/ref-self-async.rs:45:9    | LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {    |                                             -----                ----    |                                             |-   |                                             this parameter and the return type are declared with different lifetimes...+   |                                             this parameter and the returned future are declared with different lifetimes... LL |         f-   |         ^ ...but data from `f` is returned here+   |         ^ ...but data from `f` is held across an await point here+   |+note: `async fn`s return an `impl Future<Output={return type}`+  --> $DIR/ref-self-async.rs:44:66+   |+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {+   |                                                                  ^^^^  error[E0623]: lifetime mismatch   --> $DIR/ref-self-async.rs:49:9    | LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {    |                                            -----                    ---    |                                            |-   |                                            this parameter and the return type are declared with different lifetimes...+   |                                            this parameter and the returned future are declared with different lifetimes... LL |         f-   |         ^ ...but data from `f` is returned here+   |         ^ ...but data from `f` is held across an await point here+   |+note: `async fn`s return an `impl Future<Output={return type}`+  --> $DIR/ref-self-async.rs:48:69+   |+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {+   |                                                                     ^^^

Your example looks good to me!

guswynn

comment created time in 9 days

PullRequestReviewEvent

delete branch tmandry/rust

delete branch : rollup-nwntt3q

delete time in 9 days

pull request commentrust-lang/rust

Rollup of 16 pull requests

@bors r+ rollup=never p=5 @rustbot modify labels +rollup

tmandry

comment created time in 9 days

create barnchtmandry/rust

branch : rollup-nwntt3q

created branch time in 9 days

PR opened rust-lang/rust

Rollup of 16 pull requests

Successful merges:

  • #75026 (Add array_windows fn)
  • #76642 (Do not lint ignored private doc tests)
  • #76719 (Change error message for ty param in const)
  • #76721 (Use intra-doc links in core::mem)
  • #76728 (Add a comment why extern crate is necessary for rustdoc)
  • #76735 (Remove unnecessary clone()s in bootstrap)
  • #76741 (Avoid printing dry run timings)
  • #76747 (Add missing code examples in libcore)
  • #76756 (fix a couple of stylistic clippy warnings)
  • #76758 ([fuchsia] Propagate the userspace UTC clock)
  • #76759 (Fix stabilization marker for future_readiness_fns)
  • #76760 (don't lazily evaluate some trivial values for Option::None replacements (clippy::unnecessary_lazy_evaluations))
  • #76764 (Update books)
  • #76775 (Strip a single leading tab when rendering dataflow diffs)
  • #76778 (Simplify iter fuse struct doc)
  • #76794 (Make graphviz font configurable)

Failed merges:

r? @ghost

+450 -164

0 comment

54 changed files

pr created time in 9 days

push eventtmandry/rust

Rich Kadel

commit sha 5c29332ace48d8c34ad415ffcdce2641526938b8

Make graphviz font configurable Alternative to PR ##76776. To change the graphviz output to use an alternative `fontname` value, add a command line option like: `rustc --graphviz-font=monospace`.

view details

Rich Kadel

commit sha 3875abe32f6b98449bf2ec99ed210b7b77953703

Added RUSTC_GRAPHVIZ_FONT environment variable Overrides the debugging_opts.graphviz_font setting.

view details

Tyler Mandry

commit sha 3bf66ae25f6f84d22e39ac05b4f3623b08132805

Rollup merge of #76794 - richkadel:graphviz-font, r=ecstatic-morse Make graphviz font configurable Alternative to PR #76776. To change the graphviz output to use an alternative `fontname` value, add a command line option like: `rustc --graphviz-font=monospace`. r? @ecstatic-morse

view details

push time in 9 days

push eventtmandry/rust

Ivan Tham

commit sha 1dc4f8560f70500dc07c548094d8b5abd88c6130

Simplify iter fuse struct doc

view details

Tyler Mandry

commit sha d3c63213a045712fc653427a261b2441e931f3c0

Rollup merge of #76778 - pickfire:patch-7, r=jonas-schievink Simplify iter fuse struct doc

view details

push time in 9 days

push eventtmandry/rust

Dylan MacKenzie

commit sha c910e038e844628b5a1fcf0e892eb88dd819ce47

Strip a single leading tab when rendering dataflow diffs

view details

Tyler Mandry

commit sha cd766c9d0961ccc0a8254375a5b93b530dab14d0

Rollup merge of #76775 - ecstatic-morse:dataflow-extra-tab-diff, r=Mark-Simulacrum Strip a single leading tab when rendering dataflow diffs The `fmt_diff_with` formatter uses a tab to separate additions from subtractions. Strip it when rendering those diffs on separate lines. r? @Mark-Simulacrum (since you're speedy)

view details

push time in 9 days

push eventtmandry/rust

Eric Huss

commit sha e0c1621a3f687f30a372be5308cda4c8e261c768

Update books

view details

Tyler Mandry

commit sha 5d8bc9071568524b29f64a97ac691dd9a92d4686

Rollup merge of #76764 - ehuss:update-books, r=ehuss Update books ## nomicon 1 commits in 25854752549d44d76fbd7650e17cb4f167a0b8fb..6e57e64501f61873ab80cb78a07180a22751a5d6 2020-08-19 16:41:48 -0400 to 2020-09-14 11:40:23 -0400 - Fix API change to alloc::Global::grow. (rust-lang-nursery/nomicon#236) ## reference 3 commits in 25391dba46262f882fa846beefaff54a966a8fa5..56a13c082ee90736c08d6abdcd90462517b703d3 2020-09-02 07:22:55 -0700 to 2020-09-14 23:20:16 -0700 - Update the description of staticlib (rust-lang-nursery/reference#884) - Rust 1.46 now allows more features in const fn (rust-lang-nursery/reference#883) - Document the enum changes in RFC 2195 (rust-lang-nursery/reference#879) ## book 1 commits in e5ed97128302d5fa45dbac0e64426bc7649a558c..cb28dee95e5e50b793e6ba9291c5d1568d3ad72e 2020-08-31 12:53:40 -0500 to 2020-09-09 10:06:00 -0500 - Fixed the error message of invalid array element access in ch03.2 (rust-lang/book#2446)

view details

push time in 9 days

push eventtmandry/rust

Matthias Krüger

commit sha fd9be8f7aadb729e6c37c71419b43fc4d3c188f9

don't lazily evaulate some trivial values for Option::None replacements (clippy::unnecessary_lazy_evaluations)

view details

Tyler Mandry

commit sha 6e0131cd5b8867e7c7363ed85ef4ce6a10dc511f

Rollup merge of #76760 - matthiaskrgr:clippy_lazy_eval, r=varkor don't lazily evaluate some trivial values for Option::None replacements (clippy::unnecessary_lazy_evaluations)

view details

push time in 9 days

push eventtmandry/rust

Yoshua Wuyts

commit sha 143e4e975b1465f0380985d3e5597c22a6c5ee58

Fix stabilization marker for future_readiness_fns Moved it from 1.47.0 -> 1.48.0, which is the correct release for this to stabilize in

view details

Tyler Mandry

commit sha 273267c9ee16e72133d6548aac20997153cbdd81

Rollup merge of #76759 - yoshuawuyts:fix-future-pending-ready-stabilization-label, r=Dylan-DPC Fix stabilization marker for future_readiness_fns Updated the rustc version in which this will be stabilized from `1.47.0 -> 1.48.0`. Fixes https://github.com/rust-lang/rust/pull/74328#issuecomment-692133125. Ref #70921. r? @Dylan-DPC

view details

push time in 9 days

push eventtmandry/rust

Adam Lesinski

commit sha fafb2e9de717c40b95e52889bb641b32c1dc6a1e

[fuchsia] Propagate the userspace UTC clock On Fuchsia, spawning a subprocess does not automatically clone all of the parent process' capabilities. UTC time on Fuchsia is managed by a top-level userspace clock capability that is cloned and passed to subprocesses. This change ensures that any Rust subprocess gets access to the UTC clock, if the parent had access to it. This is critical for tests, which on Fuchsia, use panic=abort and spawn subprocesses per test.

view details

Tyler Mandry

commit sha ab207743aff648455687708a4cd66cf4c7132983

Rollup merge of #76758 - adamlesinski:clone_clock, r=tmandry [fuchsia] Propagate the userspace UTC clock On Fuchsia, spawning a subprocess does not automatically clone all of the parent process' capabilities. UTC time on Fuchsia is managed by a top-level userspace clock capability that is cloned and passed to subprocesses. This change ensures that any Rust subprocess gets access to the UTC clock, if the parent had access to it. This is critical for tests, which on Fuchsia, use panic=abort and spawn subprocesses per test.

view details

push time in 9 days

push eventtmandry/rust

Matthias Krüger

commit sha 73d4171ea6cb07b9426b386041b19376606db079

fix a couple of stylistic clippy warnings namely: clippy::redundant_pattern_matching clippy::redundant_pattern clippy::search_is_some clippy::filter_next clippy::into_iter_on_ref clippy::clone_on_copy clippy::needless_return

view details

Tyler Mandry

commit sha a6c4d30c7b42957873d2ff19b5405edc071e8bb5

Rollup merge of #76756 - matthiaskrgr:cl123ppy, r=Dylan-DPC fix a couple of stylistic clippy warnings namely: clippy::redundant_pattern_matching clippy::redundant_pattern clippy::search_is_some clippy::filter_next clippy::into_iter_on_ref clippy::clone_on_copy clippy::needless_return

view details

push time in 9 days

push eventtmandry/rust

Guillaume Gomez

commit sha 2a5a6b42ecf99b198eae89e13053b00bd1582a27

Add missing code examples in libcore

view details

Tyler Mandry

commit sha ab78ca92f3d7fa27e489c5cee15f60714702abb9

Rollup merge of #76747 - GuillaumeGomez:more-missing-libcore-code-examples, r=Mark-Simulacrum Add missing code examples in libcore

view details

push time in 9 days

push eventtmandry/rust

Mark Rousskov

commit sha 5f3145febd4e0e8ff28bfeec0418ece7f832428a

Avoid printing dry run timings

view details

Tyler Mandry

commit sha 233937419a0ed5ae602188a60e7ce187b6faaec9

Rollup merge of #76741 - Mark-Simulacrum:no-dry-run-timing, r=alexcrichton Avoid printing dry run timings This avoids a wall of text on CI with 0.000 as the likely time. r? @alexcrichton

view details

push time in 9 days

more