Question: COPY host-x86_64/dist-x86_64-linux/build-binutils.sh /tmp/ RUN ./build-binutils.sh <del> # libssh2 (a dependency of Cargo) requires cmake 2.8.11 or higher but CentOS # only has 2.6.4, so build our own COPY host-x86_64/dist-x86_64-linux/build-cmake.sh /tmp/ RUN ./build-cmake.sh # Need a newer version of gcc than centos has to compile LLVM nowadays </del> <ins> # Need at least GCC 5.1 to compile LLVM nowadays </ins> COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/ <del> RUN ./build-gcc.sh </del> <ins> RUN ./build-gcc.sh && apt-get remove -y gcc g++ </ins> <del> # CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+ </del> <ins> # Debian 6 has Python 2.6 by default, but LLVM needs 2.7+ </ins> COPY host-x86_64/dist-x86_64-linux/build-python.sh /tmp/ RUN ./build-python.sh <del> # Now build LLVM+Clang 7, afterwards configuring further compilations to use the </del> <ins> # LLVM needs cmake 3.4.3 or higher, and is planning to raise to 3.13.4. COPY host-x86_64/dist-x86_64-linux/build-cmake.sh /tmp/ RUN ./build-cmake.sh # Now build LLVM+Clang, afterwards configuring further compilations to use the </ins> # clang/clang++ compilers. <del> COPY host-x86_64/dist-x86_64-linux/build-clang.sh host-x86_64/dist-x86_64-linux/llvm-project-centos.patch /tmp/ </del> <ins> COPY host-x86_64/dist-x86_64-linux/build-clang.sh /tmp/ </ins> RUN ./build-clang.sh ENV CC=clang CXX=clang++ <del> # Apparently CentOS 5.5 desn't have `git` in yum, but we're gonna need it for # cloning, so download and build it here. COPY host-x86_64/dist-x86_64-linux/build-git.sh /tmp/ RUN ./build-git.sh # for sanitizers, we need kernel headers files newer than the ones CentOS ships # with so we install newer ones here COPY host-x86_64/dist-x86_64-linux/build-headers.sh /tmp/ RUN ./build-headers.sh # OpenSSL requires a more recent version of perl # with so we install newer ones here COPY host-x86_64/dist-x86_64-linux/build-perl.sh /tmp/ RUN ./build-perl.sh </del> COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh

EDIT: For our use case in , we were able to add compatibility for RHEL 5 .
See for a recent case where supporting such ancient kernels required extra manual work ( to the 2 lines mentioned by above). I am not sure how often that comes up, but probably the hardest part is to even notice that it happens -- and even then those codepaths will likely linger untested.
Yes, but this will still be true in general. If the CI kernel is newer than whatever kernel baseline we choose, it will be possible for newer syscalls to pass undetected. I don't know if we have any control over that -- can we choose a particular VM image? So that leaves us with a stated policy of support. The more that developers are aware of such issues, the better, but I'm the one most likely to notice when my build actually fails. If I come back with a fix, I at least need the project to be receptive. I haven't been in the habit of building nightly on our RHEL6 builders, but maybe I should! Catching this early is better for everyone involved...
That seems reasonable. How quick is the Rust related bootstrapping? Could it be run automatically (or more frequently)? This is an interesting point. If I hadn't made that change, would have kept working on RHEL 5, it just would have leaked an FD. I'm not sure how we would even test for this sort of thing. This isn't a RHEL 5 specific concern, I just don't know how Rust tests these types of resource leak issues in general.
About 2 hours. Automation is harder, since I believe our build system needs my credentials, but I'll look into what is possible here. Yeah, that's a lot more subtle than an !


Question: LL | fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: Debug { |                                                            ^^^^^^^^^^ <del> error: aborting due to 6 previous errors </del> <ins> error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:44:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Foo<T>: Sized { |             ^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:49:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Bar: std::fmt::Display + Sized { |                              ^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:54:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Baz: Sized where Self: std::fmt::Display { |          ^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:59:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Qux<T>: Sized where Self: std::fmt::Display { |             ^^^^^^^ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:64:46 | LL |     const SIZE: usize = core::mem::size_of::<Self>(); |                                              ^^^^ doesn't have a size known at compile-time | ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { |                      - required by this bound in `std::mem::size_of` | help: consider further restricting `Self` | LL | trait Bat<T>: std::fmt::Display + Sized { |                                 ^^^^^^^ error: aborting due to 11 previous errors </ins> For more information about this error, try `rustc --explain E0277`.

The following code errors, and the error contains a suggestion how to fix the error: The error message states: Obviously, writing is invalid syntax.
It seems the issue is that it's inserting the suggestion after the trait name and before the generics, rather than after the generics.
No-nightly-features code that exhibits the same problem: label -requires-nightly (should the F-labels go as well?)


Question: // EMIT_MIR casts.roundtrip.InstSimplify.diff pub fn roundtrip(x: *const u8) -> *const u8 { // CHECK-LABEL: fn roundtrip( <del> // CHECK: _3 = _1; // CHECK: _2 = move _3 as *mut u8 (PtrToPtr); // CHECK: _0 = move _2 as *const u8 (PointerCoercion(MutToConstPointer)); </del> <ins> // CHECK: _4 = _1; // CHECK: _3 = move _4 as *mut u8 (PtrToPtr); // CHECK: _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer)); </ins> x as *mut u8 as *const u8 }

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: . I expected to see this happen: it compiles, since raw pointer casts should be allowed even for completely different types. Instead, this happened: it fails with: It looks like for some reason the compiler creates a lifetime obligation here. Strangely, it works with : .
I've looked into this. The issue is that typeck considers this cast to be a "coercion cast", because typeck thinks that you could replace the function body with just since the types are the same (it also triggers the lint (allow-by-default)). HIR typeck isn't aware of lifetimes. So then THIR building and MIR building build MIR that doesn't contain a cast but instead just assigns one to the other. The borrow checker is rightfully not pleased. The bug here is that the THIR does not contain an explicit cast anymore. I'm not sure how to best fix this, as the current logic for "is this a no-op cast (called coercion cast in the code)" is just "try to coerce the types in the same way that happens on coercion sites and if it works it has to be useless". Which is wrong in the presence of lifetimes. It seems like the current strategy works this way because it reuses some code in THIR building. Thinking about it a little more, this is very special to pointer casts, because only pointer casts are allowed to change the type like this. Maybe THIR building should just special case pointer casts to always be emitted?
Unfortunately due to this bug there is that should be turned into a raw pointer cast, but we cannot.
I think that's a different case, these are boxes and not raw pointers, and box-box casts are not allowed to do arbitrary changes (and are in fact coercion casts, so the doesn't actually do anything). The error there is correct and this needs a transmute.
I'd like to replace the transmutes by raw pointer casts, which IMO is much preferable, similar to But this bug is in the way of that.


Question: .suggestion = convert it to a `{$msg_code}` hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` <ins> hir_analysis_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` hir_analysis_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function </ins>

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should something like this: label +D-confusing +D-invalid-suggestion <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. The output might also be different depending on the Edition. --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim


Question: if instance.def.is_inline(cx.tcx) { attributes::inline(lldecl, attributes::InlineAttr::Hint); } <del> attributes::from_fn_attrs(cx, lldecl, instance.def.def_id()); </del> <ins> attributes::from_fn_attrs(cx, lldecl, Some(instance.def.def_id())); </ins> cx.instances.borrow_mut().insert(instance, lldecl); }

and are both broken on s390x since Rust 1.28. When is built without debuginfo, the tests hang with their backtracing processes stuck in a loop. With debuginfo, it fails with output like: I believe the problem is this part of : where doesn't identify that is a 64-bit platform. See also alexcrichton/backtrace-rs. I plan to update that here when it's published, and make a similar fix in .
fixes the backtrace when is built with debuginfo, but I'm still getting a hang without. In GDB, it looks like the unwinder gets to the that catches panics, then loops unwinding that same PC forever. This part of the regression is older -- happens on 1.27.2 as well, but 1.26.2 is fine. Binaries from the older version don't appear to have a distinct symbol at all, but maybe that's just inlined differently. I'm bisecting for that hang now.
Bisecting pointed me at (cc which attributes to all functions. For s390x the base features actually include a removal, . But it doesn't look like the features are applied to the synthesized (), and as a result it doesn't get inlined anymore since it has more features (w/ ) than the callee. We probably should apply target-features to as well. I don't know why the non-inlined can't be unwound -- maybe we need to force ? By default GDB backtrace stops at crate , but tries to go further: Maybe Rust's could have a similar defensive check, at least.
Nice find Definitely makes sense to me, and this should be fixed up (at least the business) in
With , , and , I believe we have this fixed.


Question: <ins> error: attribute must be of the form `#[deprecated]` or `#[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason)]` or `#[deprecated = "reason"]` --> $DIR/invalid-literal.rs:1:1 | LL | #[deprecated = b"test"] //~ ERROR attribute must be of the form | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>

Look for example to It is deprecated, and in source code there is hint what should be used instead: but in generated html documentation there is no hint about
isn't the correct syntax for the attribute. It should be . You can see it work: . This isn't a rustdoc issue. It's an issue with rustc that it doesn't reject .


Question: } #[test] <ins> #[allow(deprecated)] </ins> fn stream_smoke_test_ip6() { let server_ip = next_test_ip6(); let client_ip = next_test_ip6();

change this to something more appropriate. This was introduced in commit when still returned . This should either block until a message from the correct sender arrives or return an error.


Question: use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::fingerprint::Fingerprint; <del> use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; </del> <ins> use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; </ins> use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr;

The resolver gathers a list of possibly unused trait imports in . This list is passed to resolver outputs, into the query. This query takes a and returns whether the import is possibly unused. This is used by the post-typeck unused import check in . This query iterates over all the statements in the crate, checks whether they may be unused trait imports, and warns if they are indeed unused. As there are typically very few unused trait imports compared to the number of items in a crate, it would make sense to directly iterate on . Steps: make an both in and , this will ensure a deterministic iteration order; rename query and give it the signature , and adapt the call site; we do not want to access directly, as this would prevent the query system from detecting that the set has not changed; in , inline and replace the loop over by a loop over ; the filter over there can be removed too (or replaced by a debug-assertion): the set may only point to use statements. Extra: investigate why we check for , and the consequences of removing that check; investigate the impact on perf of converting the to a simple when producing from . I am available on Zulip for any question. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
claim
are you still working on this?
Hello yes sorry for the super slow pace. I am still working on it (mostly reading the rustc dev guide so far). Is that alright or is it important to get this done quickly?
no worries, I am a beginner looking for tasks, hence the qn.


Question: /// any methods, but instead is used to gate access to data. /// /// FIXME. Better documentation needed here! <del> pub trait MarkerTrait : PhantomFn<Self> { } </del> <ins> pub trait MarkerTrait : PhantomFn<Self,Self> { } //                                    ~~~~~ <-- FIXME(#22806)? // // Marker trait has been made invariant so as to avoid inf recursion, // but we should ideally solve the underlying problem. That's a bit // complicated. </ins> impl<T:?Sized> MarkerTrait for T { } /// `PhantomFn` is a marker trait for use with traits that contain

EDIT: Removed talk of variance, since it doesn't seem to be the cause and it was unnecessarily longer due to it. It seems to me like is an attempt to introduce the second approach from the of RFC 738. It seems to me that the commit is actually a breaking change, because it broke my code without my changing it. Consider this reduced example (thanks to for helping me to reduce it further). This overflows on the recursive requirement evaluation: I attempted to bump the recursion limit to 2046 even and it just told me to try again with 4096, so I figure it's just going to infinitely recurse if allowed. This only seems to happen if I use a reference, so I think that has something to do with it. came up with an example that actually hangs rustc completely when using a recursive type: The real-world scenario that led me to this bug was a with keys:
cc
My suspicion (which I removed from the first post because I'm not quite sure if it's the reason) is that it has to do with variance. Creating my own similar to the one in rust but with a instead of a , OR with instead of seemed to solve the issue, but again I'm not sure if that's the reason. I figured it was because is ok to have as a covariant but must be an invariant, from my limited understanding of variance.
(More) reduced test case (reduced in that it's isolated from the stdlib): there is in fact an interaction with variance. The problem is that the "infinite cycle" detection doesn't seem to be kicking in here because an endless set of new region variables are being generated. This is probably due to the variance of . I have to think on this a second.
(Er, the variance of various things. :)
So I've kind of thought this through. I think the right fix is to enhance the trait matching system to understand that there is in fact no need to keep generating new constraints. This seems to be a bit complicated (it interacts with, among other things, ). The short-term pragmatic fix is probably to modify MarkerTrait to be invariant, not contravariant. This is stricter than necessary but probably not terrible. The implication is that if one knows that e.g. holds, that alone would not be enough to conclude that .


Question: /// any methods, but instead is used to gate access to data. /// /// FIXME. Better documentation needed here! <del> pub trait MarkerTrait : PhantomFn<Self> { } </del> <ins> pub trait MarkerTrait : PhantomFn<Self,Self> { } //                                    ~~~~~ <-- FIXME(#22806)? // // Marker trait has been made invariant so as to avoid inf recursion, // but we should ideally solve the underlying problem. That's a bit // complicated. </ins> impl<T:?Sized> MarkerTrait for T { } /// `PhantomFn` is a marker trait for use with traits that contain

It is probably possible for us to loosen this in the future, even after 1.0, though strictly speaking it would not be backwards compatible. (I guess a more limited fix would just be to change the variance of and specifically.) (The reason it is not 100% backwards compat is because impls that are not overlapping for an invariant trait can overlap for a contravariant trait; but this is unlikely to occur except for with object types.)
I plan to work around this problem for now by changing the definition of . The underlying issue has been splintered off into .


Question: /// Parses an enum declaration. fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> { <ins> if self.token.is_keyword(kw::Struct) { let mut err = self.struct_span_err( self.prev_token.span.to(self.token.span), "`enum` and `struct` are mutually exclusive", ); err.span_suggestion( self.prev_token.span.to(self.token.span), "replace `enum struct` with", "enum", Applicability::MachineApplicable, ); if self.look_ahead(1, |t| t.is_ident()) { self.bump(); err.emit(); } else { return Err(err); } } </ins> let id = self.parse_ident()?; let mut generics = self.parse_generics()?; generics.where_clause = self.parse_where_clause()?;

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: <!-- Please provide a link to --The current output is: <!-- The following is not always necessary. --Ideally the output should look like: Highlight to the user that the keywords and are mutually exclusive. Replace with . <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. The output might also be different depending on the Edition. --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim


Question: <del> use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; </del> <ins> use core::task::{Poll, RawWaker, RawWakerVTable, Waker}; </ins> #[test] fn poll_const() {

One issue that came up in the discussion is that the type implements . This might have been introduced accidentally. probably does not matter at all, given that users will only observe a by reference. However has the impliciation that we will not be able to add non thread-safe methods to - e.g. in order to optimize thread-local wake-ups again. It might be interesting to see whether and support could be removed from the type. Unfortunately that is however a breaking change - even though it is not likely that any code currently uses out of the direct path. In a similar fashion it had been observed in the implementation of () that the type is also and . While it had been expected for - given that s are used to wake-up tasks from different threads, it might not have been for . One downside of s being is that it prevents optimizations. E.g. in linked ticket the original implementation contained an optimization that while a was not d (and thereby equipped with a different vtable) it could wake-up the local eventloop again by just setting a non-synchronized boolean flag in the current thread. However given that could be transferred to another thread, and called from there even within the context - this optmization is invalid. Here it would also be interesting if the requirement could be removed. I expect the amount of real-world usages to be in the same ballpark as sending across threads - hopefully 0. But it's again a breaking change cc , , ,
Even if this weren't a breaking change, I'd want to see some really good evidence these optimizations would matter for real world code before choosing to make these types non-. I don't think getting rid of an atomic update in is a compelling example. Basically, in my view the current API is intentional and correct.
was introduced to leave room for future unforeseen requirements, and being restricts its usefulness as such, which is unfortunate. I can see a case for since we have , but it's difficult to imagine a case where it makes sense to be accessing a single from multiple threads concurrently.
I have an example of where the current API is resulting in performance issues: I am trying to implement a combined Executor/Reactor around a winit event loop. To wake up the event loop from a different thread we have to post a message to the event loop which can be a non-trivial operation.


Question: <del> use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; </del> <ins> use core::task::{Poll, RawWaker, RawWakerVTable, Waker}; </ins> #[test] fn poll_const() {

But on the same thread, we know that we don't need to wake up the eventloop, so we can use much cheaper mechanisms like an atomic bool.
But that would be true if wakers were just also, which was an intentional part of the simplification from the previous design.
I think the point is that being precludes the otherwise noninvasive restoration of a more efficient through an additional method on .
I don't think it should be the judgement of the libs team (or any of us) to determine whether something is good enough and not needs to be further optimized for any use-case. Rusts goal as a language is to enable zero cost abstractions. This requires in my opinion to not be opinionated on any design choices which have a performance/footprint impact. I think some of the decisions that have been taken in the async/await world however are opinionated, and will have an impact on use-cases that currently are still better implemented with different mechanisms. I do not really want to elaborate on anything more particular, because I fear this would bring the discussion back to a arguing whether any X% performance degradation is still good enough. That is an OK decision to have for a software project whichs needs to decide whether Rusts async/await support is good enough for them, and whether they have to apply workarounds or not. But it's not a discussion which will move the issue here any more forward, because for yet another project the outcoming of the discussion might be different. PS: I do think it's okay and good if libraries like tokio or async-std are being more opinionated about what threading models they support, and they might sacrifice performance gains in rare usage scenarios for easy of use. But and language features are different, and we expect people to use them also for niche use-cases (e.g. there is certainly a lot of cool evaluation going on with the use of async/await in embedded contexts or kernels - where requirements might be very different than for a webserver based on tokio).
This is a trade off: Context is either Sync or it isn't, some users benefit from one choice (they can use references to Context as threadsafe) and some users benefit from the other choice (they can have nonthreadsafe constructs inside the Context construct).


Question: <del> use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; </del> <ins> use core::task::{Poll, RawWaker, RawWakerVTable, Waker}; </ins> #[test] fn poll_const() {

Ultimately the libs team has to decide one way or the other on these points in the API where there is a trade off between thread safety and not. However, this decision has already been made and it would be a breaking change to change it, so this discussion is moot.
Do you have an example where this is actually done within the ecosystem, or a use-case for it? As far as I can tell, this would require spawning a thread using something like and capturing the from within a ?
A common way a user could depend on a type being is to store it in an and send it across threads. This isn't very likely for Context but it is a very reasonable pattern for .
I think its a fair point that we didnt intentionally make context send and sync, and that this precludes adding more fields to context that are not send and sync, and that since context is just a buffer for future changes, it would probably have been better to make it non-threadsafe. But now its a breaking change. If crater showed no regressions and there's no known patterns it nullifies, I would be open to changing this about Context personally, but I am somewhat doubtful the libs team as a whole would approve making a breaking change to support hypothetical future extensions. If anyone on the thread wants to pursue a change to context (not waker), they should get crater results as the next step of the conversation.
There is no discussion about being or not - it obviously has to be. The question is purely about . And in order to do what you describe you have to store an and send it somewhere. Which is very doubtful to happen, due to the not very useful lifetime and due to already being an like thing internally. As mentioned, the most likely way to see this behavior is some scoped thread API being used inside - or people doing some very advanced synchronization against an IO driver running in another thread. For all those there are certainly better ways than to rely on being . E.g. to return a flag from the synchronized section and call from the original thread when done. Or to and send the if there is doubt whether it needs to be persisted somewhere else. And yes, the impact on is even bigger. It was meant as an extension point. But we can not add any functions to it which are not thread-safe. E.g.


Question: <del> use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; </del> <ins> use core::task::{Poll, RawWaker, RawWakerVTable, Waker}; </ins> #[test] fn poll_const() {

if we want to add methods which spawn another task on the same thread as the current executor thread, and which allows for spawning futures (like Tokios ) - we would have an issue.
Why would these be "certainly better" than just calling from the scoped threads?
To be a little more expansive: the scoped threadpool you're talking about could very well not be scoped inside a poll method - rather, the waker could be cloned once and then owned by one thread and referenced by many other scoped threads in some sort of threadpool construct for CPU bound tasks. This seems like a perfectly valid implementation which allows you to divide up the work among many threads without cloning the waker many times. This is potentially an optimization. I don't think this optimization is very important, but I don't think the optimizations allowed by making waker are very important either. The point is that there's a trade off between the optimizations allowed by assuming references to wakers can be shared across threads and the optimizations allowed by assuming they can't be, its not the case that one side is inherently the "zero cost" side.
We discussed this at the recent Libs meeting and felt that deferring to would make sense here.
Though I don't have the bandwidth to carry this, this definitely seems interesting. Seeing projects such as and closed-source initiatives lead me to believe that there may actually be a decent case to enable some form of -to avoid the synchronization overhead on single-threaded runtimes. I don't know if we should make this a priority, but at least we probably shouldn't close it just yet.
I think bringing back would be a nice additional improvement. But for the moment it would be nice to just fix the general sync-ness, which blocks all other fixes and improvements.
As the person who originally introduced , it was very much a conscious decision to get rid of it and to make and . This was called out explicitly .
The cited discussion in the RFC justifies making Send, and predates the decision to (re)introduce . Making doesn't defeat the objectives discussed there. In particular, it does not impact ergonomics for the common case at all.
This was recently closed, however the issue mentions both and . The recent change only affects . There is good reason that is , however after reading this issue I'm unsure that there are good reasons why is .


Question: <del> use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; </del> <ins> use core::task::{Poll, RawWaker, RawWakerVTable, Waker}; </ins> #[test] fn poll_const() {

(NOT A CONTRIBUTION) Waker supports wakebyref, and so it is possible to pass to another thread and wake it from that thread. This functionality would not be possible without Waker being Sync. Supporting wakers that are either not Send or not Sync will best be done by adding new APIs to Context and a new LocalWaker type.
Forgive me the naive question, but how does a type work with ? As I understand, requires , as a concrete type not a trait, so this would also require a trait? At this point we have two completely incompatible async systems... Which is only useful if is not cheap to clone, and has the burden of another lifetime bound. It surprises me that the docs don't say anything about the intended cost of .
(NOT A CONTRIBUTION) Future::poll does not take Waker as an argument, Future::poll takes Context. Context could have the ability to set a LocalWaker, so that an executor could set this. Reactors which operate on the same thread as the future that polls them could migrate to using the LocalWaker argument instead of Waker. Here is a pre-RFC that someone wrote with a possible API: Commentary like this is both factually wrong and not helpful for the mood of the thread.


Question: f.debug_tuple("Drain") .field(&self.after_tail) .field(&self.after_head) <del> .field(&self.iter) </del> <ins> .field(&self.ring) .field(&self.tail) .field(&self.head) </ins> .finish() } }

liballoc's fails when run in Miri. The error occurs in the call: is called with a as argument. contains contains a shared reference to a slice; that slice is thus marked as "must not be mutated for the entire duration of this function call". calls calls calls calls , which eventually drops the . calls to re-arrange stuff (I have not fully understood this yet), and in some cases this will end up writing to memory that the slice in points to. I am not sure what the best way to fix this is. We have to fix holding (indirectly) a shared reference to something that it'll mutate during its . The mutation is likely there for a reason, so I guess the shared reference has to go. (FWIW, this shared reference already caused other trouble, but that was fixed by ) Cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
yeah I guess just change it to and toss in a PhantomData for the borrow. shrug
You mean, change this in as well? Sure, that should work. In principle this reduces the precision of compiler analyses on .
ahh misread. maybe would just not use Iter then. depends on what the impl looks like now
But the first thing it does is which should exhaust the such that its is an empty slice. I suppose its pointer will still be somewhere in the deque's memory, but with length 0 it can't actually read anything. Is that not good enough to appease Miri?
No. This code still matches the pattern There is no notion of "exhausting" or "consuming" a shared reference. When you create a shared reference with a certain lifetime, you promise that until that lifetime ends, no mutation happens. here is mutable so you can change what the slice points to, but that has no effect at all on the guarantees that have been made about the value that was initially passed to . Now, lifetimes are an entirely static concept, so for Stacked Borrows a "lifetime" generally is "until the pointer is used for the last time".


Question: f.debug_tuple("Drain") .field(&self.after_tail) .field(&self.after_head) <del> .field(&self.iter) </del> <ins> .field(&self.ring) .field(&self.tail) .field(&self.head) </ins> .finish() } }

However, for the special case of a reference being passed to a function, Stacked Borrows asserts that the "lifetime" will last at least as long as the function the reference is pointed to. (This is enforced by the "barriers" explained .) This is extremely useful for optimizations.
forward to . I wouldn't want to copy those.
Oh, I also didn't realize that doesn't actually shrink down to an empty slice -- it only updates its indexes. It would otherwise have to use two slices for the wrapped head and tail. So that full shared reference does still exist after the iterator is exhausted. (This also raises the validity question of having references to uninitialized data.) Could we base on instead? We could arrange to work through that mutable reference too, so there's no question of mutable aliasing.
That might work. However, must not access in that case -- that would be in conflict with the unique reference in .
Hmm, does need to be covariant over ? I guess would break that.
Actually this idea of "consuming a shared ref" is far from unique to ... the following code also errors in Miri:
As I understand it, Miri and stacked borrows should be "more powerful" than the Rust borrow checker, right? So, is this an example where Miri does not match what Rust allows or is this a bug in Rust that could lead to undefined behaviour in safe code? ()
-- I believe is admitting that example as something that should be allowed. But this issue with involves raw pointers, which rustc doesn't check at all, so miri is in uncharted waters here.
This is up for us all to decide. I can't tell you. ;) Not necessary. I have argued that / are problematic long before Stacked Borrows. The lifetimes there are, strictly speaking, wrong. I think it would be reasonable to rule that they have to use raw pointers.
FWIW here is a stand-alone version of the testcase to reproduce this with Miri (but it needs access to some private internals):
See for the issue about whether Stacked Borrows should allow such code or not. For now, with , Miri accepts this code again. So I am going to close the issue here. It still represents an interesting data point to inform what Stacked Borrows rules should be.


Question: f.debug_tuple("Drain") .field(&self.after_tail) .field(&self.after_head) <del> .field(&self.iter) </del> <ins> .field(&self.ring) .field(&self.tail) .field(&self.head) </ins> .finish() } }

nods wisely just gotta stand still long enough for the spec to bend around you
;-) I don't think the decision is made either way, but for now with several counterexamples in libstd, it is not helpful for Miri to complain about this. Plus, this matches what we formalized in Coq; the basic optimizations that we considered so far are all fine with this change.
See there actually is a bug here right now, because we do emit for passed to a function. So what Miri found is actually UB in the LLVM IR that we are generating right now. Reopening for now, but maybe it makes more sense to treat this as a duplicate of
Smaller reproduction that I found in (a now closed dupe of this issue) that doesn't rely on VecDeque internals, that fails now with
re-enables the part of Stacked Borrows that got disabled (in parts) to work around the issue, before I knew that we actually have here and are risking real miscompilations.
claim


Question: <ins> error: index out of bounds: the len is 3 but the index is 4 --> $DIR/array-literal-index-oob.rs:2:7 | LL |     &{[1, 2, 3][4]}; |       ^^^^^^^^^^^^ | = note: #[deny(const_err)] on by default error: this expression will panic at runtime --> $DIR/array-literal-index-oob.rs:2:5 | LL |     &{[1, 2, 3][4]}; |     ^^^^^^^^^^^^^^^ index out of bounds: the len is 3 but the index is 4 error: reaching this expression at runtime will panic or abort --> $DIR/array-literal-index-oob.rs:2:7 | LL |     &{[1, 2, 3][4]}; |     --^^^^^^^^^^^^- |       | |       index out of bounds: the len is 3 but the index is 4 error: aborting due to 3 previous errors </ins>

Originally stumbled upon through the eval IRC bot: Here's the smallest reproduction I could get, Removing either the block or the borrow displays only a normal compiler error (not an ICE) trace
triage: P-high, assigned to ; removing I-nominated label


Question: crate_lint: CrateLint, ) -> PartialRes { tracing::debug!( <del> "smart_resolve_path_fragment(id={:?},qself={:?},path={:?}", </del> <ins> "smart_resolve_path_fragment(id={:?}, qself={:?}, path={:?})", </ins> id, qself, path

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --I tried to call default trait implementation from overriden method. Googling was not so useful as wanted so I started playing with "super" keyword and found this bug. Bug appears both on stable and nightly <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Bisected:
Relevant code: In case it helps, the merges in nightly-2020-06-05 were , , , , , and . Playground:
Error from just before the regression was introduced (run with ):
Assigning and removing as ) in the prioritization working group.
claim


Question: } } } <ins> #[allow(improper_ctypes)] mod unknown_layout { mod a { extern "C" { pub fn generic(l: Link<u32>); } pub struct Link<T> { pub item: T, pub next: *const Link<T>, } } mod b { extern "C" { pub fn generic(l: Link<u32>); } pub struct Link<T> { pub item: T, pub next: *const Link<T>, } } } </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
cc for ClashingExternDeclarations in backtrace.
claim
Thank you for fixing it! There is nothing better than software with only a few open issues.
Not a problem! Thank you for the report, and especially for taking the time to make a minimal example :)


Question: let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { let bounds = this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound { <del> GenericBound::Trait( ty, TraitBoundModifiers { polarity: BoundPolarity::Positive | BoundPolarity::Negative(_), constness, }, ) => Some(this.lower_poly_trait_ref(ty, itctx, *constness)), // We can safely ignore constness here, since AST validation // will take care of invalid modifier combinations. GenericBound::Trait( _, TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. }, ) => None, </del> <ins> // We can safely ignore constness here since AST validation // takes care of rejecting invalid modifier combinations and // const trait bounds in trait object types. GenericBound::Trait(ty, modifiers) => match modifiers.polarity { BoundPolarity::Positive | BoundPolarity::Negative(_) => { Some(this.lower_poly_trait_ref( ty, itctx, // Still, don't pass along the constness here; we don't want to // synthesize any host effect args, it'd only cause problems. ast::BoundConstness::Never, )) } BoundPolarity::Maybe(_) => None, }, </ins> GenericBound::Outlives(lifetime) => { if lifetime_bound.is_none() { lifetime_bound = Some(this.lower_lifetime(lifetime));

<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [fnsig] computing function signature of [collectmoditemtypes] collecting item types in top-level module [analysis] running analysis passes on this crate --
bisects to


Question: // list. let argv = ARGV.load(Ordering::Relaxed); let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) }; <del> (0..argc) .map(|i| { let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char); OsStringExt::from_vec(cstr.to_bytes().to_vec()) }) .collect() </del> <ins> let mut args = Vec::with_capacity(argc as usize); for i in 0..argc { let ptr = *argv.offset(i) as *const libc::c_char; // Some C commandline parsers (e.g. GLib and Qt) are replacing already // handled arguments in `argv` with `NULL` and move them to the end. That // means that `argc` might be bigger than the actual number of non-`NULL` // pointers in `argv` at this point. // // To handle this we simply stop iterating at the first `NULL` argument. // // `argv` is also guaranteed to be `NULL`-terminated so any non-`NULL` arguments // after the first `NULL` can safely be ignored. if ptr.is_null() { break; } let cstr = CStr::from_ptr(ptr); args.push(OsStringExt::from_vec(cstr.to_bytes().to_vec())); } args </ins> } } }

Currently in , Rust is hooking into the glibc extension for retrieving / even in case Rust does not manage and is e.g. just loaded into a process as a . While this is great and convenient, it's unfortunately not implemented in a safe way. Various C commandline argument parsers are modifying while parsing, so the information that gets passed into might not be correct anymore. Examples of such parsers are glibc's own  parser, noting " The default is to permute the contents of argv while scanning it so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. " GLib's  parser, which removes all already handled arguments from and only leaves others (removed ones are set to and moved to the end). Qt does the same thing in in . It shuffles around arguments in and removes (by setting to ) arguments it handled already. This means that at least can easily be too big, and Rust would read beyond the (new) end of . This caused crashes in because of calling on when creating an around such an "removed" argument. Now the question is how this should be handled in Rust. I see three options here Remove the extension usage and handle glibc like all other libcs Copy all arguments in . This means everybody has to pay for that even if they don't use arguments, and this is theoretically still not safe if the shared library is loaded at the same time the array is modified and a partially written pointer value is read Handle pointers in by skipping over them. This means we would lose the exact length information of the iterator, and this is still theoretically not safe for the same reason as 2. See This code was in 2019 by (CC I've created as a proposed fix for this, which implements option 3. : <details<summaryBacktrace</summary<pAlso </p</details
Arguably swapping two entries of is still a lot less dangerous than setting one to NULL -- it seems totally legitimate to assume that there are no NULL pointers in , and does not insert any NULL there either. So what GLib does here is certainly questionable, more so than what does. That would be a data race.


Question: // list. let argv = ARGV.load(Ordering::Relaxed); let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) }; <del> (0..argc) .map(|i| { let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char); OsStringExt::from_vec(cstr.to_bytes().to_vec()) }) .collect() </del> <ins> let mut args = Vec::with_capacity(argc as usize); for i in 0..argc { let ptr = *argv.offset(i) as *const libc::c_char; // Some C commandline parsers (e.g. GLib and Qt) are replacing already // handled arguments in `argv` with `NULL` and move them to the end. That // means that `argc` might be bigger than the actual number of non-`NULL` // pointers in `argv` at this point. // // To handle this we simply stop iterating at the first `NULL` argument. // // `argv` is also guaranteed to be `NULL`-terminated so any non-`NULL` arguments // after the first `NULL` can safely be ignored. if ptr.is_null() { break; } let cstr = CStr::from_ptr(ptr); args.push(OsStringExt::from_vec(cstr.to_bytes().to_vec())); } args </ins> } } }

However, just like multi-threaded programs cannot mutate the process environment or write to the global pointer ( is inherently unsafe if there are other threads; also see the discussion in ), I would argue that multi-threaded programs cannot mutate . Global state such as or is inherently read-only in a concurrent program; there is just no way to make mutation safe. So, I think for concurrent programs we can already assume that there are no concurrent mutations, and if there are then that is a bug in the code that performs the mutation. What remains is the question whether we should adjust the args handling to be able to deal with NULL pointers in .
The problem here is that this behaviour of GLib exists since literally decades, and I'm sure we'll find other commandline parsers that are doing similar things if we search a bit. My first reaction also was that this feels like something to fix in GLib, but that doesn't seem to be a practical resolution because of the above. Skipping over s seems to be a relatively cheap mitigation if we decide that concurrent modifications of are simply wrong (who even does that! also seems less likely than ).
I can't judge how common it is to add NULLs there, and don't have an opinion on whether we should support that -- let's see what says. If you know of another library doing this that could be useful, though GLib doing it for decades on its own already means this is quite wide-spread. I hope GLib does this before any threads are spawned, because otherwise I'm afraid that is just inherently doomed.
I'll search a bit later. An application could surely do that, but that's just asking for problems and I wouldn't really worry about that. The following would work around this FWIW. Maybe should be conditional on glibc.
nit: s/Same/Some
Qt does the same thing in in . It shuffles around arguments in and removes (by setting to ) arguments it handled already.
's library is not affected because it always copies each string directly into a vector and then operates on that.
Another approach would be parsing . Doesn't work if proc isn't available, but so do things like .
is created by the kernel reading from the original location of argv (as specified by the auxiliary vector). If you edit argv, so will the commandline reported by the kernel.


Question: // list. let argv = ARGV.load(Ordering::Relaxed); let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) }; <del> (0..argc) .map(|i| { let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char); OsStringExt::from_vec(cstr.to_bytes().to_vec()) }) .collect() </del> <ins> let mut args = Vec::with_capacity(argc as usize); for i in 0..argc { let ptr = *argv.offset(i) as *const libc::c_char; // Some C commandline parsers (e.g. GLib and Qt) are replacing already // handled arguments in `argv` with `NULL` and move them to the end. That // means that `argc` might be bigger than the actual number of non-`NULL` // pointers in `argv` at this point. // // To handle this we simply stop iterating at the first `NULL` argument. // // `argv` is also guaranteed to be `NULL`-terminated so any non-`NULL` arguments // after the first `NULL` can safely be ignored. if ptr.is_null() { break; } let cstr = CStr::from_ptr(ptr); args.push(OsStringExt::from_vec(cstr.to_bytes().to_vec())); } args </ins> } } }

Skipping over NULL seems less safe; would it make sense to just stop at the first NULL?
To the best of my knowledge, it's completely valid to parse argv by stopping at the first NULL; if an argument parser is replacing an argument with NULL, it should not expect that arguments after that point will be seen. I've seen plenty of C programs that just do or equivalent.
For the commandline parsers from GLib and Qt that would be sufficient, yes. Considering the below, it seems OK to do that and there shouldn't really be any risk of missing useful arguments. TIL that is -terminated. Thanks for pointing that out :)


Question: <ins> running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s </ins>

Hi, I've just published a new version of my crate and the generated documentation is including a lot of bullet points that have never been included before. When I generate the docs locally on the 1.8.1 source code using the latest stable version of rust I see the same formatting for the 1.8.0 that generated, so I think this is a bug that's slipped into the nightly version of Stable local docs: ! ! My guess is that it's because I'm using block comments, the unwanted bullet points seem to match up with empty lines in the documentation comment which consist of just a . Thanks
Seems potentially related to , but the latest builds were from a nightly that should have that fixed in; cc you probably have some idea on where the issue is.
This is highly surprising indeed. Can you run with the last nightly locally and tell us if it reproduces the bug please? If so, I'll try to check what's wrong in rustdoc.
I have ran cargo doc on the latest nightly locally (nightly-x86_64-unknown-linux-gnu rustc 1.60.0-nightly ( 2022-01-20)) and it has reproduced the bug - I see the same generated docs as from the build.
It'll be fixed by
Thanks, is there any way I can get to rebuild the docs for the affected versions or will I have to submit a new version of my library to get a fixed build?
Sure. But that for that, please open an issue on repository directly.


Question: pub use adt::*; pub use assoc::*; pub use generics::*; <del> use hir::OpaqueTyOrigin; </del> use rustc_ast as ast; use rustc_ast::node_id::NodeMap; use rustc_attr as attr;

Here is an example which uses a RPIT on a borrowed type in three different ways: IMO this is perfectly reasonable code and (EDIT: see below). On stable () we have the following: And on beta () and nightly () we get some additional errors: EDIT: On second thought, I guess the first error (on stable) is reasonable, since we are actually returning a in that case. If you either use in the body or in the return type then the error goes away. But the second error is still a regression. It most recently worked on: rustc 1.66.0 ( 2022-12-12) : modify labels: +regression-from-stable-to-beta -regression-untriaged
This is . Cc It is related to the invariance: Another case that doesn't rely on member constraints in the second function and yields a different error message: I also found a distantly related regression that doesn't require invariance. It looks like a missed subtyping opportunity:
Another version using TAIT: At this point there are two classes of regression: The first is related to the fact that and the the second requires more subtyping relations. label I-types-nominated T-types T-compiler
WG-prioritization assigning priority (). label -I-prioritize +P-critical
From beta crater: https://crater- https://crater- https://crater- https://crater- https://crater-
unnominating as it will get fixed by which is approved again. Have to try to get this into beta though, only have 1 more day for that


Question: } /// Derive macro generating impls of traits related to smart pointers. <del> #[rustc_builtin_macro] </del> <ins> #[rustc_builtin_macro(SmartPointer, attributes(pointee))] </ins> #[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize)] #[unstable(feature = "derive_smart_pointer", issue = "123430")] pub macro SmartPointer($item:item) {

https://crater- https://crater- cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
label F-derivesmartpointer
Thread on zulip: https://rust-
claim
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: use FfiResult::*; if def.repr.transparent() { <del> // Can assume that only one field is not a ZST, so only check </del> <ins> // Can assume that at most one field is not a ZST, so only check </ins> // that field's type for FFI-safety. if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) { self.check_field_type_for_ffi(cache, field, substs) } else { <del> bug!("malformed transparent type"); </del> <ins> // All fields are ZSTs; this means that the type should behave // like (), which is FFI-unsafe FfiUnsafe { ty, reason: "this struct contains only zero-sized fields".into(), help: None, } </ins> } } else { // We can't completely trust repr(C) markings; make sure the fields are

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
modify labels: regression-from-stable-to-nightly Regressed in cc
Hmm, I don't think this is actually a regression. The MCVE triggers an error on stable and beta: and it seems like the requirements for were relaxed by such that this code should compile successfully on nightly.
Sorry, I forgot to re-check this issue before opening my PR. You can have a look at to avoid duplicate work, if it's not too late already...
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-low


Question: /// /// Additionally, `f32` can represent some special values: /// <del> /// - −0.0: IEEE 754 floating point numbers have a bit that indicates their sign, so −0.0 is a ///   possible value. For comparison −0.0 = +0.0, but floating point operations can carry </del> <ins> /// - −0.0: IEEE 754 floating-point numbers have a bit that indicates their sign, so −0.0 is a ///   possible value. For comparison −0.0 = +0.0, but floating-point operations can carry </ins> ///   the sign bit through arithmetic operations. This means −0.0 × +0.0 produces −0.0 and ///   a negative number rounded to a value smaller than a float can represent also produces −0.0. /// - [∞](#associatedconstant.INFINITY) and

Pointed out by in the float docs are using the term "arithmetic" operations in a few places, but that term is never defined. Furthermore, the new NaN docs probably should use that term as well when discussing which operations the NaN rules apply to (instead of "non-bitwise floating point operations" which they use currently). By "arithmetic operations", the docs likely mean all operations except for unary , , , , , and .


Question: impl<'tcx> OpaqueTypeExpander<'tcx> { fn expand_opaque_ty(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> Option<Ty<'tcx>> { <del> if self.found_recursion { </del> <ins> if self.found_any_recursion { </ins> return None; } let substs = substs.fold_with(self);

I tried this code: I expected running to produce an error like: It does, but takes time exponential in the number of calls, although doesn't appear to use any extra memory. In the time take looks like: I believe it's also exponential in the number of calls in . The reason I had code like this was because I was using nom's parser combinators which results in lots of nested closures. I spotted it because this caused rust-analyzer to hang because cargo clippy hung (it looks like check was the issue), I had to kill clippy to fix it. I bisected this (with cargo-bisect-rustc) to find the regression in , which contained the following bors commits: merge of - Centril:rollup-rzvry15, r=Centril merge of - tmandry:rollup-0k6jiik, r=tmandry merge of - Manishearth:clippyup, r=Manishearth merge of - tanriol:explain_borrow-use-context-dominators, r=nagisa merge of - ehuss:update-cargo-books, r=alexcrichton modify labels: +regression-from-stable-to-stable -regression-untriaged
what version of rust are you using? Is this also present on nightly?
Good question! This repros on the latest nightly () and on stable (1.53.0 2021-06-17).
Regression means that it was linear, or exponential, but smaller?
I didn't looks to still be exponential just much quicker, and with a smaller base (~2 vs ~14):
looks related
Bisected to innocent-looking commit . Removing the caching from in master does indeed fix the issue. I haven't looked at the how or why or where that causes (other) problems though. cc
Hmm, the only thing that looks expensive there is the hashing - I wonder if it's hashing over and over again without ever getting a cache hit? Hashing has a fixed cost, but can be an arbitrary length:
cuts down on time for this testcase and others with invalid recursive opaque types by bailing out early if a recursion is found.


Question: impl<'tcx> OpaqueTypeExpander<'tcx> { fn expand_opaque_ty(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> Option<Ty<'tcx>> { <del> if self.found_recursion { </del> <ins> if self.found_any_recursion { </ins> return None; } let substs = substs.fold_with(self);

This fixes the regression but the check time is still exponential in the recursion: #wraps|time (s) ---|--- 23|9.2 24|18.3 25|36.6 Not sure if that matters in practice though.
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-high
That's the same as before the regression, right? I definitely think that's a change worth making :) I expect the doubling will have a completely different cause.
Yes, same ballpark.


Question: /// Options for rendering Markdown in the main body of documentation. pub(crate) fn opts() -> Options { <del> Options::ENABLE_TABLES | Options::ENABLE_FOOTNOTES | Options::ENABLE_STRIKETHROUGH </del> <ins> Options::ENABLE_TABLES | Options::ENABLE_FOOTNOTES | Options::ENABLE_STRIKETHROUGH | Options::ENABLE_TASKLISTS </ins> } /// A subset of [`opts()`] used for rendering summaries.

These include: The reasoning for all of these extensions is that they all have wide use not just in GitHub, but in many applications of Markdown.
I'm not sure if automatically creating links from bare domain names is a good idea, so if there's an option to disable that specifically I'd suggest it. The rest all seems fine to me.
Just like said for Autolinks. I'm also not sure to see the point of the task list one. However, adding strikethrough would be nice.
Tasklist would be useful for things like this: [x] Implemented thing [x] Some other implemented thing [ ] Unimplemented thing [ ] Some other unimplemented thing or possibly in the crate root [x] Webhooks [x] Websockets [ ] Websites [ ] Other
Another noteworthy extension to implement is . This would prevent the following tags from being used for safety reasons: - - - - -
We decided in not to add this. Instead rustdoc will now suggest to turn raw links into automatic links (). So I think the only thing left is adding task list parsing.


Question: - env: IMAGE=dist-x86_64-linux DEPLOY_ALT=1 - env: > RUST_CHECK_TARGET=dist <del> RUST_CONFIGURE_ARGS="--enable-extended" </del> <ins> RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler" </ins> SRC=. DEPLOY_ALT=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1

Steps to reproduce: Alternative steps to reproduce that will provides a suitable compiler: On OS X, with LLVM assertions disabled (like in rustc builds in , which are the default in Servo’s ), rustc 1.20.0-nightly ( 2017-06-28) fails with: This problem does not occur with from rustup, which has LLVM assertions enabled. (But perhaps that’s not the only difference between the two kinds of builds?)
What’s ?
It’s also enabled in the "non-alt" build, so probably not relevant.
Have you tried building the project in the same disk partition where you've installed rustc, i.e. inside ?
Yes. With the second set of steps (and ), the error message looks like this:
Does show anything special?
not as far I can tell.
Okay... There are for dyld but I doubt if they are useful. The problem is that is not found, meaning is not expanded properly. I've checked does not* have an load command, meaning the is only supplied through . I don't think the alt-build's and normal build's Cargo has any difference though. Verify if is correct?
with and without in : Both contain:
Both contains directly inside ? (not )
Almost, the one has a different hash:
Huh, that's even stranger. The should be resolved correctly. But the alt- rustc linked using the libstd from the non-alt-build??
Well it sounds unlikely to me that “from the other build” is really what’s going on, I’d bet on incorrect hashing. How is the hexadecimal part of determined? What base values are being hashed?
IIRC rustc will just search for all , it doesn't recompute the hash. Would it work if you move out of , and then do a + ?
I first hit the issue before the "non-alt" build was downloaded.
I've tried to reproduce it myself and it seems plays a role in finding which is linked. I can make it link to the correctly hashed by: "Install" it sure does not contain , and includes it. It should work. Overriding without installing causes rustc not able to find .
What is "it" and what does "installing" mean?
Run after extracting the tarball (sorry was on mobile so did not check the exact instruction).
What does this do besides copying the files?


Question: - env: IMAGE=dist-x86_64-linux DEPLOY_ALT=1 - env: > RUST_CHECK_TARGET=dist <del> RUST_CONFIGURE_ARGS="--enable-extended" </del> <ins> RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler" </ins> SRC=. DEPLOY_ALT=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1

Regardless, this is a regression, it only happens on OS X, and only with "alternate" builds…
It looks like the problem is presumably that and don't have the same hash. One fairly clear problem is that Servo for some reason doesn't download rust-std from alt by-default AFAICT; having some quick prints to the util script. That would lead to incompatibilities; this should be fixed.
I've filed which should fix this.
Good catch! This fixes the problem, thank you.


Question: # https://github.com/puppeteer/puppeteer/issues/375 # # We also specify the version in case we need to update it to go around cache limitations. <del> RUN npm install -g browser-ui-test@0.2.12 --unsafe-perm=true </del> <ins> RUN npm install -g browser-ui-test@0.2.14 --unsafe-perm=true </ins> ENV RUST_CONFIGURE_ARGS  --build=x86_64-unknown-linux-gnu

It looks like a CSS rule is being applied incorrectly. It also looks weird if you click through to the type alias's page (). ! !
I'm not really sure, could that be slipped in ?
It turns out it was actually much more recent. The PR causing the regression was , cc searched nightlies: from nightly-2021-05-01 to nightly-2021-06-12 regressed nightly: nightly-2021-06-04 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-apple-darwin Reproduce with: </details
The culprit CSS rule is here: It also caused which was fixed by .
Ah, I have missed this one. Sending a fix.
Assigning priority as in the prioritization working group. label: +P-medium -I-prioritize
The fix should be merged in less than 3 hours. ;)
I know, but we had already agreed on a priority :)
Oh I see. Thanks for taking care of that then! :)


Question: use libc::{mmap, mprotect}; use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE}; <ins> use crate::io; </ins> use crate::ops::Range; use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys::os;

There is too little confidence in this mistake, why not return to errno. The mmap interface provides the errno, such as the ENOMEM and SIGSEGV interfaces. panic!("failed to allocate an alternative stack")
!
Please try again your code latest nightly Rust version. Also could you paste the ICE backtrace? label E-needs-mcve I-ICE
This is not a ICE This issue propose printing errno on this :
Probably we want this then: label: -I-ICE, -T-compiler, +T-libs


Question: } } <del> clean::ExternCrateItem(..) | clean::ImportItem(_) => { if i.visibility != Some(hir::Public) { return None } } </del> clean::StructFieldItem(..) => { if i.visibility != Some(hir::Public) { return Some(clean::Item {

Rustdoc defaults to only documented things that are public, i.e. things that the user of a library would care about. This is a good default, but rustdoc can also be useful to people working on large crates by documenting these crates themselves. In that case, it’s preferable to also include private types, fields, functions, and methods. was about this use case, and was closed with this solution: We just tried this on . It’s better than before, but has the unexpected side effect that every item (including non- and the implicit prelude) and every (including the implicit ) is documented under “Reexports”. It can get pretty noisy: ! They’re technically part of the crate, but don’t provide useful information. Could rustdoc split up the pass into one that strips private and , and one for everything else?


Question: RelateOutputImplTypes(span) => span, MatchExpressionArm(match_span, _) => match_span, IfExpression(span) => span, <ins> IfExpressionWithNoElse(span) => span </ins> } } }

I apologize in advance if this is a separate issue. With the map() generic function from the tutorial: That code gives a nice error message: However, remove the assignment and what should be the same error message becomes:
Yes, that is unrelated to this issue. You're seeing an expected type mismatch error since the return type of main() is () and your samples result in two different non-() results.
Thanks I was one hour into learning Rust when I came across this. I understand what is going on now. I still think the error message could be improved to mention that "expected " is referring to the return type of main(). That simple clue could help people not as familiar with Rust to remember the semicolon rule to turn a statement into an expression.
Not critical for 0.7, but improving error messages is always good. Nominating for milestone 5.
declined. this is bad but it's not a blocker.
Confirmed that the situation is unchanged.
This is still an issue.
Bug triage. Still an issue.
Very, very small change:


Question: <ins> pub trait Ice { fn f(&self, _: ()); } impl Ice for () { fn f(&self, _: ()) {} } fn main() { ().f::<()>(()); //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied } </ins>

Repros on the /current nightly. But works (gives an error about mismatched number of generic arguments) on stable and beta. s/o to for the minimal example. : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
label regression-from-stable-to-nightly
Regressed in (nightly-2022-09-02), presumably , though seems to have already made the connection to that PR anyways :-)


Question: kind_name, tcx.item_path_str(variant.did), field_names); <del> if let Some((span, _)) = inexistent_fields.last() { </del> <ins> if let Some((span, ident)) = inexistent_fields.last() { </ins> err.span_label(*span, format!("{} `{}` does not have {} field{}", kind_name, tcx.item_path_str(variant.did), t, plural)); <ins> if plural == "" { let input = unmentioned_fields.iter().map(|field| &field.name); let suggested_name = find_best_match_for_name(input, &ident.name.as_str(), None); if let Some(suggested_name) = suggested_name { err.span_suggestion(*span, "did you mean", suggested_name.to_string()); // we don't want to throw `E0027` in case we have thrown `E0026` for them unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str()); } } </ins> } if tcx.sess.teach(&err.get_code().unwrap()) { err.note(

With a single typo in a match arm, we generate three separate errors: We should collect all these errors into a single diagnostic:
could you share sample code to exactly reproduce above diagnostic?
I will raise another PR to address the case where we are unnecessarily throwing .


Question: <ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Test transitive analysis for associated types. Collected types // should be normalized and new obligations generated. trait Foo { type A; fn foo(&self) {} } impl Foo for usize { type A = usize; } struct Bar<T: Foo> { inner: T::A } fn is_send<T: Send>() {} fn main() { is_send::<Bar<usize>>(); } </ins>

For example, this code does not compile: cc
I think this may be another instance of
Trusting analysis, closing in favor of but adding test case there as well.
(it of course would be good to confirm that this actually is an instance of -- my initial reaction when I saw it was "they might be related ... but wait, wasn't part of the opt-in-builtin-bounds work to be able to move the special case handling of / out into library code...?"; I've only done some rough skimming that makes me think the hypothesis remains plausible.)
Ah either way is fine by me, I personally like fewer issues :). We can reopen once is addressed one way or another if necessary (or if you'd like to reopen now that's also fine by me!)
oh that was really just a note to myself as much as anything else, not a comment on your choice to close this ticket. :)
I don't think this code uses type-contents. If it does, that is itself a bug! Either way, we should keep this open for the time being.
cc


Question: <ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Test transitive analysis for associated types. Collected types // should be normalized and new obligations generated. trait Foo { type A; fn foo(&self) {} } impl Foo for usize { type A = usize; } struct Bar<T: Foo> { inner: T::A } fn is_send<T: Send>() {} fn main() { is_send::<Bar<usize>>(); } </ins>

The following doesn't compile, but I believe it should: Error: Even though , and . In fact, this compiles:
should be , because the old definition that didn't use assoc types was . Probably the code that detects builtin bounds wasn't updated to handle associated types. cc
This breaks us in hyper. For now, I'll have to manually , knowing that it's safe.,,


Question: fn to_radians(self) -> f64 { num::Float::to_radians(self) } #[inline] <del> fn ldexp(x: f64, exp: int) -> f64 { unsafe { cmath::ldexp(x, exp as c_int) } </del> <ins> fn ldexp(self, exp: isize) -> f64 { unsafe { cmath::ldexp(self, exp as c_int) } </ins> } /// Breaks the number into a normalized fraction and a base-2 exponent,

has an unusual format: it takes as it's first parameter where everything else in the trait takes . It should take as it's first parameter for consistency with everything else. It is located in
+1. There are a few different things to consider here, though: does not operate on any FP number per se like most other operations do, but rather constructs a new FP number from two arguments one of which happens to be FP number. This function’s signature is consistent with most other methods that construct some kind of FP number (e.g. ). We might want to consider whether methods such as shouldn’t just go ahead and take instead. can’t currently be chained, but I see literally 0 cases where anybody would chain this function. cc
Okay, but from a consistency standpoint, it's like 1/80 for vs . It it keeps the same format, it and it's similar functions would probably be better to go at the end or beginning of the function list where they won't be so unusual.
Nominating for 1.0-beta P-backcompat-libs
One should be able to call this thing as a method, one way or another. We need to make sure that is resolved.
0 beta, P-backcompat-libs
I started to fix this.


Question: <ins> error[E0599]: no method named `b` found for reference `&Self` in the current scope --> $DIR/issue-117794.rs:5:14 | LL |         self.b(|| 0) |              ^ help: there is a method with a similar name: `a` error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0599`. </ins>

<!-- ICE: Rustc '' 'error: internal compiler error: expected type of closure to be a closure', 'error: internal compiler error: expected type of closure to be a closure' File: --auto-reduced (treereduce-rust): original: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirbuilt] building MIR for [unsafetycheckresult] unsafety-checking [mirconst] preparing for borrow checking [mirpromoted] promoting constants in MIR for [mirborrowck] borrow-checking [typeofopaque] computing type of opaque [typeof] computing type of [checkmoditemtypes] checking item types in top-level module [analysis] running analysis passes on this crate --
regression in ping
nice, that's one of the ICE messages I just too


Question: <ins> error[E0599]: no method named `b` found for reference `&Self` in the current scope --> $DIR/issue-117794.rs:5:14 | LL |         self.b(|| 0) |              ^ help: there is a method with a similar name: `a` error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0599`. </ins>

<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'no entry found for key'', 'thread 'rustc' panicked at 'no entry found for key'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details
Regression in nightly-2023-11-08 / ping
I think is fixing an issue that may have the same root cause.


Question: <ins> error[E0599]: no method named `b` found for reference `&Self` in the current scope --> $DIR/issue-117794.rs:5:14 | LL |         self.b(|| 0) |              ^ help: there is a method with a similar name: `a` error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0599`. </ins>

<!-- ICE: Rustc '' 'thread 'rustc' panicked at ', 'thread 'rustc' panicked at ' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details
Regression in nightly-2023-11-08 / ping
This should be fixed by
I'm intrigued as to why you believe could rectify this problem. The issue can be distilled as follows: It results in a panic at due to the closure utilizing the type from its outermost function, eventually returning . This issue appears to be unrelated to .
You're provably correct, and I am likely wrong about the root cause of the issue. I will look tomorrow. Feel free to claim this issue if you've already found a solution in the process of investigation.


Question: assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α"); // https://github.com/rust-lang/rust/issues/124714 <ins> // input lengths around the boundary of the chunk size used by the ascii prefix optimization assert_eq!("abcdefghijklmnoΣ".to_lowercase(), "abcdefghijklmnoς"); </ins> assert_eq!("abcdefghijklmnopΣ".to_lowercase(), "abcdefghijklmnopς"); <ins> assert_eq!("abcdefghijklmnopqΣ".to_lowercase(), "abcdefghijklmnopqς"); </ins> // a really long string that has it's lowercase form // even longer. this tests that implementations don't assume

I'm looking into the performance of / on mostly ascii strings, using a small microbenchmark to . Using linux perf tooling I see that the hot part of the code is the following large loop, which despite heavy use of sse2 instructions only seems to process 32 bytes per iteration. I don't see an easy way to improve the autovectorization of this code, but it should be relatively easy to explicitly vectorize it using , and I would like to prepare such a PR if there are no objections. As far as I know, is already in use inside , for example by .
The way the loop ors the bits for the is-ascii check into a single usize doesn't seem ideal for vectorization. keeping the lanes independent should yield better autovectorization results.
Thanks for the suggestion. I already started with a simd implementation, but now checked again if the autovectorization could be improved. With the following main loop The assembly and performance is indeed better, but there is still some weird shuffling and shifting going on: The explicit simd version looks a bit better, mostly because the ascii check directly translates to a : Do you have a preference here between autovectorization and explicit simd?
If the SIMD impl results in reasonable code across architectures, including some without SIMD then that should be fine. I think it would be the first time where we use portable simd unconditionally, so it could use some additional scrutiny. If it's only meant to target x86 with SSE2 then that'd mean having multiple paths and in that case we'd still have to tweak the generic path anyway. At that point we might as well just optimize the latter further. You can probably get rid of those too by keeping multiple bools in a small array. That way the optimizer will more easily see that it can shove them into independent simd lanes. Increasing the unroll count might help too to fit better into simd registers. We do get pretty decent autovectorization in other places in the standard library by massaging things into a state that basically looks like arrays-instead-of-SIMD-types. E.g.
It seems llvm is too "smart" for this trick, on its own that generates the exact same code. The trick does work, although it seems a bit fragile.


Question: assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α"); // https://github.com/rust-lang/rust/issues/124714 <ins> // input lengths around the boundary of the chunk size used by the ascii prefix optimization assert_eq!("abcdefghijklmnoΣ".to_lowercase(), "abcdefghijklmnoς"); </ins> assert_eq!("abcdefghijklmnopΣ".to_lowercase(), "abcdefghijklmnopς"); <ins> assert_eq!("abcdefghijklmnopqΣ".to_lowercase(), "abcdefghijklmnopqς"); </ins> // a really long string that has it's lowercase form // even longer. this tests that implementations don't assume

The following creates a instruction just like the simd version, but a slightly different alternative with a array and comparing against 0 does not. It only needs to be better than the autovectorized version on those platforms ;) My initial idea was to gate the simd code on either SSE2 or Neon (possibly also Altivec and RiscV). I'd also add a scalar loop for the non-multiple-of-N remainder, so all-ascii strings are fully handled by specialized code. Currently this remainder goes through the generic and code path. On other platforms, only the scalar loop would be used, since I assume the autovectorization would also generate suboptimal code. But I agree that if similar code quality can be achieved with autovectorization, that would be preferable. I'll open a PR after a little bit more polishing the code.


Question: <ins> // check-pass // revisions: new old //[new] compile-flags: -Znext-solver //! This test checks that we can successfully infer //! the hidden type of `FooImpl` to be `Foo<i32, {closure}>` //! and `ImplT` to be `i32`. This test used to fail, because //! we were unable to make the connection that the closure //! argument is the same as the first argument of `Foo`. #![feature(type_alias_impl_trait)] use std::fmt::Debug; use std::marker::PhantomData; struct Foo<T: Debug, F: FnOnce(T)> { f: F, _phantom: PhantomData<T>, } type ImplT = impl Debug; type FooImpl = Foo<ImplT, impl FnOnce(ImplT)>; fn bar() -> FooImpl { Foo::<i32, _> { f: |_| (), _phantom: PhantomData } } fn main() {} </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --Hey! I was trying to make it work somehow with , when the function depends on the other generic parameters. I came to this approach and encountered an ICE. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <details<summary<strongOutput</strong</summary<p</p</details
label requires-nightly F-typealiasimpl_trait
Regression in nightly-2023-02-22 Regression in cc
still crashing, rustc 1.77.0-nightly ( 2024-01-08)


Question: /// A Terminal that knows how many colors it supports, with a reference to its /// parsed Terminfo database record. pub struct TerminfoTerminal<T> { <del> num_colors: u16, </del> <ins> num_colors: u32, </ins> out: T, ti: TermInfo, }

does not emit color output when running under a tmux session with set correctly to (supported by the latest versions of ncurses) even with when is set to . On the machine in question (macOS) the term file for is installed and returns the following: Per cargo should be invoking rustc with the flag, and indeed, returns 'Option color given more than once. Executing also does not produce color output, but does.
I have a similar bug on Archlinux. I used to get colored output on this system, but that recently stopped working for rustc. (Cargo is still fine for me.) If I add in and run in , I get Result::unwrap()Err/lib/terminfo/x/xterm-256colorncursesNEWS file does mention a new (incompatible) file format with a different magic number: Could rustc switch to whatever Cargo uses for colored terminal output?
A work-around for my machine was temporarily downgrading the packages, and copying the old file to .
Yes rustc should be able to switch at any time
Thanks for the workaround!
Changing from to also seems to work as a temporary workaround. (note: this may affect other terminal applications)
Another work-around if you're using sh: This sets to a possibly incorrect value, but limits its impact to only the output of a command.
That worked for me as well. I had no colour with . I downgraded to , which was what I had in , and now I have colour again.
I have a similar issue: In my regular terminal emulator (not tmux), there are no colors from rustc (as executed with ), colors from cargo itself are working fine. The default setting for there is: . The problem is fixed by setting to . Inside tmux however, colors work just fine, there seems to be by default.
Colors are fixed in the latest nightly (thanks to o/)
This is fixed for me in today’s nigthly, presumably by
With the current nightly I still have no colors with and have to use as a work around. What might still be broken?
Terminal colors are still broken with . however, does use colors, so there's clearly still a discrepancy between how and use termcolor
It works fine for me with ncurses 6.1, even rustup has colors again since the last version .


Question: /// A Terminal that knows how many colors it supports, with a reference to its /// parsed Terminfo database record. pub struct TerminfoTerminal<T> { <del> num_colors: u16, </del> <ins> num_colors: u32, </ins> out: T, ti: TermInfo, }

I’d like to note though that things like destroy this for some reason (even if is set). It took me some time to figure that out
I'm using ncurses 6.1 on Fedora 28 and everything appears to be working fine except for test colors. In mentioned that a bit tricky due to how the build works, but we can always tackle that later. What is the barrier to migrating libtest from to ? For now, it's leaving my test output looking like this. !
I have an in-progress patch for libtest but I ran into I'm guessing that's the build issue that is referring to. I don't know how linking libtest works, but I'm happy to try to fix the build if someone can point me in the right direction.


Question: #[must_use] #[inline] pub const fn from_waker(waker: &'a Waker) -> Self { <del> Context { waker, _marker: PhantomData } </del> <ins> Context { waker, _marker: PhantomData, _marker2: PhantomData } </ins> } /// Returns a reference to the [`Waker`] for the current task.

One issue that came up in the discussion is that the type implements . This might have been introduced accidentally. probably does not matter at all, given that users will only observe a by reference. However has the impliciation that we will not be able to add non thread-safe methods to - e.g. in order to optimize thread-local wake-ups again. It might be interesting to see whether and support could be removed from the type. Unfortunately that is however a breaking change - even though it is not likely that any code currently uses out of the direct path. In a similar fashion it had been observed in the implementation of () that the type is also and . While it had been expected for - given that s are used to wake-up tasks from different threads, it might not have been for . One downside of s being is that it prevents optimizations. E.g. in linked ticket the original implementation contained an optimization that while a was not d (and thereby equipped with a different vtable) it could wake-up the local eventloop again by just setting a non-synchronized boolean flag in the current thread. However given that could be transferred to another thread, and called from there even within the context - this optmization is invalid. Here it would also be interesting if the requirement could be removed. I expect the amount of real-world usages to be in the same ballpark as sending across threads - hopefully 0. But it's again a breaking change cc , , ,
Even if this weren't a breaking change, I'd want to see some really good evidence these optimizations would matter for real world code before choosing to make these types non-. I don't think getting rid of an atomic update in is a compelling example. Basically, in my view the current API is intentional and correct.
was introduced to leave room for future unforeseen requirements, and being restricts its usefulness as such, which is unfortunate. I can see a case for since we have , but it's difficult to imagine a case where it makes sense to be accessing a single from multiple threads concurrently.
I have an example of where the current API is resulting in performance issues: I am trying to implement a combined Executor/Reactor around a winit event loop. To wake up the event loop from a different thread we have to post a message to the event loop which can be a non-trivial operation.


Question: #[must_use] #[inline] pub const fn from_waker(waker: &'a Waker) -> Self { <del> Context { waker, _marker: PhantomData } </del> <ins> Context { waker, _marker: PhantomData, _marker2: PhantomData } </ins> } /// Returns a reference to the [`Waker`] for the current task.

But on the same thread, we know that we don't need to wake up the eventloop, so we can use much cheaper mechanisms like an atomic bool.
But that would be true if wakers were just also, which was an intentional part of the simplification from the previous design.
I think the point is that being precludes the otherwise noninvasive restoration of a more efficient through an additional method on .
I don't think it should be the judgement of the libs team (or any of us) to determine whether something is good enough and not needs to be further optimized for any use-case. Rusts goal as a language is to enable zero cost abstractions. This requires in my opinion to not be opinionated on any design choices which have a performance/footprint impact. I think some of the decisions that have been taken in the async/await world however are opinionated, and will have an impact on use-cases that currently are still better implemented with different mechanisms. I do not really want to elaborate on anything more particular, because I fear this would bring the discussion back to a arguing whether any X% performance degradation is still good enough. That is an OK decision to have for a software project whichs needs to decide whether Rusts async/await support is good enough for them, and whether they have to apply workarounds or not. But it's not a discussion which will move the issue here any more forward, because for yet another project the outcoming of the discussion might be different. PS: I do think it's okay and good if libraries like tokio or async-std are being more opinionated about what threading models they support, and they might sacrifice performance gains in rare usage scenarios for easy of use. But and language features are different, and we expect people to use them also for niche use-cases (e.g. there is certainly a lot of cool evaluation going on with the use of async/await in embedded contexts or kernels - where requirements might be very different than for a webserver based on tokio).
This is a trade off: Context is either Sync or it isn't, some users benefit from one choice (they can use references to Context as threadsafe) and some users benefit from the other choice (they can have nonthreadsafe constructs inside the Context construct).


Question: #[must_use] #[inline] pub const fn from_waker(waker: &'a Waker) -> Self { <del> Context { waker, _marker: PhantomData } </del> <ins> Context { waker, _marker: PhantomData, _marker2: PhantomData } </ins> } /// Returns a reference to the [`Waker`] for the current task.

Ultimately the libs team has to decide one way or the other on these points in the API where there is a trade off between thread safety and not. However, this decision has already been made and it would be a breaking change to change it, so this discussion is moot.
Do you have an example where this is actually done within the ecosystem, or a use-case for it? As far as I can tell, this would require spawning a thread using something like and capturing the from within a ?
A common way a user could depend on a type being is to store it in an and send it across threads. This isn't very likely for Context but it is a very reasonable pattern for .
I think its a fair point that we didnt intentionally make context send and sync, and that this precludes adding more fields to context that are not send and sync, and that since context is just a buffer for future changes, it would probably have been better to make it non-threadsafe. But now its a breaking change. If crater showed no regressions and there's no known patterns it nullifies, I would be open to changing this about Context personally, but I am somewhat doubtful the libs team as a whole would approve making a breaking change to support hypothetical future extensions. If anyone on the thread wants to pursue a change to context (not waker), they should get crater results as the next step of the conversation.
There is no discussion about being or not - it obviously has to be. The question is purely about . And in order to do what you describe you have to store an and send it somewhere. Which is very doubtful to happen, due to the not very useful lifetime and due to already being an like thing internally. As mentioned, the most likely way to see this behavior is some scoped thread API being used inside - or people doing some very advanced synchronization against an IO driver running in another thread. For all those there are certainly better ways than to rely on being . E.g. to return a flag from the synchronized section and call from the original thread when done. Or to and send the if there is doubt whether it needs to be persisted somewhere else. And yes, the impact on is even bigger. It was meant as an extension point. But we can not add any functions to it which are not thread-safe. E.g.


Question: #[must_use] #[inline] pub const fn from_waker(waker: &'a Waker) -> Self { <del> Context { waker, _marker: PhantomData } </del> <ins> Context { waker, _marker: PhantomData, _marker2: PhantomData } </ins> } /// Returns a reference to the [`Waker`] for the current task.

if we want to add methods which spawn another task on the same thread as the current executor thread, and which allows for spawning futures (like Tokios ) - we would have an issue.
Why would these be "certainly better" than just calling from the scoped threads?
To be a little more expansive: the scoped threadpool you're talking about could very well not be scoped inside a poll method - rather, the waker could be cloned once and then owned by one thread and referenced by many other scoped threads in some sort of threadpool construct for CPU bound tasks. This seems like a perfectly valid implementation which allows you to divide up the work among many threads without cloning the waker many times. This is potentially an optimization. I don't think this optimization is very important, but I don't think the optimizations allowed by making waker are very important either. The point is that there's a trade off between the optimizations allowed by assuming references to wakers can be shared across threads and the optimizations allowed by assuming they can't be, its not the case that one side is inherently the "zero cost" side.
We discussed this at the recent Libs meeting and felt that deferring to would make sense here.
Though I don't have the bandwidth to carry this, this definitely seems interesting. Seeing projects such as and closed-source initiatives lead me to believe that there may actually be a decent case to enable some form of -to avoid the synchronization overhead on single-threaded runtimes. I don't know if we should make this a priority, but at least we probably shouldn't close it just yet.
I think bringing back would be a nice additional improvement. But for the moment it would be nice to just fix the general sync-ness, which blocks all other fixes and improvements.
As the person who originally introduced , it was very much a conscious decision to get rid of it and to make and . This was called out explicitly .
The cited discussion in the RFC justifies making Send, and predates the decision to (re)introduce . Making doesn't defeat the objectives discussed there. In particular, it does not impact ergonomics for the common case at all.
This was recently closed, however the issue mentions both and . The recent change only affects . There is good reason that is , however after reading this issue I'm unsure that there are good reasons why is .