<!-- 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. --Playing around with (the not yet stable) and features I stumbled over the below problem, where type parameters to nested TAIT/GAT with lifetime parameters cause a "this type parameter needs to be std::marker::Sized" compiler error. The following code fails to compile with below compiler error (): In contrast, the following code, without lifetime type parameters compiles without any error. <!-- 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. --:
This gives a different error. Minimized:
GATs issue triage: not blocking. Seems like a TAITs bug; not sure there's anything for GATs to change here.
Compiles just fine now.
I guess this issue can just be closed if there's a test already?
I think test needs to be moved to correct place?
Hello, first time contributing to rust. I was trying to resolve this issue and after looking at the test I am a little confused. To me it looks like the test code is failing correctly and I can't understand where the TAIT bug is. has a concrete type whereas the function is generic over . So to me it looks like the raised error is correct. Changing the implementation to makes the code compile. I am sorry if I am missing something here. If the test is correct then would moving the test to resolve this issue? I also don't think relates to this test.
Yeah, I messed up my minimization. The test should just use the original MCVE in the OP. And that is indeed fixed.
For clarity: this can be closed when the current known-bug test is moved to the main directory for GAT tests and changed to use the OP MCVE.


<!-- 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 look like: while the current error message might still give a hint as to what could be going on, if you have genuinely large numbers passed to the function, you may go in a completely wrong path while debugging (testing the input to be within limits, rather than checking if it is negative or not). <!-- If dramatically different output is caused by small changes, consider also adding them here. Occurs in stable, beta and nightly compiler. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim


Using a const parameter in an inline const pattern causes an ICE, but only when you don't directly use the parameter. This seems to be the same problem as , although under different circumstances. Using instead of gives Disappointing, but undoubtedly the intended behavior. The above example wouldn't be easy to come across naturally, but if the const parameter was (for example) an array and you tried to index it, the compiler would tell you to use a to do that. This code causes the same ICE: I should note that this issue is only present with the feature and the feature. : <details<summary<strongBacktrace</strong</summary<p</p</details
label +A-const-generics


As of the 2021-09-23 nightly, rustc has stopped producing debug output for variables in a specific combination of circumstances: The variable is It is defined in a lib crate. The lib crate is included in a bin crate. The bin crate is built with . We noticed this after bumping past 09-23 to the 2021-10-27 nightly, when our debugger broke. The static is still being included in the ELF output (both allocated space, and represented correctly in the symtab), but is missing from DWARF. Bisecting indicates 2021-09-23 as the culprit (09-22 works). Here is a repro case that I've reduced that works on linux x86-64, at least, and probably other DWARF platforms. modify labels: +regression-from-stable-to-nightly -regression-untriaged
Bumping to regression-stable-to-beta, because 2021-09-23 is a 1.57 nightly. But would be good to confirm this reproduces on beta.
points at (). That being a rollup, looks the most relevant.
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-high
I think this may be a duplicate of . Please test on a current nightly, and when goes out it should have the backport via . It's still possible that introduced its own problem, but maybe it just exacerbated the LLVM issue.
It looks to me like the problem still reoccurs on the current nightly: <details<summaryFor completeness, here is a transcript showing the behavior that is expected, from nightly-2021-09-22</summary</details
This appears to still be reproducing as of ; we're stuck on because basically anything newer breaks our debugger.
So, after working out how to build a toolchain that includes our cross target and rust-lld and whatnot locally, I've tested today's mainline with a revert for PR , commit -- which had previously identified as the likely culprit. I can confirm that DWARF output for our statics on thumbv7em and kin is restored after that commit is reverted. Shall I prepare a PR?


<!-- 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. --: Also get this using stable: You can see it on the playground: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Can reproduce even without the type aliases: Edit: even smaller reproducer: Produces this output: () :
After some testing, this can be reproduced since 1.53, might have been introduced in


This function is only used once, with the current session's directory. Is there a reason to keep it, or should it be replaced by ? Originally posted by in <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
label +A-incr-comp +C-cleanup
feel free to make a PR and r? me on it.
claim


Right now, there are docs for x.py in a bunch of different places: https://rustc-dev- https://rustc-dev- It would be nice to consolidate these some; e.g. can probably just point to the README, and lots of the information in the readme is duplicated in the dev-guide and can be deleted and replaced with a link. cc - do you have strong opinions on this? <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
No, seems good to consolidate. I personally think we might get something out of ending up with two guides, one of which discusses the content from an internal perspective (e.g., Step, how to add new targets) and another from an external perspective, focusing on what users need to know. I think most of the existing documentation is sort of in the second of those, but also (potentially correctly, hard for me to say) treats things as a very leaky abstraction and documents a lot of the internals too. I think some of this is our audience, but I do wonder if a much simpler message is possible with just a few standard commands depending on what they want to build, and documenting specific outputs rather than the whole layout. I think right now we're trying to explain things by teaching everything, but perhaps we can get away with not teaching the internals of the abstraction. Anyway, mostly musing, no strong opinions here.
We should also document that we support suffixes instead of full paths (e.g. instead of ):
Hello, Should I start working on adding doc-comments in bootstrap ?
more doc-comments are always welcome :) but when I wrote the issue I was imagining coming up for a plan for how to organize the standalone documentation. maybe we can put the internal documentation in src/bootstrap/README and the user facing documentation in the guide?
claim
I like the idea and I think this standard should be applied in general since this seperation reduces cost of the maintaince and makes dev-guide more understandable and simple for users. I will follow that idea in the refactoring.


I'm seeing an internal compiler error on the following input, found by : The ICE happens after correctly reporting the error "cannot find type in this scope", so low priority. Affected versions: I tried nightly 2021-11-12 and stable 1.56.1 and they both show the same ICE. <details<summary<strongBacktrace</strong</summary<p</p</details
Regressed since , cc
Assigning as and removing .
Another input with a slightly different error message: <details<summary<strongBacktrace</strong</summary<p</p</details
searched nightlies: from nightly-2021-01-07 to nightly-2021-12-24 regressed nightly: nightly-2021-07-26 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
This regressed in . cc
No longer ICEs since


Consider the following code with custom DSTs: The generated assembly for x86_64 is as follows (with my comments ): This can be seen on . Why does the compiler check for zero alignment? It seems that it's impossible, as the alignment cannot be zero. :
Why alignment can't be zero ? Are you sure it's check for alignment ? As I read the asm using for ref: test if is zero, use 1 as default, move rcx if it was not zero. make sense for me but asm is not my field of expertise and even less vtable so I don't really understand why put 1 instead of just move rcx assuming the alignment should be correct but I guess I miss a crucial information about rust internal. I guess is why rust need to test since it's "maybe" sized
Adding gets me So, at least as far as the compiler is concerned, there is no obvious reason it could not be a zero-sized type. I could believe this is a missed optimization, where the compiler could infer that because of the i8 field, it has to be aligned to at least 1, but I do not believe it is a bug. It seems to satisfy the current reasoning around alignment and DSTs.
As stated in , Yes. The references to consist of two pointers, one of with is a base pointer ( in the assembly above) and the second one ( in the assembly above) is the pointer to vtable. The entry of vtable with index (written as in assembly) is the alignment (as it can be seen ).
How does the compilation error above indicate that? Also, ZSTs has alignment 1, as you can check using Why it's not a bug? The compiler generates a seemingly unnecessary instruction, which is an optimization issue. I agree that the issue is quite minor, though, and most probably it doesn't cause observable slowdown. Maybe there are some reasons why the alignment in vtable can be zero, but it seems to contradict the documentation.
I fail to see any explanation in the link that say that, is about the alignment of the vtable not its position or whatever registry contain it. For me it's make more sense it's the size of the object or something, why this code would need the vtable anyway ? It's probably search the alignement of to know the offset of the strucutre: Again just random guess.
It's the alignment of the type corresponding to this vtable, not the alignment of vtable itself. Yes, it is. The issue is that while calculating the offset dynamically, it does redundantly check whether the alignment is zero.
why do you suppose rust internal doesn't need this ? having a zero alignment could mean something like unknown alignment ? I mean you first need to prove test for zero is useless before say it's seem useless. We don't know for sure what Rust really need to do here, the type is dyn, maybe Sized. That not trivial, one should perfectly know Rust internal to know if this check is useless. Sorry for my poor knowledge in this if my comment are just losing your time just ignore them, I just try to understand your point.
I didn't dive into Rust internals code, but I know that the compiler doesn't always check for zero alignment. Here's the example: gives just But, even if I add the transparent wrapper, the check for zero is generated. See the following example: The generated assembly becomes much more complex: I don't have an idea on why the check happens. If it's omitted sometimes, then the compiler kind of knows that the alignment in vtables cannot be zero, yet it generates the check in a more complex example.
I think the diff is caused by versus but you use transparent so here I agree with you it's look strange. You convince me.
This check is generated by the following code: and is used to determine the runtime alignment of the field, which is . In the general case, this check is required, because the alignment of may be 1. You can see this if you change the field in to an , which has 2-byte alignment: In the specific cases you've identified, where the alignment of is 1, I agree that it is unnecessary. When loading alignment from the vtable, we should be adding range metadata to tell LLVM that it's nonzero. (opened for this)


I've rebased this morning and I can't build the repo anymore since landed. It seems there are missing tools in the LLVM CI tarball. AFAICT, these are the tools CI copies in the tarball: And these are the tools bootstrap tries to install in : being defined as: As you can see, there are many tools in that are not included in that step shown above. I'm on macOS, and here is the list of tools that I found in the downloaded LLVM CI tarball: Cc who authored .
I think we should disable copying those tools under ci-llvm for now, and then decide if we want to include them in the ci-llvm artifact or not.
makes sense to me!
Actually the problem seems to be bigger, for now I disabled using the LLVM CI tarball locally and it still failed.
What error are you getting with it disabled?
Exactly the same. I restarted the whole build after running , I'll report back once (if) the error reproduces again.
Ah! The compiler profile sets to , my bad, I'll explicitly override that to in my config and the problem will probably go away. I should have noticed I didn't actually rebuild LLVM hah.
I'll open a PR to make copying the tools conditional on LLVM being built locally.
Or just call , like I suggested originally ... I'm not sure why dist is being treated differently from all the other build commands.
Those tools don't exist in the downloaded archive, so won't help here


The following code works in 1.56.0 but crashes 1.57.0 as well as the most recent nightly — . <details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
According to cargo-bisect-rustc the regression is from — FYI regressed nightly: nightly-2021-09-06 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.1</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
Seems that this is duplicate of and ; only triggers with incremental compilation enabled. Unfortunately although I authored the original PR, I don't know a lot about incr-comp or the query system to diagnostic the issue. label: +A-incr-comp
Found the bug, I'll put up a PR in a sec. claim
reopening as this is a stable-to-stable regression, and (I think) we keep those open until a fix lands on stable or we explicitly decline to fix.
was this backported / can we close the issue? :)
The fix was backported and released in 1.58.0
Perfect, thanks for checking !


contains two sets of methods to access the Arc's wrapped object. and are tagged unsafe as "it is possible to construct a circular reference among multiple Arcs by mutating the underlying data. This creates potential for deadlock, but worse, this will guarantee a memory leak of all involved Arcs." There are also and methods defined when the inner type is freezable as that guarantees the type can't contain a . However, it's still trivially easy to deadlock using the safe methods: It seems that the consensus in was that possibility of deadlock is inherently unsafe, so should and be removed? cc
Perhaps access should fail when it is called by the same task twice? It would be nice if people didn't have to use unsafe blocks just to get normal stuff done.
Nested locks in the same task aren't the only way you can run into deadlock:
I am aware of that, but it seems to me this particular error would be easy and cheap to catch, so if we aren't doing that yet, we probably should. Personally I don't think the possibility of a deadlock should require an unsafe block.
Consensus in the past has been that deadlock is not unsafe (). You can deadlock with pipes too, with just two lines of code. The non- accessors for are unsafe for a totally different reason, which is documented in . Regarding "cheap and easy to catch" - I don't believe we should try to fail in the single-task deadlock case unless we can reliably fail in all deadlock cases (which is not out of the question but requires scheduler support, see ). A user who is used to seeing a failure message from their previous attempts which had deadlocked would be all the more confused when they find their cross-task deadlocking code does not fail.
Is the possibility of memory leakage really considered unsafe? doesn't seem to share that assumption, but I may be missing something there.
Neither or provides a way to leak memory via the safe constructors.
We currently don't officially consider leaks to be , but I think leaking past the lifetime of tasks with references is a very questionable thing to allow.
The box annihilator is not a good solution to rc reference cycles, but it is at least a solution. Cycles of MutexArcs will produce valgrind errors.
now provides a way to leak with the safe constructors.


Feature gate: This is a tracking issue for scoped threads. RFC: https://rust- Documentation: [x] RFC attempt 1: [x] RFC attempt 2: [x] Implementation: [x] Change signatures a bit to remove the argument to the spawn closures: [x] Fix soundness issue in implementation: [x] Document lifetimes: [x] Final comment period (FCP): [x] Stabilization PR: [x] Can we omit the argument to the functions given to ? That is, rather than . It's already possible by forcing the user to use instead, but that's not great. Maybe the language could be subtly changed to capture references or certain types by value rather than by reference(-to-reference). See also and the collapsed section in . Mostly answered in . Working idea in . Implementation in [x] How to document the and lifetimes clearly without scaring people away.
Nominating this for team discussion for the unresolved question.
Awesome API, thanks again for taking care of driving this <details<summaryTo expand on my captures suggestion / "thingy"</summaryI think it would generally make sense to be able to mark () type definitions with a annotation on them or something, so that, in a non-generic context, if one has , is nonetheless captured by move. It sounds like a kind of straight-forward thing to implement? I'd be willing to try to tackle the implementation . With it, we'd then replace with (probably still named , but I'm using the suffix here to clarify the comparison with the current implementation). The reason for that would be to have that first parameter be non-covariant (≠ the (co)variance of in ), so that the requirement for the scoped joined thread closure would become rather than , so that would be allowed to capture the . With all that, the API would become: which is not only neater (there is one scoped / scope-defining API, at the outermost closure layer, and then good old functions), but would also avoid the rather hard to grasp error messages that somebody gets when they update their scoped threads usage with a new nested thread. Indeed, consider somebody updating some code and doing: They'd get, as of the current , the following error message: Now, I personally do love the quality of this error message, but I think we have to admit it can still be quite too "technical / advanced" for some Rust programmers out there (Alan yadda yadda): they shouldn't have to know about variance to know how to use a scoped API. Granted, another option would be to invest some effort in improving the error message when using a scoped API / hard-coding this very situation, but I'd rather see that effort invested on , for instance. _ These have been my two cents on the topic, thanks for reading , and won't insist anymore on this subject, I promise </details
Hmm, regarding the capture of references, I think that the RFC 2229 logic might be relevant here. i.e. we could capture by reference instead of capturing by reference. In a way, I'm always surprised we don't.
In the meeting last week, I about the question of whether a more ergonomic API is possible. I see that has a nice write-up as well. Is there any way to make it so that calls don't need to get a scope? In other words, instead of this: can we have this? No. OK, fine: maybe someday. But not for a while. <details<summaryIf you insist, but remember that you asked for it.</summaryI spent a while deep-diving here because the situation wasn't quite what I expected. To explain, though, I think we gotta go back to basics. Similar to Rayon and others, the current scoped API gives each task a reference to the scope that contains the task: The question is, why is this inner necessary? Couldn't we just do and capture ? If you try to setup an API like the one above, you will find that it doesn't work. The problem is that the inner closure captures from the outer frame by reference. This turns out to be a general thing: any time that you have reads of a copy type, a non-move closure like will always capture it by reference. The reason is that non-move closures take the "least permissions" that they can: they prefer to capture by ref, then by , and finally to take ownership ("by value"). The downside of capturing by reference in this case is that it means the lifetime of the inner closure is linked to the outer closure, and we need them to be independent. We want the outer closure to return and then the inner closure is still running in a parallel thread, so it can't have a link to the outer closure. So why DON'T we always capture copy types by value? It's debatable if the current behavior is right, but it wasn't an accident. The intuition for the current rules is that a (non-move) closure is "part of the enclosing stack frame". The problem is that this is not the behavior we want here, we actually want something that is detached from its immediate parent, but attached to the parent of the scope itself. We don't have a way to express this (we'll return to this theme). This is not something we can "just change", it would change the semantics of existing programs in various ways. Consider this example: Today, this code fails to compile, because grabs a shared reference to , preventing the mutation . If you change to a closure, the code compiles and prints (not , because it now has its own independent copy of ). I suspect there are examples of code that runs in both versions but does something different, though at the moment I'm not sure what that is (if were copy, it'd be easy to create such programs, but it's not, partly for this reason). OK, so if by-reference closures aren't quite what we want (because we want something detached from the caller), why not have people use a move closure? i.e., why not write ? That would work fine for copy types like , but not so well for things that are not copy. The problem is that the intuition for a move closure is that it is detached from the surrounding stack entirely. But that's not what we want here. As we said, we want something that remains attached to the parent stack, but not the immediate parent. We want it to be attached to the scope's parent. If you use a move closure, patterns like this don't work, and that's annoying: Here, the two move closures would both try to take ownership of , which means this code won't compile. We'd have to write before spawning for this to work. So, the above is all accurate for Rust 2018, but as of Rust 2021 the situation is actually somewhat different. In particular, we can now capture places and not just variables. Actually, in Rust 2021, it turns out that we don't capture -- we capture . You can see this if you use some internal rustc annotations. Analyzing gives output that includes: The means that the closure is borrowing , and not . This is important because it means that we don't actually capture data from the intermediate stack frame, which is going to terminate. We capture the object directly from its owner, which is the function, which (simplified) looks like this: So why don't things work? The problem is this lifetime. It represents "the lifetime of the closure's captured data", and it can basically be anything, but it has to be larger than the call to itself. Therefore, so long as doesn't return, that data remains valid (which is what we want for this API). The API requires that each thread's closure outlives : So, let's put it together: We have a lifetime that lives "sometime longer then the call to " Threads can only captaure things that live for We have a variable that threads need to capture which is a local variable within You see the problem? Threads cannot capture because it doesn't live for . We can't quite express what we need to express, which is something like "some lifetime that is internal to but longer than the call to this closure". It's possible we'll grow ways to say that or tweak the system in the future, but I don't think it'll be soon. =) I could imagine us trying to tweak the closure capture rules here, but I'm not sure exactly how. In some ideal-ish world we've have a way for the compiler to know "how detached" the closure ought to be from the parent stack frame (e.g., based the lifetime bound that the API requires). I've advocated for a more explicit set of capture clauses, too, but that doesn't really solve anything here, since you wouldn't want to use those on a common basis. I think that the that recently blogged about is relevant here (I view the "scope" as a kind of capability), but that's obviously far out. In any case, any change here will require a fair bit of research and coordination. </details
Thanks for the detailed write-up, It turns our that that 2021-edition-captures tangent about a being captured by "value" rather than by ref ( on older editions) is actually a very interesting escape hatch. It basically provides one case of my advocated , and one case is all I needed: scope parameter that would be captured "by value", and with the inner , made interiorly invariant, so as to be able to use rather than . Here is , a bit dirty, tweaked from the original __ Now to decide if such a complex type is warranted More seriously: if hidden behind a type alias, the API docs could just show , so it's not that bad.
Heh, thanks for proving my conclusion a bit hasty! I think indeed that this scheme can work, though whether the type is too complex is a good question. To elaborate a bit around this point, if we had the ability to write (not a syntax I would recommend, but hopefully you get the idea) then effectively what we want to be able to say is something like i.e., each of the spawned closures must outlive this , but they don't quite know what is, only that it is outlived by . So if they can prove they outlive , that's good enough. You can indeed often simulate where clauses like this by leveraging implied bounds, e.g., , which is kind of the trick here, but it does make the signature more complex of course (as you noted).
Thanks and your suggestion is interesting! The type is a bit complex, but users don't have to write it out as they just get it as argument to their closure. It's definitely worth considering. However, I'd really like to have some understandable explanation of the lifetimes, which is already quite tricky with the version that's currently implemented. If a user asks how the lifetimes work here, I'd like to be able to explain it without causing more confusion. explanation helps a bit here. (Not sure if that type alias helps much, since the definition of such an alias is public and part of the stable api anyway.)
The gist regarding the lifetimes involved here, would be: ⇔ ⇔ Where I'm using the alias for better readability, and notation for . So we can replace the bounds with bounds, provided be invariant[^1] That way we can have the closures capture the itself. [^1]: if we were to let the caller "shrink ", then they'd end up with , which would always be met, resulting in a useless bound We achieve invariance of by having it inside the type, since otherwise, with the part alone, would be covariant (the region could be shrunk by users).We need to have a rather than just a because of this capture-by-move thing, where is captured as such, whereas a would be captured by reference, yielding a , which would not meet the requirement.To get a quantification in current Rust, we carry an implicit bound inside the type itself, so that quantifications that "see" the type end up correctly constrained. Hence why also needs to be infected with [^2]. [^2]: Technically an extra closure parameter could be the one mentioning : it doesn't necessarily have to be tied to itself (e.g., ). But we can agree that it wouldn't improve the readability . As to what does represent, it's a caller-chosen upper-bound on this quantification, and the caller will get maximal flexibility by picking a minimal . In Rust, the minimal fed to a generic function call necessarily spans beyond the return of that call. In this instance, : These lines I've drawn thus represent the limit after which stuff borrowed by the threads may die / be dropped.
I tried the current nightly API in some test code I was writing, and it worked well. Served the purpose I wanted it for, borrowing some local values, without any issues.
What's the next step here? We have an existence proof that it's possible to eliminate the scope parameter. It might be possible to do so in a simpler way, but we don't know that yet. Can we hide some of the internals and the multiple lifetimes from the public API to allow for future evolution, perhaps by keeping the Scope type unstable for longer than the scope function?
I think we should go forward with removing that parameter. I implemented suggestion here:
Found a soundness bug in the implementation. Here's the fix:
Adding documentation about the lifetimes here:
merge While the implementation is pretty new, the design of this API has been around for a while. There was just one open question of whether it was possible to remove the (unnecessary) scope argument to the thread closures. As it turns out, that was possible, and was done in Other than that, there are no more open design questions and I feel the design space has been properly explored. The top comment on this thread contains the up-to-date overview and history, including links to the documentation:
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [ ] [x] [x] [x] [ ] Concerns: resolved by resolved by Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
I agree that the scope argument removal should not affect the perceived maturity of this solution. However, should we consider the issue at to be a motivation for additional time to bake?
I remember there being a bit of a debate / open question around how panics are handled and aggregated. Can I get a quick summary of how that discussion was resolved and what behavior we settled on?
That was unrelated to the API, but was only a very subtle implementation issue (part of which even affected the long stable regular threads from ), so not part of what we stabilize.
Thanks for the clarification! reviewed
I've not read this API in detail but I'm in favor in principle of this being in the stdlib -- that said, I am interested to know how panics are being managed. It occurs to me that this API is probably setting important conventions that will have a precedent. (In particular, I'm very interested in seeing a "structured concurrency" API for async settings that will feel a lot like this, I suspect.)
The user can always handle panics any way they like by using on the within the scope. If they don't explicitly join all scoped threads, we only track whether any of the implicitly joined threads panicked, and in that case panic at the end of . An alternative could be to collect all the results/panics in a Vec and return that from the scope, but that's often not useful and can result in an infitely growing Vec in common use cases (e.g. a web server spawning one thread per connection). If users want to collect all the panics in a Vec for some reason, they can keep the ScopedJoinHandles around and them to get the results. The other part of the discussion we had about panicking was about the exact panic message from the main thread at the end of the scope, e.g. whether it should include one (or all/some?) of the original panic messages. That's not part of the API though, and an implementation detail that can be changed later.
Ah, yeah, I remember that decision now and that sounds good. Do we handle panics from the main closure any differently from those of spawned threads?
I think this API might be a bit more boring than you think, as there's not much interesting it can do with panics. Panics always directy run the panic handler/hook which will print it to stderr by default, and then afterwards it might unwind with a payload, which might be caught by a . If there's no surrounding and unwinding goes past the 'main' function of a thread, its panic payload is available as an from . This is true for both regular and scoped threads. (There's no reason to do this differently for scoped threads.) The only new question is what happens with panics from threads that are not explicitly ed, but those that are implicitly 'joined' when the scope ends. We could either try to collect them into some structure and allow the user to handle them, which is not always useful and can be a waste of resources, or we can just do and leave it to the user explicitly if they want to do any more sophisticated panic handling.
One related thought, though I agree with the decision to leave it up to the user to handle panics explicitly when that is important to them, I think there's an opportunity here for us to provide helpers to make it easier to do so and assert that no join handles are left unjoined. Wondering if we should add a restricted lint that people can enable to get the compiler to help them catch implicit joins.
Yes, panics on the main thread simply continue unwinding past the scope, and do not start a new panic. Example to demonstrate the difference: Here we see first the spawned thread panic, and then the main thread panic because a scoped thread panicked: But with a panic on the main thread within the scope, we just see one thread panicking. Exactly the same as when you panic outside the scope: If both these situations happen, the main thread will still continuing unwinding its own panic, making both panic messages visible: We no longer see the 'a scoped thread panicked' panic, because that's not the reason the main thread panicked.
That comes very close to an opt-in . The same lint would be useful on regular threads if you never want to detach one, so it's not really specific to scoped threads.
One last question, what happens when the main thread panics but a scoped thread is still running? Does the panic propagation wait for the scoped thread to exit?
Yes. Not doing that would be unsound.
Regarding this comment, I would like to wait at least until the unstable scoped threads apis have made it into a stable release, right now if you open the docs on stable[^1] there's no mention of scope, so I imagine many users haven't even realized that we the API yet, let alone taken the time to try it out on nightly. I checked github code search to find example usages of the API and I got exactly zero[^2] results other than and its forks. [^1]: vs [^2]:
I don't think anyone would use std's nightly unstable version, because crossbeam::scope is available on stable. Searching for that on github or gives lots of matches.
The crossbeam API is different from the one we're exporting, particularly with respect to how it propagates panics. I think given the changes to the API and how little testing they've had we shouldn't be rushing to stabilize this. People will use this API given the chance even if it's on nightly[^1], and the people who are affected by needing this API and needing stable still have crossbeam which you've pointed out is similar in functionality if not implementation so there shouldn't be a pressing need here to stabilize this ASAP. [^1]:
The difference is very small. I don't think it'd be a reason for anyone to use the nightly if they can just use the stable . Writing rather than isn't really a big benefit, and basically every user just ignores or s the result.
To clarify, this discusses the stabilization of , but not necessarily that of the type itself? Because there may be naming considerations for the latter (, or , rather than the abstract concept of a scope, alone[^naming]), and also the idea that maybe in the future we could get rid of that parameter on the scope, should we get kind of bound: We may never get -in- clauses, and even if we do, we may not make that change; but still, it may be something worth considering before stabilizing the type itself. [^naming]: we currently have a function called , which takes a closure involving a lifetime , which itself is part of a type called , yielding: a kind of API, conceptually. Imho, we should try to vary a bit some of these names for clarity. My personal view is that the function itself, even, ought to be named or , and the type or (the lifetime ought to remain named ), even though I imagine that the ship to change the function's name has already sailed…
No, the FCP is for everything listed in this tracking issue. I don't see much reason to keep the type unstable. I don't think we should rename the type to anything like , as I explained . ("I don't think we should rename Scope to Spawner, because I imagine Scope might be able to do more than just spawning threads in the future. For example, I can imagine something like to check if any of the threads panicked. Or to see how many threads are currently still running in this scope. Etc.") I don't see that happening any time soon. I even if that'd be possible at some point in the future, I don't think it really matters. You'd rarely spell out the full type anyway. Removing that one lifetime from the type and exchanging it for a bound doesn't really have much advantages for the user.
:bell: This is now entering its final comment period, as per the . :bell:
AFAIK, the burden of proof when stabilizing is reversed: there has to be a reason for the stabilization to be actually useful, and knowing, to the best of our knowledge, that "we won't regret it". Regarding the stabilization of the type being useful, I just don't see it: we can use and without the type of having to be nameable, and that should cover 99% of the usages of a scoped API. <!-- --And you seem to agree with me on this point:Regarding potential drawbacks, however, I insist that our current: API leads to very poor readability, since we have four distinct things named the same. Either the function or the parameter ought to have their name changed, to improve the teachability. I think we would all like for Alan, for instance, to be able to just look at the definition of this API signature and already have some idea of what's going on: if they have to click on to see the difference between that parameter and the function that introduced it, then that's an instance of Rust being more obtuse than it needs to be. (Meta: I didn't fight for this bikeshedding before, just hinted at it, since we were just in the experimental / phase (which is why I didn't keep discussing about it in the mentioned PRs, it seemed out of context). But I haven't seen either a "context" to discuss about this emerge; instead, we are suddenly going for stabilization (for something that isn't even yet in the stable Rust docs!). Moreover, it seems to be about full stabilization rather than stabilizing the 99% useful API, even though there are outstanding objections) Regarding the naming, then, I see two approaches: to rename to or (or even, would be the most self-documenting name, since this is what this abstract "scope" is about, but I reckon that it may be a bit too long).and/or to rename to something else. I have personally suggested , since: that would be the main role of that handle; it still seems sensible to ask the handle in charge of spawning stuff if any of the spawned stuff has panicked, or how many things it has spawned / are still running, so I don't see the "we may add other APIs related to the spawned threads" as a counter-argument for the name. If the vision that this handle represents something to manage the "scope", whatever that abstract thing may be, then let's at least have that in the name: . Or . Or . Remember that these are names that will rarely occur in code, but which will be paramount for people reading the docs and trying to figure out what's going on. A good type name goes really far in that regard, yielding the "pit of success" design philosophy. Or, even a (similar to how we have always had s). It's not super great, imho, but it is still better than a bare . This "conceptual" view (obviously real code won't name the lifetime, nor the type of the closure param, and if pervasive enough, may just name the closure parameter ), thus yields to the following signature, for which we can now already have an intuition of the API from just looking at it: <img width="589" alt="Screen Shot 2022-03-30 at 13 50 46" src="https://user-"I don't claim to have the better knowledge about this documentation-in-code bikeshed; I'm sure people can come up with nicer names than the ones I've suggested. But I do claim that the current naming, while good for a prototype, is not something we'll want to have around in the future, that the bikeshedding itself is legitimate. Thus the name of the type, at the very least ought not to be stabilized. If that requires splitting up this feature in two, so be it.
That doesn't mean never. It can be reasonable to take it as an argument to a regular function for example. Limiting the API just introduces needless frustrations where this argument can only be used in certain ways. This function is used to define the boundary of the scope, so writing seems like a good way to clearly state 'this is the scope'. Things like sound like they take a scope as input, rather than being used to define the scope. We usually name things after what they are or represent, rather than after what they can do. E.g. rather than or or . A represents the scope during which scoped threads may run. The method and potential future methods like are attached to that type because it operates on that scope specifically. seems like a perfectly fine way to express the concept of spawning a thread within a scope. It seems very reasonable to me to have the function that creates a be called . That is a pretty common pattern in Rust. Same for calling the lifetime of that object . Things like this also don't seem to lead to difficulties: I have had no issues so far with teaching this API, but I'm interested to hear any issues you ran into while teaching others this API. Explaining that defines a scope and that you can then spawn threads in that scope seems to be intuitive.
I haven't yet had the chance to teach this API to others, I admit, but I recall very well when starting with crossbeam's API, to wonder "why is everything called scope", and having to navigate back and forth between the function API, and the type (with its instance in the examples) to better grasp the interaction between the two. Having names to distinguish between two different things helps our thoughts "anchor" onto those names to better articulate the logic (language as the vessel of abstract thinking, etc.). That sentence, for instance, illustrates quite well what I mean: by definition, currently, a closure is very much "taking a scope as input". but a is also defining the scope within which the threads will be scoped, I agree. Hence my advocating for one of those two things to be renamed, even if just from to . But I don't want to delay stabilization of this very useful and well thought of API you've written based on this minor naming concern. Hence why I am suggesting that be stabilized, and that we be given time to discuss a bit more about the name of the parameter. Maybe it doesn't change, after all, but maybe it does. (The other option would be to rename to (it's less "takes a param" than , while conveying that it's different from its own parameter). But doing that, if I understand FCPs correctly, would require delaying the whole API for another release or something, which seems undesirable?) To clarify, I'm trying to be conciliating here : whilst not going against the main stabilization process altogether, which I'm in big favor of, I'm trying to nonetheless voice a nit which I think would improve documentation. This is basically just a statement that "to condemn the current naming, as a whole, to remain as it currently is", there must not be any reasonable doubt_ : ! So while the evolution of the name could go in either direction (maybe it stays as it is, if it turns out that I'm alone in this "feeling uneasy with overloading the term for two things"), I hope I have communicated the presence of enough reasonable doubt for the stabilization of the type parameter to be delayed a bit, just for the time to properly discuss about it.
concern stabilization speed Should have made this explicit before with my earlier comments. Im concerned with how quickly we're moving forward with this stabilization and what it means for how we view nightly as a tool for testing our APIs and gathering feedback.
The object represents the call; it provides the way for the closure to interact with that scope. I think it'd be more confusing to use separate names. We're not in a court room trying to handle a murder case.
I understand, but that's not a very actionable concern. Is there something specific you want to wait for? A moment in time, or a specific release? A certain type of feedback? This FCP is now blocked, which is fine, but it'd be useful to know what unblocks it, to make sure it will not end up being stuck forever.
One thing I like about the function name is that it very clearly does not create/spawn a thread. This is not true for or (for me at least).
My intent is to discuss this during the libs API team meeting, but I'm happy to share my thoughts ahead of time. First, I would like to ascertain our goals for using nightly and merging features unstably. My understanding is that we have this functionality so that we can thoroughly test out new APIs and gather feedback on those APIs prior to stabilization. If this is the case, and we're not getting that feedback, I'd like to better understand why and fix that problem, rather than using that as justification for merging features anyways. As a strawman, I can imagine the problem is that we're not giving new APIs sufficient visibility or making it clear to users that we need feedback on them, so I can imagine us changing release notes to also include a description of newly available nightly features that we would like people to start testing and giving feedback on. Alternatively it may be that our processes are too obscure and so too few people feel comfortable engaging, in which case we'd need to find which areas are unclear, improve documentation in those areas, and find ways to make it easier for people to provide feedback. I'm not sure exactly what we will find or what the solution will be, but I think it's fair to point out that there seems to be something wrong here. Depending on what we identify as the problem I think it's entirely likely that we will want to more clearly document the approximate stabilization life cycle of features, including a minimum time to stabilization, and I would personally like this to include at least one release cycle of the nightly feature being visible in stable docs before an FCP ends.
I don't think it's easy to make a general rule for this. Do we reset that timer every time some small change is made to an API? We very regularly apply some final change right before stabilizing, like when we renamed/flipped isrunning to isfinished recently. We also regularly take something from a popular crate that lots of people already have experience with, and then relatively quickly stabilize it based on that experience, even if it has small modifications like taking something by reference instead of value, etc. I very much agree that experience is important for feedback, but I don't think that experience always has to come from usage of nightly std. The main goal is to make sure we're not making mistakes, so experience from the same or similar APIs from other crates should be just as valid. In this specific case of scoped threads, there is tons of experience with crossbeam's functionality, and this is only a very small modification of it. (It handles panics in a simpler way, matching how we see crossbeam::scope being used in practice. And it has a slightly simpler interface thanks to Rust 2021. That's all.) The original RFC is from early 2019, and a lot of people have already taken their opportunity to add their thoughts to those threads. Waiting until the latest version of this api and its documentation has been included in stable for a full cycle delays the FCP until early August, after which the stabilization could be merged only in 1.64, which will be released in November. I don't think we should delay this until November, if we feel like the design space has been properly explored and we're happy with the API. I think we should start the FCP when we feel like the design space has been properly explored and evaluated, such that we can be confident we're picking the right design. I'm afraid that cannot be put in a general rule like "we'll stabilize 8 months after the last significant change". Some unstable APIs have been unstable for much longer, as there's still alternatives left to explore before we feel confident it's the right API. (E.g. the try trait.) And some unstable APIs have a very small design space or have been explored very well already, and we very quickly feel comfortable to continue. (E.g. os::unix::net::SocketAddr::frompathname.) Waiting for the full release train and a full stable cycle after_ we're at the point where we feel confident about an API effectively raises the FCP from 10 days to many months, which doesn't seem like the right thing to do. Delaying the FCP because we're not yet confident about the API is of course fine, but then I do think it'd be useful to know in which ways we're lacking confidence and what kind of input we're looking for to gain that confidence. For this specific feature it looks like you're worried that it hasn't gotten much attention yet, which I agree would be a problem. But I don't think that's the case here: the RFC and tracking issue threads were quite popular and show a lot of interaction (both in comments and emoji-reacts), and it's also gotten attention on various social media. (And the FCP adds it in TWiR of course, too.)
I agree that we shouldn't have a rigid process here and that exceptions should be made and that figuring out the boundaries is going to be an important body of work over time, but I think in this specific case we should absolutely err on the side of caution. My understanding is that there have been 4(+?) attempts to add scoped threads to the standard library over 7 or more years. That they have a long history of soundness issues. That the current implementation was less than 3 months ago[^1], had changes to the API and lifetimes 27 days ago[^2], and a soundness issue discovered in the current implementation 25 days ago[^3]. My concern is with soundness issues in the current implementation. Is the current implementation a copy of scoped threads? If so, does that mean we need to port the soundness fix back to scoped threads? I was under the impression this was a novel implementation based on crossbeam's API. Either way, I think it would be irresponsible to rush things in this case just because we've been working on this for years. [^1]: [^2]: [^3]:
Some extra context related to some of your concerns: The implementation is almost fully shared with regular threads. I modified the existing regular threads such that their (the Arc through which the return value or panic is communicated back to the JoinHandle) can decrement a counter in the Scope when it is dropped. waits for that counter to be zero before returning. Everything else is just plain old threads. The bug you mentioned () is about dropping the result stored in that too late on the thread (after its main function, when there's no more JoinHandle), which caused undefined behaviour for regular threads as well (since before 1.0). The main issue was the 'leakpocalypse', leading to the api to ensure things always get dropped, as popularized by crossbeam. I'm not aware of any other related soundness issues we had in the past with (scoped) threads. The implementation is much simpler than crossbeam's, as we don't have to collect panics, and we can directly use the internals of regular threads in std, which I've modified to support decrementing a counter when they end. Both the rfcs for the post-leakpocalypse version simply got stalled on the author not having time for it.
I tried to use this feature and got error when trying to use non- function arguments in spawned threads, ie.: Is this intended limitation? Note that it does work with crossbeam ().
Interesting, that definitely needs investigation. concern borrow function arg ref example
That error looks very strange. It's mentioning a 1-element tuple () that doesn't explicitly appear anywhere in the code. It seems to be the tuple of captures of the closure, but that's not supposed to show up in diagnostics like this. What it complains about is that it cannot find a lifetime that is not longer than the one of the argument, but at least as long as the scope closure. But that second lifetime is always shorter. I'm filing a bug for this.
It compiles fine with enabled. So it looks like it's an issue with the 'old' borrow checker that's already been fixed in nll.
Looks like will be stabilized soon: https://rust-,
I have a couple questions: Will join all the constructed threads if the initializer panics? Will try to join all the remaining threads if any of the joined threads panic? Sorry if this has already been answered somewhere - I haven't looked through the minutes or related.
I think those questions were discussed starting here:
Yes, to both questions. Any other answer would be unsound.
Perhaps that should be clearly documented. I imagine it is easy to create a scenario where one thread panics and another thread never finishes, causing to hang. That could be surprising.
Sounds like we may need to block this waiting for the nll feature to stabilize.
It works perfectly fine without NLL for most use cases, holding it on that seems a waste of time if the alternative is failing to compile in the absence of it. I've provided some uses of the API in the form of a generic threadpool.
Quoting an issue that was recently opened on the repository: The doesn't have this issue: it does not maintain a Vec of join handles or similar, and doesn't grow its memory usage over time. (Other than what the running threads themselves are using.) It's good to see there are already real uses of long living scoped threads with unbounded spawning, as that means the effort to make be just as efficient in those cases was worth it. :)
Any news on the stabilization proposal? Regarding the lack-of- borrow checker error, it's a rough edge due to a borrow checker bug that one may rarely run into (easily solved with more type annotations / helping inference, by the way!), but not only would it be rare, we also know that once becomes the default we won't hit that issue anymore, which guarantees we won't have to change the API. I thus second making the API fully unusable just so that users don't run into the API being unusable in a few cases seems counterproductive.Regarding the naming concern (of my own!), since I notice I'm the only one of that opinion, I won't insist. I thus recant those concerns, especially if it helps moving things forward is there anything else remaining?
I've nominated for lang team discussion. I got the impression it's close to stabilizing. If it's stabilizing in 1.63, we don't need to have a discussion about whether we're okay with stabilizing scoped threads without waiting for . has an open concern (with rfcbot) about stabilizing this too quickly without the opportunity for the community to give feedback. It's been some time since then, so that might be resolved now, but that's not up to me to decide. I've opened to add scoped threads to the new TWiR 'call for testing' section, which might help with getting some feedback.
Are we certain this issue will be rare? The original repro in is just from using a non reference in a scoped thread, right? That seems like a primary use case to me. The only source I can find saying this is a rare issue is in but there doesn't seem to be an explanation as to why they think it is uncommon. With the TWiR post I think I'm relatively reassured that we will get enough eyes on this before it has a chance to stabilize, so I'll go ahead and resolve my issue for now, but if we get feedback that people are running into the NLL issue often I think we should just tie the stabilization to NLL. resolve stabilization speed
It works fine with non-'static lifetimes: borrowing from the local scope works without problems, as shown by the example at the top of this thread and in the docs. The issue seems to pop up when the lifetime comes from outside the current function. I wouldn't say it's a super rare case, but it's less common than just borrowing things from the local scope. I'm hoping we can stabilize both and scoped threads in 1.63.
Should we also update the example of in ?
My bad, I missed a imho qualifier in it, since that wasn't an objective statement. To detail: I suspect the cases where this issue will be fully blocking one's usage to be rare. Indeed, while the cases where we may run into this issue ("lifetime comes from outside the current function") can happen, they can be worked around by: either feeding that lifetime name to :or by making an even more nested non-copy borrow:(the reason for the latter is that thanks to the 2021 edition, only a local-to-the-function reborrow of is captured by the closure, thereby removing from the equation). so this leads to a rough edge in the API rather than a blocking thing; nothing some documentation can't palliate while waiting for nll to be stabilized. _ But if nll is to stabilized that fast, then there obviously isn't even a question to begin with, so let's wait for that nominated discussion
The fact that the support for nested usage of in non- closures relies on edition-2021 capturing behavior means that someone who would try to do something like on edition 2018 or 2015 would (given the current documentation) have a hard time knowing in the first place that this is something that just works on edition 2021 have to come up on their own with the solution of putting a reference to into a variable in order to be able to work with closures, provided they stay on the older edition; something as follows: I think at a minimum, the documentation should mention the fact that nested usage of the value is possible without on edition 2021. In a perfect world, we could quickly implement both HRTBs with lifetime bounds (in some sort of clause), as well as a way to mark some type as "always capture by value in closures when in case it would otherwise be captured by immutable borrow", and then the API could become significantly more simple by replacing by a simple , and all the receiver types by . This would then also solve edition-dependence. In particular as someone who regularly advises newcomers to generally avoid most or all occurrences of where a value is borrowed with the same lifetime as a lifetime argument (though the rule is even more important only for ), and -- what amounts to the same thing -- to avoid (or even more importantly ) methods on a type with lifetime argument , I perceive this type here as considerably ugly. And that's not surprising since the whole thing is nothing but a hack in the first place, around the lack of a feature to mark capture-by-value-instead-of-immutable-reference types. Given the fact that closure captures were worked on somewhat "recently" (for the 2021 release) anyway, I'm wondering how hard it would be to, perhaps, at least get the "capture-by-value-not-immutable-reference" marker implemented. With this, it at least becomes instead of , and the edition-dependence is lifted. And the signature of is shorter this way even compared to an ultimate solution, because it can use lifetime elision. Compare vs. (Although, I'm not 100% sure whether , or the more explicit would be preferable. And is yet another option.) Even without any language changes, there's the option of introducing a type synonym for for . (Naming could also be changed so the synonym would be called .) This allows the option of lifetime elision in the bound, too, as well as giving a shorter name to that type. On the other hand, the 's methods would still be necessary to be placed on the type itself, since we cannot do a block for a type synonym that's defined to be a type, so would probably be the only function signature in the standard library that could use the synonym.
NLL is about to be stabilized: resolve borrow function arg ref example
:bell: This is now entering its final comment period, as per the . :bell:
NLL has been stabilized/merged. The examples that broke before now compile fine on the latest nightly. :)
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.
Merged and stabilized in 1.63!
Do we have a test case for the ? I’m asking because apparently there’s happening, and we probably wouldn’t want that test case to break before scoped threads are released, or otherwise (in case of a full revert on NLL) reconsider whether or not scoped threads should be already stabilized without it regardless, or later. In any case having a test case seems important, I couldn’t find any so far, but also I don’t exactly know everywhere I’d have to look for it.
Reopening for now. Can be closed with a test case .
Err I guess I should have reopened the other issue. Whoops. Oh well.
Tell me best night vision scope type?


I was attempting to assign directly to the result of a vector's , which caused this error to fire. That is when I discovered that the help section was telling me to do add an extra let to my while statement, which is not syntactically correct. I tried this code: I expected to see this happen: The code would fail to compile and the help message would tell me to dereference the left side, or at the least give me code that was syntactically correct. Instead, this happened: The could failed to compile, and the help message gave syntactically incorrect code as seen in the backtrace section. <!-- 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<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
This minifies to which reports and are related I think, since this example produces the ICE mentioned there on stable
label +A-diagnostics +D-invalid-suggestion +T-compiler
claim


<!-- 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. --rust version: (tried in the playground) This compiles successfully on the stable and beta channels. <!-- 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 --
prioritize nightly-to-beta regression
ICE bisected to searched nightlies: from nightly-2021-12-12 to nightly-2022-02-01 regressed nightly: nightly-2022-01-19 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.1</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
I'll take a stab at fixing this, unless (cc: ) wants to! claim feel free to steal this issue from me.
Hmmm actually this might make sense to be a miscompilation now, since it is kind of ambiguous. We probably should default to the old behavior, but not sure if that makes sense goin forward?
So this is two bugs: associated type resolution is ambiguous, because of the conflict between the associated const and the associated type. Probably needs reworking path resolution to prefer types in type position... because only looks for associated types instead of types and consts. I know how to fix (2.), but I'll try to see if I can include something for (1.) as well... Otherwise I'll just put up the one-liner for (2.)
mmm ok this is fair enough, edit: I guess I was just more worried that we'd have to introduce preference for types/consts here which may not have been defined previously
Yeah, my understanding is that types and consts occupy mutually-exclusive positions in well-formed code, but we might not currently have the right information piped into path resolution to prefer resolving one over the other in cases like this. To demonstrate the issue, here is another regression in path resolution, which passes on Stable and fails on Nightly. Not an ICE, but not sure if we should be breaking existing code that compiles. Happy to help work out a fix-forward, or defer that work to you if you're interested in whipping up a fix. Otherwise we might need to roll back (or at least gate its changes to path resolution behind the feature it introduces).
since this only affects nightly, as long as we put in a fix, it should be ok to not rollback, I can try to look into that
Cool! If you're gonna look into it, then I'll give the task to you. release-assignment
claim
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-medium


(Using + ) (Minimized from ) : <details<summary<strongBacktrace</strong</summary<p</p</detailscc
One thing I forgot to do is check that my minimization is exhaustive. After deleting all the from the original crate it still ICEs, so there must be another way that it is triggering this too.
Could this issue be related/duplicate of (and therefore fixed by )? Also, perhaps replace the team label with ?
I assume you meant ? That was included in which I tested with (we have a collection of failing crates in that I am rebuilding as each fix for the fallout from lands).
Fixed in


<!-- 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. --for example: <!-- 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. --: rustc needs to be built with debug assertions!! <!-- 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 --
might be related to
Probably related to (or in the same spirit) -- debuginfo code may not account for non-ZST allocator on .
Actually mentioning that issue, it gives me a probable fix. claim


<!-- 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 discovered a compiler error (segfault) in the following code () in which a generic function is called many times with different types. Some changes that avoid the crash: Running with debug mode instead of release Making simpler (e.g. or ) Marking as Removing the generics () Using the same type argument for all calls () For reference, I wrote the code in question because I was curious about whether the compiler would monomorphize multiple copies of the generic function for different types when the implementation does not depend on the type. <!-- 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. --: also the following versions on Rust playground: stable nightly See backtrace. The output looks the same to me and this was too long to submit with two copies. <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details label I-crash <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
No longer ICEs since
claim


Given the following code (): Rust gives a diagnostic suggesting deriving : However, adding leads the compiler to still give an error about not supporting this. A non-nightly compiler should not give the second error at all; it should only give the first, saying that the only supported types are integers, and . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
assigning this to project-const-generics, getting worked on in https://rust-
claim
To fix this issue, you can do the following steps: grep for "forbidden as the type of a const generic parameter" look at that function for a bit change it so that the second error isn't emitted on stable (probably actually change the control flow to start by branching on In case you are interested but need more help to fix this, feel free to reach out to me on
claim


<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --I tried this code: I expected to see this happen: either it to compile or not compile. Instead, this happened: it compiled but only on 64-bit platforms. <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --It most recently worked on: Rust 1.59 (where it did not compile no matter what platform) <!-- Provide the version you are using that has the regression. --: <!-- Did the compiler crash? If so, please provide a backtrace. --<!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- If you know when this regression occurred, please add a line like below, replacing with one of stable, beta, or nightly. modify labels: +regression-from-stable-to-{channel} -regression-untriaged -- modify labels: +regression-from-stable-to-beta -regression-untriaged
Not sure what the best approach is here. We could just to restore consistency from which made auto-implement . cc
which non-64bit platform does reproduce the issue (not sure if this question matters a lot)?
All platforms that have and . For example, . This is caused by this code:
Ah, should have or something along those lines. I'll get a fix for this up later this evening or tomorrow.
Hmm, this should probably not be closed, unless prioritization will still see it if it is closed.
Yeah, for backports I think the issue stays open until the backport is landed or decided against. Reopened for tracking.


I tried this code: I expected to see this happen: bootstrap documents the whole compiler, like it does for . Instead, this happened: The problem is that is too naive and expects the name of each crate to match its file path on disk: It needs to map from the path to the name somehow. There's already a way to go from the name to the path: but I don't think there's a way to do the reverse. HEAD is . label +A-bootstrap
label: +A-bootstrap
label: +E-mentor +A-rustbuild


<!-- 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. --run this in miri to reproduce the 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. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Looks like it tries to access the discriminant (field 0 of ), but then this case does not apply: The case does not apply because has size 8, but the field only has size 1. I didn't know types can have padding in them... in fact this is a type with layout where the size of the layout is bigger than the size of the scalar. This has me slightly worried about our code path which has less strict sanity checks. Is it possible to have a ScalarPair layout with one field where that one field covers both components of the pair and yes is smaller than the entire type? Miri (and CTFE) would go completely wrong on that.
Oh, turns out codegen uses the same logic: So I think a similar bug can somehow be triggered in codegen. I am just not sure how to make it call in the right way...
I am still missing something, the bug doesn't reproduce as often as it should... e.g., this one doesn't ICE but this one does Also I noticed that this type has ABI. do you know why lose their newtype layout optimizations with but do not? Should we really give enums a layout? Or is "Scalars do not have padding" part of the contract of layout computation?
FWIW, if I put this kind of sanity check also into Miri, things explode spectacularly. This type from memchr ends up with a immediate while having ABI. I suspect this is because even when the enum has layout, its variant (after a downcast) can have layout. That sounds like yet another bug in layout computation to me. EDIT: Also, just fixing the logic in will not be enough. We'd still be loading an 8-byte scalar which is partially uninit (yielding an entirely uninit scalar in Miri) and then try to get an integer out of that, which would raise UB. The assumption that scalars do not have padding is laced throughout Miri.
Not really a why in the sense you're asking for, but the layout computation makes the struct decision right here: For fieldless enums, is def missing an alignment check
So this is just a bug in layout computation then, and we are okay with enums losing their layout (and hence their niche)? That would be a big relief. ;)
I made that a separate issue: So this issue now is about some enums violating the invariant that layout types do not have padding.
here is already , so this is not the place where the alignment check is missing. I am not sure where is the right place though... However, I also cannot see any code in the enum path that would take into account , so I am probably missing something.
Actually the problem is the fix () for (the same code as this problem^^): that introduced the branch, which uses scalar layout even when it should not be used.
This is quite interesting, and I am not sure what to do. The problem is that on the one hand, must have layout since it has padding. on the other hand, since this enum has explicit discriminants, parts of the compiler expect that they can on it, which means it must have layout. It is impossible to satisfy both of these constraints together. any ideas for what to do here?
(Digging a bit deeper) it's not [just] about having explicit discriminants, but rather that enums can be the input to a cast and cast values are expected to be represented as immediates. Allowing on enums looks like a mistake... (we disallow , FWIW)
FWIW, here's basically the same bug during CTFE, though for some reason it doesn't cause an ICE: So we can have this as a testcase in rustc.


<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --I tried this code: It seems like is not working anymore. <!-- Provide the most recent version this worked on, for example: It most recently worked on: Rust 1.47 --: <!-- Provide the version you are using that has the regression. --: </p</details<!-- If you know when this regression occurred, please add a line like below, replacing with one of stable, beta, or nightly. modify labels: +regression-from-stable-to-{channel} -regression-untriaged --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
Probably another issue with stdcall symbol name mangling uncovered by cc cc
Hmm, seems that we would have to replicate the name decoration scheme in Rust?
claim


IIRC there is a broken link checker, but somehow it doesn't catch this case: ! which is a 404 modify labels: A-docs
Also, all source links of the macros in are broken as well.
Another reexport bug. :) EDIT: so in here the problem is that the crate isn't documented on It should redirect to .
I think the right fix is to pass -Zrustdoc-map to cargo when documenting the standard library. We already do that for the compiler docs: mentoring instructions: add that same flag to .
cc , which is one way to fix this in rustdoc, but will result in a worse experience for the source view.
I just opened a PR for this issue: I confirmed that it fixes this issue. One of my concerns is that it is very similar to even if I followed the mentoring instructions. And the other concern is that although this PR fixes the main issue, there is another issue: Macros here seems still not working: Actually is working after this PR but others aren't; I think there is some mismatch about generating links between Cargo and I can investigate this second issue further in this issue or in a new issue but at first I wanna ensure that I am on the right way.


I noticed this bug while researching the same bug in Given , I expected: Instead, this happened: The related issue in the STL is microsoft/STL; the PR to fix this in the STL is microsoft/STL. The problem is that opens the file; this is not allowed for the following four files (not sure if there are additional files which act similarly): We can get around this by using instead of ; is that something that's desired, or is this considered a weird enough use case that we aren't interested in fixing it?
Documentation explicitly documents that is equivalent to accessing metadata of the file, doesn't it? Changing this behaviour would be a breaking change I'm afraid we wouldn't be able to afford.
true, the question was whether could use instead of followed by ; that's how we're solving this in the C++ standard library. (I'll note that this documentation is now wrong, since it now uses ) This would mean that the returned from would now have for but otherwise it'd be complete (although for reparse points, we'd still have to open the file). We could additionally do followed by , to fill out those fields. I'll note that we already have this behavior on UWP, and when getting metadata from a .
Hm, changing is not something I'd be minded to do lightly. At least not without further investigation. Some questions that spring to mind: What happens if the user does not have permission to read the directory but does have permission to read the file? Can we get all the metadata that's needed? Ah your edit answered that. Does this affect performance?
given that it's reading the directory, it should make performance better (assuming one doesn't do the double call thing). I'm personally not that invested, I just thought I'd share with y'all since I have to fix this bug for the STL
It's great that we have this report! I just want to make sure we investigate fully before making changes that may affect users of the standard library. I'll also note we do have the unstable whose behaviour can change.
Ok I tested with two users. For the sake of this example, I'll call them "Admin" and "User". As Admin I created a directory and denied User all access. Within the directory I then created a "" file and granted User access to just that file. As User, I tried using to test if the file exists. This failed with . I then tried using which succeeded. As does opening the file with , Thus can fail in situations where directly accessing the file would succeed.
FYI, has run into this in the wild: We'll work around it by falling back to if fails. Would be nice if could do something similar automatically, but I appreciate that there's a high bar for backwards compatibility and performance here.
To be clear, using FindFirstFile as a fallback (rather than replacement) answers my concerns and I think would be the best solution to this issue.


<br<img width="300" src="https://user-"<br<img width="300" src="https://user-"<brI used the following script to bisect: It bisects to nightly-2022-04-14 and specifically , of which seems the most relevant because it involves associated constants in rustdoc.


Current docs on derive : I interpret the above statement as " compares enum discriminants", which is not the case. This is true for enums variants with no data, however for enum variants that are struct-like or tuple struct-like, derived actually compares the fields (which is expected) and not just discriminants: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label: +A-docs +C-cleanup +E-easy +T-libs-api
claim


The following code sometimes causes a data race to be reported by Miri: Miri reports: The deallocation occurs when returns and its local variable gets deallocated. The read occurs here (I am fairly sure): This reads the contents of the field after the . But the moment the is done, the memory backing might be deallocated. That makes the read a potential use-after-free, and a race with the deallocation. Cc
The following patch fixes this: However, even with this patch, we still run into a problem like the gets deallocated while still runs. This is still UB even after my proposed because contains a field that is not inside an (the field). So that part of what points to is expected to stay live for the entire duration of the function call. Another alternative might be to put the entire into an rather than allocating it on the stack frame of .
Going to attach this to the 1.63 milestone, since this is in a newly stabilized feature -- we may wish to back out stabilization for a cycle or backport fixes.
Re-opening for beta backport.
The fix was backported in .


This bug has already been identified but I wanted to open an issue for it. The following code should print first. () I believe there is an unanswered question: Should temporaries be dropped before the block? said this issue is being investigated at <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
assign (I'm pretty sure you are working on this at )
I think they should, since this would be consistent with if/else. ()
Originally reported in: There are also some variations of it: I've made a little test case for it that doesn't rely on printf but instead can be ran as a run-pass test:
I believe the two tests in shall be comparing to . The reason is that actually extends the temporary to the end of the block at the moment, which is the desired outcome. cc
good point. What's important is that both the let-else and let-else free version are doing the same thing. Maybe one can add an additional block around the and then add a second to ensure it dropped after the block terminated? Edit: nvm, it's not possible as the .stdout files are for compiler output, not runtime output of the tests.
<details<summaryHere's another way to test, using Rc</summary</details
It might also be an idea to add a test for the inconsistency between if and if let: (no matter which side of the divide let else is on, make sure that there is no breakage of it in the future)
The above test for "drop before else block" failed on master. Reopening.
Allow me to notify that I am currently looking at how to drop values earlier inside the block.
So I was rebasing onto latest master and I wanted to share this as part of the diff: ! There has been great improvement by but it was no full fix, especially this still post-drops: prints: If you remove the it works now thanks to .
I think this is because the borrowed is assigned with extended lifetime. only breaks out towards the remainder scope. It turns out this is not sufficient. I will try to break out to further one scope up, say the parent remainder scope of the current one. I feel that this should suffice.
This is correct behavior I think. Anything accessible in the pattern needs to be in scope till the end of the block. Consider you can write . It shouldn't depend on whether the pattern matches since that is not known at compile time generally.
yeah it may not be dropped before the code after the construct terminates, but it can be dropped before the block.
I see. I think this is the non-temporary case, when the pattern doesn't match.


<!-- 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. --After more testing, this only reproduces consistently under cmd, as other Windows shells have diverging behavior about what it means to close a pipe via program termination does not panic, but this appears to be not because of rustc doing anything different, but because finishes writing to stdout before it is closed. Note: never occurs under , as rustc sets to . <details<summary<coderustcdriver::setsigpipehandler</code </details<!-- 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
label +O-Windows
This is a consequence of using the print series of macros. They ignore errors but otherwise they're designed to panic on I/O errors. The panic could be handled in a global . Or by using and handling the error in place.
rustc explicitly chooses to override the startup code (which installs a SIGPIPE handler of SIGIGN) and reinstall a handler of SIGDFL: This means that rustc halts via SIGPIPE on POSIXy platforms and a broken pipe. To match this behavior on non-POSIX platforms, rustc should probably avoid the family of macros, and use a custom version which s on . What makes this interesting to me is that does terminate quietly on Windows in the face of a broken pipe; it's only style help printing which ICEs. The Zulip thread about is highly relevant here. The provides a platform-specific (a la ) to choose the SIGPIPE behavior between inherit/SIGDFL/SIG_IGN.
Oh, that is interesting and a bit of an odd difference. Should be easily fixed though? I mean if rustc already has code to print without ICEs.
<details<summary<code--help</code </details<details<summary<code-C help</code </detailsThere's nothing different going on here; is used in both paths. Instead, what I think is happening is buffering. I wrote a little test program: And running it I get (All runs here are done in the Windows Terminal terminal emulator with a shell of nushell, which as of 0.64.0 is using cmd to run non-builtin commands. I did a smaller number of tests directly in cmd when I realized that this may be impacting the results, and observed equivalent behavior.) The number of s I get is variable, though: I've seen as low as and as high as . (I even saw with in nushell...) <details<summarySome other runs with <eminteresting</emqualities</summaryThese commands were run directly into a cmd shell, still with Windows Terminal as the terminal emulator: In the limited trials I did, I didn't see any skipped iterations directly in cmd. </detailsSomething interesting is going on here: if you'll note, the highlighted example is missing and , despite stderr locking saying that this shouldn't be possible. This isn't a one-off error or just copy/paste error, either; this kind of data loss happened multiple times (see above dropdown for some cherry-picked trial runs). In any case, changing the loop to results in a quiet exit every time. The reason exits quietly thus seems to be not because that code path is handling , but because Windows isn't returning a broken pipe error quickly. Now, I realized after collecting most of the above data that the shell may be impacting the result... Observed differences: nushell turns into roughly . This is why results in a broken pipe. cmd and pwsh parse and do command lookup before executing the first part of a pipeline. This means e.g. <subpwsh</subfails before calling at all. pwsh is really an odd one out here... (this continues infinitely.) Eerily, it seems that pwsh treats a pipe-to-finished-program as an infinite sink, not a broken pipe! This means that in pwsh, and inputting will hang until you CTRL-C the pipeline. In cmd, nushell-on-cmd, and Git Bash For completeness sake, under Git Bash (a MINGW64), consistently gives . Additionally, under all tested shells (Git Bash, pwsh, cmd, nushell-on-cmd), doing the equivalent of and CTRL-Cing the pipeline exited without a panic, as did the equivalent of [^8]. (As opposed to on a properly POSIX shell with SIGPIPE, where AIUI non-final entries in the pipeline get SIGPIPE and continue running if they SIGIGN it, rather than receiving SIGINT? Leading to panics?) [^8]: New info! Most of the time in Git Bash hangs until CTRL-C exits without a panic. ( is not accepted by this pipeline.) But sometimes when I've just run with piping to (with or without ) will result in , and once I even just got with no more info. (I'm still running the same pc-windows-msvc build from MINGW.)


There are many examples where produces worse code than it should (worse than you'd write by hand, at the very least, and in the case of slices, worse then I think it needs to). You can often work around this by going through a pointer, although this is surprising, and not always an option (for example, it is not an option for users of ). Here's a minimal example extracted from some real code but massaged somewhat: For posterity, the generated code here currently is: (And here is actually better than I was getting in my real code, where it ended up as a branch. That said, this is bad enough to demonstrate the problem). I guess this is because gets passed a which itself may not be aligned to (for example, can't be satisfied). That problem is avoided by going through u8 (as is done with ), since that should always succeed (for non-const which isn't relevant here), and hits the special case to fix ). However, in this case the compiler should know that the pointer is aligned to 4, since it comes from a slice (and the pointer does end up with in the LLVM). I think this means there's no actual reason that must be less efficient than (unless I'm missing something), and the issue is just that our impl doesn't have a fast path for this situation. That said, maybe I'm wrong, and the generated code is bad for some other reason. Either way, it would be very nice for this to do better for the slice use case -- as I mentioned, going through is not viable when is invoked from an API like (I suspect if we can't fix it for , we probably could work around it in more directly, but it would be better to do it in if possible. That said, if I'm wrong about why this is happening, all bets are certainly off). See also , which seems related (and my hunch is that it will be fixed if we fix this issue, at least in this case). CC since . P.S. Sorry that this is a bit of a rambling issue. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Saw, got interested. Some drive-by notes: is exactly the codegen plus an to multiply it by the stride. which is used to gate is necessarily not constant folded. Interestingly, (edit: forgot "removing") the fast path thus seems to and . Everything not derived from successfully constant folds. This , even at -O1, with no changes to . (EDIT: on mobile and can't edit on godbolt, but: the linked code implements incorrectly as where it should be . In this case this does not change the results; the UB results in the optimizer assuming the slice is length zero but this has no impact on the pointer aligning.) I figured this out while trying and failing to add a fast path for . I tried delegating inside which I couldn't get to work, then had the idea to just do it from the outside. Even inside , a is correctly constant folded, so it should be possible to improve perf internally, but I couldn't figure out how to add a correct fast path for that case.
Thanks for the report. I think I have an idea how this can be improved, but I need to think about it a little further to see if it really is correct in all instances and to evaluate if it the tradeoffs in code quality are going to be positive enough to warrant a change I’m thinking of. claim


<!-- 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. --There are two crates here, and (which depends on ). library: consumer: The current output is (when running on ): <!-- The following is not always necessary. --Ideally the output should look like: We should not be suggesting private types to users, since macro hygiene does mean they can't write This is on the latest nightly, This was ran into in
this only happens with items and not ?
I included examples of and , and it seems to happen for both (see: )
Oh, my bad. I didn't read closely, my eyes just went directly to the macro item. Sorry. :sweat_smile:
For the record, this is not a macro problem. See that does not use macros: /// fn needsmeow<T: playground::Meow(t: T) {} /// fn main() { needsmeow(1usize); } /// (uses a doc comment to emulate two crates on playground) The reason is that  does not do any filtering for type privacy.


Any methods of container types (12 in Rust 1,62.1, including duplicated ones in ), and maybe corresponding methods. - - - - ... and corresponding methods in . Documentations for describes "If the capacity overflows, or the allocator reports a failure, then an error is returned.". However, it does not give any guarantees about whether the content is preserved or not on that error. This guarantee (or absence of the guarantee) should be explicitly described.
At least for (and -based things like ) it's obvious to guarantee that, so we might as well. (Thank you, Rust, for insisting on move-is- so we don't have the "what if the move constructor panics" problems like C++.) I think it'll need to be to hashbrown before we can consider promising it for /, through -- there's no guarantee in <https://rust-
Modulo needing to add it in hashbrown, shall we see if we have consensus to say that failures preserve the current contents? merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [x] [ ] [x] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.
Please feel free to post a PR for this.
Created a PR for this.