Question: <ins> error[E0609]: no field `c` on type `Foo` --> $DIR/non-existent-field-present-in-subfield.rs:37:24 | LL |     let _test = &fooer.c; |                        ^ unknown field | = note: available fields are: `first`, `_second`, `_third` help: one of the expressions' fields has a field of the same name | LL |     let _test = &fooer.first.bar.c; |                        ^^^^^^^^^^ error[E0609]: no field `test` on type `Foo` --> $DIR/non-existent-field-present-in-subfield.rs:40:24 | LL |     let _test2 = fooer.test; |                        ^^^^ unknown field | = note: available fields are: `first`, `_second`, `_third` help: one of the expressions' fields has a field of the same name | LL |     let _test2 = fooer.first.bar.c.test; |                        ^^^^^^^^^^^^ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0609`. </ins>

I just encountered this output: We currently mention available fields when the field used isn't found. It would be nice if we peeked at the types for the available fields to see if any of them has any fields (including through deref) of the name we originally wanted. In this case, I would love to see the following output: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I'll work on this. claim
I was just about to open a PR when I saw that you claimed the issue. It's my fault for not claiming this issue myself obviously, so if you've already been investing time into this the issue its still yours, but if you haven't can I open a PR for this?
I've done nothing yet as I planned to work on this tomorrow morning, so this is yours :)
release-assignment
if you're still interested in contributing, it seems to me that might be similar in scope and section of the codebase you could work in.
Thank you.


Question: mod stripper; pub(crate) use stripper::*; <ins> mod strip_aliased_non_local; pub(crate) use self::strip_aliased_non_local::STRIP_ALIASED_NON_LOCAL; </ins> mod strip_hidden; pub(crate) use self::strip_hidden::STRIP_HIDDEN;

I tried this code: with and . I expected to see this happen: No internal fields of the should be displayed as users won't be able to use the fields, making their appearance confusing and useless. Instead, this happened: The internal fields of the are displayed ! Real impact as can be seen . : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
labels +T-rustdoc +A-rustdoc-ui -needs-triage claim
Dupe of and more discussion there


Question: mod stripper; pub(crate) use stripper::*; <ins> mod strip_aliased_non_local; pub(crate) use self::strip_aliased_non_local::STRIP_ALIASED_NON_LOCAL; </ins> mod strip_hidden; pub(crate) use self::strip_hidden::STRIP_HIDDEN;

Using to document private types of the current workspace exposes external types private implementation details (in this case private fields). I would expect the expansion to limit itself to public fields. e.g. gives ! <details<summary<coderustc --version --verbose</code</summary<p</p</detailsr?
I suppose it's "ok" since you used the option. I'll add it to the next rustdoc team meeting agenda to be confirmed by the team.
Rendered output for anyone wondering: !
I'll summarize the exchange I had with Guillaume on matrix. First, the flag I'm talking about is the one you provide to . does not blindly pass the flag to but only for crates you own in your current workspace. That means that when documenting your workspace with . Private items, fields of your crates are shown contrary to your dependencies. Regarding design, it seems weird to me that aliased type expansion shows private implementation details of dependencies (e.g. for the given example). I would personally expect something like:


Question: } fn test_26444() { <del> assert_eq!("a , b , c , d , e", foo_26444!(a, b; c; d, e)); </del> <ins> assert_eq!("a, b, c, d, e", foo_26444!(a, b; c; d, e)); </ins> assert_eq!("f", foo_26444!(; f ;)); }

proc-macro derive panicked All of the 62 regressions are due to old versions of having an assert expecting instead of . So this is again a consequence of whitespace changes in pretty-printing (). I think we should be able to fix this by special casing the comma token during token stream pretty-printing and not printing the space before it.
Fixed in
Just FYI, we discussed this in the meeting. We felt like the action here was appropriate -- while in general we do not guarantee stability of pretty printing, it makes sense to be judicious, and in this particular case not having a leading space before just looks better anyway.


Question: # one is MSI installers and one is EXE, but they're not used so frequently at # this point anyway so perhaps it's a wash! - script: | <del> powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe" is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- </del> echo ##vso[task.prependpath]C:Program Files (x86)Inno Setup 5 <ins> curl.exe -o is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- </ins> displayName: Install InnoSetup condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))

The "Install MSYS2" step of failed, but the build kept going and failed later with obscure errors. We should fix this so that if msys2 installation fails the build fails immediately!


Question: let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); let display_warnings = matches.opt_present("display-warnings"); let linker = matches.opt_str("linker").map(PathBuf::from); <ins> let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance"); </ins> match (should_test, markdown_input) { (true, true) => {

Instead it should use the order that appear in the crate file. Even better, it should allow adding section headers (with a description) between them. Hypothetically: And get something like this: This would make both the source code and the documentation more accessible as the modules would be presented in a comprehensible order, with some description of each related group of modules. Edit: Rename issue to reflect that this isn't an either-or. Alphabetical order is useful, but so is programmer-specified order (to make the code accessible for newcomers) and Rustdoc should support both - see the thread below.
Shouldn't related modules be nested in submodules rather than logically ordered in the source? Finding things in long non-ordered lists is a real pain.
Yeah, I'm going to vote "alphabetical".
Hmmm. I pretty sure I put a comment here, and now its gone. Strange. Anyway. Here it goes again. Alphabetical order == random order. That's great when you know what you are looking for and just want to find it. When coming to a new non-trivial code base, being presented the content in random order is just about the worst possible way to access it. Nested modules allow us to group related modules together, and that's a good thing. If you have a long list of modules, certainly, group them. But this doesn't solve the problem. You now have a TOC where each level is randomized, which is still inaccessible. Searching for a function or module by name is an important use case, sure. But being able to access a new code base is as important, if not more so. Looking up a name in a short non-alphabetized list (at each level) isn't too hard, and one can always compensate for the lack of an alphabetical index by using ^F. Trying to understand a system presented in random order is next to impossible, and one can not compensate for the lack of a comprehensible order in a large system. If there was a way to specify the order of the entries in each level, which we agree should only contain "a few" entries, then the TOC would become accessible. If one could even add a bit of annotation for each level, so much the better.


Question: let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); let display_warnings = matches.opt_present("display-warnings"); let linker = matches.opt_str("linker").map(PathBuf::from); <ins> let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance"); </ins> match (should_test, markdown_input) { (true, true) => {

The annotated TOC would serve as a very accessible way for a newcomer to understand the code base. And, this doesn't rule out also generating an alphabetically sorted reference index, beside the TOC. All good books do both - a TOC in reasonable order and an index for looking up data by name. We shouldn't have to choose, we should be able to get both. So, I misnamed the issue. It should be "Rustdoc shouldn't list modules only alphabetically".
Agreed. Can someone rename the title?
Rename done.
Visiting for triage. Minor, but still an issue.
Triage, still listed alphabetically. Here's a sample source file: !


Question: } macro_rules! tool_check_step { <del> ($name:ident, $path:literal, $($alias:literal, )* $source_type:path $(, $default:literal )?) => { </del> <ins> ( $name:ident, $display_name:literal, $path:literal, $($alias:literal, )* $source_type:path $(, $default:literal )? ) => { </ins> #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub target: TargetSelection,

When I do , it says: Strangely, when I do , it uses the correct name: No idea how it is even possible for this tool to have two different names inside bootstrap...
I think this is just because cargo-miri's tool check step is generated through a macro this macro generates the check message via there's a in there too. The build step has a different name because that macro explicitly asks for a display name
If I make the macro use a display name,
Ah, I didn't realize those two steps were defined entirely independently.
Anyway, should make this more consistent.


Question: "extra arguments to prepend to the linker invocation (space separated)"), profile: bool = (false, parse_bool, [TRACKED], "insert profiling code"), <del> disable_instrumentation_preinliner: bool = (false, parse_bool, [TRACKED], "Disable the instrumentation pre-inliner, useful for profiling / PGO."), </del> relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED], "choose which RELRO level to use"), nll_facts: bool = (false, parse_bool, [UNTRACKED],

LLVM's MergeFunctions introduces aliases which can trigger a bug in macOS's linker when compiling with ThinLTO: For this reason Firefox has to be built with a patched version of when compiling with xLTO. Since the bug in question is pretty nasty (the above example shows a program just returning a different value with no indication that anything is wrong), we should probably try to not trigger it. Right now, however, it seems that one cannot even turn the MergeFunctions pass off in stable Rust. (I wonder if the pass should even be disabled by default on macOS?) cc & (this seems related to )
Is it a mergefunc bug or a ThinLTO bug? Can it be triggered without ThinLTO? If not, I would rather not blindly disable it on macOS, at least not when ThinLTO isn't enabled.
It's not a bug in mergefunc. It might not even be a bug in ThinLTO. It's just that mergefunc is the only thing in that generates symbol aliases in LLVM IR, and these are what can lead to "miscompilations" when using the macOS linker.
Has the ld64 bug been reported somewhere?
We could use to prevent the pass from emitting aliases on macOS, AFAIK.
This is already supported via either or in the target spec.
Do you mean that the test case also fails with enabled, or that we already have a knob to disable them?
Answering my own question, we already have a knob for that.
Which was because .
As and point to there is the unstable option which I've only tested on nightly. I guess there could be a stabilized option, but maybe what you really want to do is to patch the x8664 macos target definition (I believe this is the correct one: ).
Yes, I've been told that it has been reported to Apple. On nightly, one can already control the mergefunc pass. On stable, however, one is stuck with the default behavior. That's what this issue is mostly about.
just want to double-check my understanding: I would have thought one could use the options and to override the set of passes, even on the stable channel. Am I incorrect about this? (If I am correct, I nonetheless will admit that this is an ugly (and very fragile) method to opt out of the MergeFunctions pass)
I think that is correct, yes.


Question: "extra arguments to prepend to the linker invocation (space separated)"), profile: bool = (false, parse_bool, [TRACKED], "insert profiling code"), <del> disable_instrumentation_preinliner: bool = (false, parse_bool, [TRACKED], "Disable the instrumentation pre-inliner, useful for profiling / PGO."), </del> relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED], "choose which RELRO level to use"), nll_facts: bool = (false, parse_bool, [UNTRACKED],

It would be rather hard, however, to re-create the set of passes meaningfully, I suspect. Even the compiler delegates this to methods within LLVM, iirc.
I think using might work on stable.
So did that help,
Unfortunately not. Specifying this gives me:


Question: use rustc_middle::bug; use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::mir::tcx::PlaceTy; <ins> use rustc_middle::mir::VarDebugInfoContents; </ins> use rustc_middle::mir::{ self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory, FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind,

No response No response No response
I thought the intent with was to use it in a passthrough style, so you can insert it into existing expressions ie. becomes . In which case, maybe the lint should be for not using the value resulting from evaluating .
Not sure about the majority of users but for me is a convenience over . I use it without using the return value almost all of the time.
Probably a common thing to do, sure, but if we're talking about adding a lint, why not nudge the user in the direction of the intended and documented usage? You could at least do both: "insert into an existing expression or pass it a borrow" etc.
The fix in will only report a hint when there is already a happened. For example this code: before this fix the error is: with the fix, since there is already a error, the lint will try to find out the original macro, and suggest a borrow: The suggestion is not 100% right, since if we change it to , we need one more extra fix now(the return type is not expecting a reference), but there is a different issue, at least we have already moved one step on. If the original code is: Then suggest a borrow is a great and correct hint.
Similar in the scenario of function argument: original error is: new errors from the fix:
Would not also be a good hint? The suggestion wouldn't compile anyway right? Because would need to change to take ? Without involved, the compiler does indeed suggest that: Once that's addressed (whichever way it's done), once again becomes transparent, and eg. or works. does not, however, and I see why a "consider borrowing" hint would be good there. However, if you make the change first and leave as-is, the resulting error does not include the suggestion to change , which is unhelpful. (I agree that the message is even less helpful though, I'm not disputing that.)
Yes, it's a good hint, but from the implementation view of a hint, it's much harder to analyze the following code from the error point and then construct a new expression. Even it seems an easy thing for humans. You are right, the suggestion is not 100% right, we may need an extra follow-up fix after applying the hint, which is also a common thing in rustc diagnostics.


Question: ) -> Item { let target_attrs = inline::load_attrs(cx, def_id); let attrs = if let Some(import_id) = import_id { <ins> // glob reexports are treated the same as `#[doc(inline)]` items. // // For glob re-exports the item may or may not exist to be re-exported (potentially the cfgs // on the path up until the glob can be removed, and only cfgs on the globbed item itself // matter), for non-inlined re-exports see #85043. </ins> let is_inline = inline::load_attrs(cx, import_id.to_def_id()) .lists(sym::doc) .get_word_attr(sym::inline) <del> .is_some(); </del> <ins> .is_some() || (is_glob_import(cx.tcx, import_id) && (cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id))); </ins> let mut attrs = get_all_import_attributes(cx, import_id, def_id, is_inline); add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None); attrs

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: ! Instead, this happened: ! This is issue from First screenshot is of and second is of
Probably , it shouldn't have affected glob re-exports but maybe did (cc
Taking a look.
Same issue with a simple reexport:
That's what was meant to do, it wasn't meant to affect globs though.
I think there is another issue with how it's handled because nothing is listed on the item itself too: !
Ok so it's the expected output for a non-glob reexport. I wrote the fix for glob reexports, just need to add tests.
Latest nightly fixed the issue for but it didn't fix the issue for . In latest nightly below example doesn't work its last working version was also .
Noted. Sending a fix for it as well. :)
Fixed in


Question: /// # Examples /// /// ``` <del> /// #![feature(vec_spare_capacity)] /// </del> /// // Allocate vector big enough for 10 elements. /// let mut v = Vec::with_capacity(10); ///

The feature gate for the issue is . Tracking issues are used to record the overall progress of implementation. They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label. [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) [stabilization-guide]: https://rustc-dev- [doc-guide]: https://rustc-dev- Initial implementation ()
FWIW, here is a full-featured API provided by an external crate:
I wonder how this API relates to . It would be great if there was some safe API that wrapped around the use of to access a 's spare capacity, then updated based on the s .
Maybe we should follow that example and generalize to return ?
has implemented that, albeit as a private function. Sounds like a good idea to me.
Since exists now I think is redundant.
That's not actually true due to pointer invalidation, see and
I think it would be better to have this feature sooner rather than later. I'm starting to notice instances where people are doing things that are probably or definitely UB because they want this functionality. So I think this API falls squarely into the standard library's mission to provide pre-built and correct implementations of things that are subtle or difficult to get right.   (originally posted on but per Ralf's comments there, it is probably better to have this method for the above use cases)
I agree. I've been using this in my code and found it to be very useful. Even though is more general, I've never had a need for it and I feel that is useful on its own. The API being stabilized is: 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!


Question: /// # Examples /// /// ``` <del> /// #![feature(vec_spare_capacity)] /// </del> /// // Allocate vector big enough for 10 elements. /// let mut v = Vec::with_capacity(10); ///

See for info about what commands tagged team members can give me.
while waiting for this feature to be stabilized, you should suggest that and use one of the convenience methods in:
:bell: This is now entering its final comment period, as per the . :bell:
Ralf mentioned this on , mostly rewording with my own opinion: I would prefer not to recommend that function, because even if you just want access to the spare region, under SB, these interfaces invalidate all pointers to the initialized region. I think that's too much of a footgun for codebases where people are already writing code that is rejected by Miri.
I wonder how many people do keep outstanding pointers to the initialized part while toying with the extra part 's implementation is already better than their 0-elems slices that get -ly converted into non-empty slices (and currently better than the stdlib one since it doesn't involve a 12-week delay for stable Rust). Anyhow, I've just released a new version () with a dedicated adapter: , for extra good measure.
To be clear, my concern is that the splitting interfaces are adding a landmine for the future. If I'm sending someone a PR I'll make sure it passes Miri at the time, but that's a hard condition to maintain. Especially because the two aforementioned codebases have dependencies that do int-ptr casts, an operation that Miri just doesn't understand at the moment, so it would be hard to advocate Miri in CI.
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.


Question: LL | fn bak<I: Iterator + std::fmt::Debug>(constraints: I) where <I as Iterator>::Item: Debug { |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^              ^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <del> error: aborting due to 5 previous errors </del> <ins> error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug` --> $DIR/impl-trait-with-missing-bounds.rs:45:13 | LL |         qux(constraint); |             ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` ... LL | fn qux(_: impl std::fmt::Debug) {} |                --------------- required by this bound in `qux` | = help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item` help: introduce a type parameter with a trait bound instead of using `impl Trait` | LL | fn baw<I: Iterator>(constraints: I) where <I as Iterator>::Item: Debug { |       ^^^^^^^^^^^^^              ^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors </ins> For more information about this error, try `rustc --explain E0277`.

(Edit: Actually, being an inherent fn doesn't matter. It happens with top-level fns too.) This prints the diagnostic: The suggestion in the last line is not valid syntax (). It also emits malformed syntax if the first parameter is a or parameter. The diagnostic becomes well-formed if any of the following is done: The first parameter is changed to instead ofThe fn is not an async fn. In either case, the diagnostic correctly says: Happens on both nightly: ... and stable:
This should hopefully be a fairly straightforward patch to the diagnostics code that generates the suggestion.


Question: /// Creates an iterator that skips the first `n` elements. /// /// After they have been consumed, the rest of the elements are yielded. <ins> /// Rather than overriding this method directly, instead override the `nth` method. </ins> /// /// # Examples ///

From : It's easy, according to implement my own ` implementation for free. In retrospect it makes sense, but it was not obvious to me at all just from reading the docs. It is not mentioned in , or the docs for . And as the link in my post suggests, trying to work my way around the ownership of the APIs led me quite far afield. Admittedly it's not the most common case, but I think it would save others time if the standard library at least mentioned this somewhere. EDIT: fixed forum link which changed its name when I marked it solved.
A section about "you should consider overloading these things" definitely sounds good. should also be on that list. (In the future or in nightly is in that list too, .)
Your forum link is broken.
The docs do say However, I do like 's suggestion, about talking about which methods you may want to override.
Such hints should be non-normative though to allow the implementations, especially specializations, to use different approaches in the future.
Agreed, I was picturing more which methods to consider overloading, not specifically which things use them. (Or, contrapositively, which things there's usually no reason to overload, like , because the default implementation is generally as good as it gets because it's a trivial wrapper.)
So basically this issue is about adding some documentation on which methods you might want to override right? Which methods do you think are best to mention? Or did I misinterpret the discussion?
That's correctly, probably under or near For now my inclination would be to mention and -- once stable it should be instead, but IIRC we don't mention unstable in the broader docs until it stabilizes.
What about adding this line of text at the end of the "Implementing Iterator" section? which call internally. However, it is also possible to write a custom implementation of methods such as and if an iterator is able to compute them more efficiently without calling . Feel free to adjust the text or make something up yourself :) If you agree I will create a PR for this.
I think it would also be nice to add something to the documentation. How about this? Rather than overriding this method directly, instead override the method.
in case it wasn't clear or you are not watching your GitHub notifications, I approve of both your and suggestions. I look forward to the PR!


Question: /// Creates an iterator that skips the first `n` elements. /// /// After they have been consumed, the rest of the elements are yielded. <ins> /// Rather than overriding this method directly, instead override the `nth` method. </ins> /// /// # Examples ///

Sorry for the late reply! I apparently don't get notifications for thumbs ups and the like! I will hopefully be able to create a PR somewhere this midday.


Question: } } <del> /// Constructs a new `Rc<T>` using a closure `data_fn` that has access to a /// weak reference to the constructing `Rc<T>`. </del> <ins> /// Constructs a new `Rc<T>` while giving you a `Weak<T>` to the allocation, /// to allow you to construct a `T` which holds a weak pointer to itself. </ins> /// /// Generally, a structure circularly referencing itself, either directly or <del> /// indirectly, should not hold a strong reference to prevent a memory leak. /// In `data_fn`, initialization of `T` can make use of the weak reference /// by cloning and storing it inside `T` for use at a later time. </del> <ins> /// indirectly, should not hold a strong reference to itself to prevent a memory leak. /// Using this function, you get access to the weak pointer during the /// initialization of `T`, before the `Rc<T>` is created, such that you can /// clone and store it inside the `T`. /// /// `new_cyclic` first allocates the managed allocation for the `Rc<T>`, /// then calls your closure, giving it a `Weak<T>` to this allocation, /// and only afterwards completes the construction of the `Rc<T>` by placing /// the `T` returned from your closure into the allocation. </ins> /// /// Since the new `Rc<T>` is not fully-constructed until `Rc<T>::new_cyclic` <del> /// returns, calling [`upgrade`] on the weak reference inside `data_fn` will </del> <ins> /// returns, calling [`upgrade`] on the weak reference inside your closure will </ins> /// fail and result in a `None` value. /// /// # Panics <ins> /// </ins> /// If `data_fn` panics, the panic is propagated to the caller, and the /// temporary [`Weak<T>`] is dropped normally. ///

As I in the i.r-l.o prerelease thread, the documentation of the new(ly stabilized) and method could really use some elaboration before the 1.60 release. I'm quite familiar with refcounting, strong/weak refs, etc. but just from the doc, I have no idea what problem the new method solves exactly, when I should use it, why the closure is needed, how the closure argument seems to come from "thin air", and what the closure should return.
Argh, thanks. Could've sworn I specifically double-checked that I wrote "cyclic"…
Problem the method solves: constructing a which holds a pointer to itself. When you should use it: when you need to do the above. Previously you'd construct with e.g. and then mutate the value (via e.g. ) to fix up the self references. Where the closure argument comes from: essentially, the point of is that the place is allocated first, with strong=0, weak=1. The place has no data yet (you're constructing the value to place there), but is in the "zombie" state where it has weak references but no data. Why the closure is needed: the place needs to be "finished" once the value is created. In theory, you could "recover" any zombie weak, but for the most case, Rust wants to pretend that a "zombie" and a dangling are equivalent. What the closure should return: the closure returns the object to place in the reference counted place. After you've constructed the object, the reference count is "activated" and the object is accessable by (clones of) the weak pointer given to the constructor closure. For the most part, exists to construct style objects more easily, which is what the example demonstrates. It can be used for other use cases, but this is the primary motivating example. I'm biased because I know what is used for, so the existing documentation is enough. The docs aren't going to be changed for 1.60, but if you (or anyone) can improve the docs (with the above information or otherwise), PRs to do so are welcome!
I agree I had to read the documentation a few times to understand what this does.
Hi!


Question: } } <del> /// Constructs a new `Rc<T>` using a closure `data_fn` that has access to a /// weak reference to the constructing `Rc<T>`. </del> <ins> /// Constructs a new `Rc<T>` while giving you a `Weak<T>` to the allocation, /// to allow you to construct a `T` which holds a weak pointer to itself. </ins> /// /// Generally, a structure circularly referencing itself, either directly or <del> /// indirectly, should not hold a strong reference to prevent a memory leak. /// In `data_fn`, initialization of `T` can make use of the weak reference /// by cloning and storing it inside `T` for use at a later time. </del> <ins> /// indirectly, should not hold a strong reference to itself to prevent a memory leak. /// Using this function, you get access to the weak pointer during the /// initialization of `T`, before the `Rc<T>` is created, such that you can /// clone and store it inside the `T`. /// /// `new_cyclic` first allocates the managed allocation for the `Rc<T>`, /// then calls your closure, giving it a `Weak<T>` to this allocation, /// and only afterwards completes the construction of the `Rc<T>` by placing /// the `T` returned from your closure into the allocation. </ins> /// /// Since the new `Rc<T>` is not fully-constructed until `Rc<T>::new_cyclic` <del> /// returns, calling [`upgrade`] on the weak reference inside `data_fn` will </del> <ins> /// returns, calling [`upgrade`] on the weak reference inside your closure will </ins> /// fail and result in a `None` value. /// /// # Panics <ins> /// </ins> /// If `data_fn` panics, the panic is propagated to the caller, and the /// temporary [`Weak<T>`] is dropped normally. ///

Just a quick note that changing the documentation for the Rust 1.60.0 release itself will likely not be possible, that'd require a full release rebuild.
I'm sending a PR with explanations provided by so that it'll at least be in the next release. Why do you need a full release rebuild btw? Isn't it possible to regen the docs without rebuilding everything like the option on rustc?
I opened Feedback is very welcome. :)
Our release tooling only supports building everything at the same time.
Well, at least it'll be present in the next release with a beta backport.


Question: // stripping away any starting or ending parenthesis characters—hence this // test of the JSON error format. <del> #![warn(unused_parens)] </del> <ins> #![deny(unused_parens)] </ins> #![allow(unreachable_code)] fn main() { // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not // the malformed `1 / (2 + 3` <del> let _a = 1 / (2 + 3); </del> <ins> let _a = 1 / (2 + 3); //~ERROR unnecessary parentheses </ins> f(); }

Update test file to use + annotations instead of (see https://rust-) The files need to update are: - <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
is the correct file name , not ? And what about this comment?
Is the problem fixed ? If not, I would like to work on it !
WIP PR has been closed due to inactivity so you can work on this.
I would like to be assigned to this issue. Am I supposed to do a new pull request ?
claim Go ahead!
Error: Parsing assign command in failed: claim Please let know if you're having trouble with this bot.
claim
Error: Parsing assign command in failed: claim Please let know if you're having trouble with this bot.
Hmm, it's odd, anyway, you can assign the issue to yourself by comment Ah, I mistaken the command, the collect one is , sorry.
claim
If I understood well the problem: I must replace all the by just , even if comment exist ? Because the output changes, I should modify the .stderr version I must change with in , and as should raise an error we add why add in the version ?


Question: <ins> //~ ERROR overflow evaluating the requirement `([isize; 0], _): Sized </ins> trait Foo<A> { fn get(&self, A: &A) { } }

No response No response No response
(for compiler people:) We could fix this by merging the impl WF and coherence checks into one compiler stage. I'll put up a PR and see what T-types thinks.
labels +AsyncAwait-Triaged We discussed this in a WG-async meeting and are deferring to the resolution suggested above. He noted that this is a fix to the diagnostics only. That fact that this is an error is correct.


Question: } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { <del> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </del> match &expr.kind { ExprKind::Call(callee, args) => match &callee.kind { ExprKind::Path(qpath) => {

root: updns-0.0.6: v.
triage: P-high. Nominating for discussion.
self-assigned for investigation in short term (as in, next two or three days). However I suspect someone from will be a better choice to investigate this.
We should try to bisect this
used . Determined: searched nightlies: from nightly-2019-11-26 to nightly-2020-01-03 regressed nightly: nightly-2019-12-01 searched commits: from to  regressed commit:
is a rollup commit of the following PR's: I'm guessing this is due to PR
I'm still working on reducing this down to something that I could put into the playpen. However, one interesting thing I've found locally during my reduction: This version of the will signal an analogous compilation error: but if I lift the first argument out to a separate -binding (i.e. change it to use above, or the sub-expression out to a separate -binding (i.e. change the argument expression to use above), then the error goes away. I'll admit that I don't know all the details of how the fn-transformation works to support , but I strongly suspect that if this kind of local code change can make an error go away, then that represents a weakness somewhere (either in the fn-transformation, or in the borrowck).
Okay in the details block is a standalone version suitable for the : <details</detailsand the error it generates:
So this does seem like somewhat clear (expected?) fallout from PR : a use of a in a generator witness will be recorded as a unsafe pointer , and then is never , but the method requires that the task you give it is . I believe we can readily update the crate in question to avoid using the in the expression under the RHS of . But I do wonder whether we can/should improve the diagnostics here to try to guide the user towards such a solution ...?
I might have worded this too strongly, and/or over-reduced my example. In particular, its easy to move around the access to . But the borrow of may be trickier to deal with.
I'll have a look at addressing this with another approach I considered for . If that doesn't work out then I'll have a look at the error message.


Question: } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { <del> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </del> match &expr.kind { ExprKind::Call(callee, args) => match &callee.kind { ExprKind::Path(qpath) => {

The patch linked is enough to fix the crate in question, but I'm all for finding an in-compiler solution if we can do it soundly.
OK. I'm going to write some things up because I've changed my mind a bunch of times about how/if this can be fixed in MIR building and I don't want to keep forgetting things. Generators store values that if their value needs to be preserved across a yield. These values need to be visible for auto-traits, for example a generator may be resumed on a different thread after it yields, and so cannot be if any of theses values isn't . There are two passes that determine which values can be included in the generator: A pass that runs as part of typeck that walks the HIR to find the types of expressions and then checks for yields in the values scope (as determined by the RegionScopeTree). The types recorded here are stored in the GeneratorWitnesss type contained in the generator, which is then used for auto trait checking. This notably uses the types of expressions that HIR sees. The MIR transform that lowers the generator to a state machine. This determines the values that the generator actually stores. As a check for the compiler, we assert that any types that we capture here are included in the witness type (we don't know all auto traits, so can't check only for them). After statics no longer have a special representation in MIR. They are instead lowered to a dereference of a pointer to the given static: is lowered as if it were: Which becomes: The example above is somewhat deceptive in that the temporary that holds the pointer is used immediately after it's assigned. In this case it cannot end up in the generator since it's not live across any user code. However this isn't true in all cases, index and match expressions allow running user code while the pointer is live: In these cases MIR has to put the temporary pointer into the generator state and promptly ICEs. The obvious solution now is make type checking record the new pointer types in the generator witness in these cases. Unfortunately HIR is not a great tool for specifying "these cases". The methods that the region scope tree provides in HIR are either usually far too large (the "temporary scope") or occasionally too small (the "enclosing scope"). went for the sound but rather approximate approach, leaving us here.


Question: } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { <del> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </del> match &expr.kind { ExprKind::Call(callee, args) => match &callee.kind { ExprKind::Path(qpath) => {

One idea might be to try changing MIR building so that the temporary is never live across user code. For example, one might change the lowering as follows However working out how to do this for in a reasonable to implement way is harder. MIR actually already contains an escape hatch for values that are in the MIR but aren't in the HIR in the form of a flag (called ) on the variable. We currently use it for drop flags and boxes created by expressions. It's unclear what exactly the difference is between is. I guess one could argue that auto traits are for layout introspection and this would be further breaking that. I think that's everything for now.
Visiting from triage. were you planning to work on this further?
It's definitely tempting to take advantage of the constraints around statics to just declare these equivalent, and use the flag to get out of this. While I don't see any soundness issues around that, I also don't quite trust myself to get this right :) Can you expand on this? I'm not sure I follow.
Another solution that comes to mind relies on the fact that these pointers never need to be stored in a generator. They are consts, and the temporaries containing them shouldn't ever be mutated. We could add semantics for "const temporaries" to MIR, and never store them inside generators. The semantics would (hopefully) be simple: defined once and assigned a value that doesn't depend on any other temporaries; never mutated or borrowed mutably. We can move the statements defining them to the top of the function inside the generator transform. But that would be adding more semantics and special casing to MIR to fix a change which removed extra semantics and special casing, so I'm not sure if that's what we want :)
The argument is that the given the following auto trait we guarantee that if then there are no raw pointers directly stored in an instance of . If we make that guarantee then using internal in generators would not be OK. I would argue that we're not making such (or really any) guarantees with user defined auto traits.
Yeah, I don't think auto traits should expose layout implementation details of generators. And this really does seem like a pure implementation detail -- it doesn't have any bearing on what kinds of (unsafe) operations are allowed on a generator, like a self-reference would.


Question: } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { <del> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </del> match &expr.kind { ExprKind::Call(callee, args) => match &callee.kind { ExprKind::Path(qpath) => {

cc
So, I've been putting off commenting here to let these ideas sit, but let me leave a comment. I think I've reached a conclusion. TL;DR. I think we should mark these types as internal, but I think there are some better options for fixing this in the medium term, and this interaction should be taken into account as part of the "MIR 2.0" effort to rework places. Auto traits weren't really intended as a tool for probing layout, but rather semantic considerations. This is why traits like can be implemented by users. So I don't really think that auto traits give any sort of guarantee about their layout. Rather, this question is about is simply "what are the constituent types exposed by a generator", and this should correspond to the types that user code can directly access. The raw pointers here are not directly accessible. The values that are accessible are the "live values" that the user's code may later use -- and of course the code currently makes the constituent types be a superset of those, based on the AST structure. Of course, the real root cause of this error is a simplifying change to the definition of in MIR. It used to be that a Place had this grammar: but now we changed to just , which is why we are required to introduce the new temporary (and that holds the address of the ). As we've been talking about this change, I've been saying that we should be considering the older definition of as the one that is used by various analyses (and in particular by borrow check). This particular transformation of removing statics doesn't affect borrow check, but we failed to take into account the fact that the set of live variables can effect the definition of what is live in a generator. In particular, compiling for some expression requires a temporary unless corresponds to a place -- those places used to include statics like , but they no longer do. But I think that for analysis purposes, it should appear as if they do. We could fix this in two ways. We could write some code motion / duplication that takes temporaries like that are live across a yield and creates a fresh variable after the yield. The idea would be to make them never* live across a yield.


Question: } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { <del> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </del> match &expr.kind { ExprKind::Call(callee, args) => match &callee.kind { ExprKind::Path(qpath) => {

We can do this because that operation is a compile-time constant, really, and thus the value doesn't need to be live across a yield. This might be worth doing as a size optimization regardless. Secondly, some of the proposals we've been kicking around for going further with simplifying include the idea of a distinct sort of temporaries that explicitly represent a "partially constructed that hasn't been used by the user". The idea was to allow borrowck (and other analyses) to trivially reconstruct the . We might want to add this interaction with auto-traits into the consideration for that design, and maybe it takes us some place (e.g., these special temporaries are not considered live for the purposes of auto traits). Having written out both of those options, though, I sort of lean towards the first, at least for this specific issue.
I think these references and raw pointers created by MIR construction should be marked as . They are not visible at the language level. They can be viewed as just prefetching the address of a static, so the compiler could pick any type it likes for it (, , , some compiler internal type) so it must not affect auto trait inference. Drop flags are ignored for similar reasons. You cannot use an auto trait like this to detect them: So I think that should be reverted and the temporary static references should be marked as .
Note: opened instituting this change and I r+'d it, since fixing the regression seems pretty important and time is of the essence; there is general consensus here on the thread; this is only restoring older behavior. In particular, there were some suggestions that this might be a lang team issue; I think there is some 'intersection' and I don't want the perception that I'm trying to shortcircuit discussion. That said, I also think this is primarily a compiler team matter, since it's a deviation from the old behavior, and further this deviation was caused by altering the MIR away from the "natural, Rust-based" definition and towards a lower-level definition.


Question: <ins> error: expected `while`, `for`, `loop` or `{` after a label --> $DIR/str-as-char-butchered.rs:4:21 | LL |     let _: &str = 'β; |                     ^ expected `while`, `for`, `loop` or `{` after a label | help: add `'` to close the char literal | LL |     let _: &str = 'β'; |                     + error[E0308]: mismatched types --> $DIR/str-as-char-butchered.rs:4:19 | LL |     let _: &str = 'β; |            ----   ^^ expected `&str`, found `char` |            | |            expected due to this error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>

<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed: bpos.tou32() = () + as u32'', 'thread 'rustc' panicked at 'assertion failed: bpos.tou32() = () + as u32'' File: --snippet: Version information Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [typeck] type-checking [analysis] running analysis passes on this crate --
cc


Question: #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); <del> let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); </del> <ins> // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. // Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::<usize>()); let ret = libc::posix_memalign(&mut out, align, layout.size()); </ins> if ret != 0 { ptr::null_mut() } else {

The man page for says And yet Miri found libstd calling this function with an alignment of 4 on a 64bit-platform. This happens when size=2, align=4. The fact that size<align makes it enter the code path for .
The only reason I can imagine for to exist there is a buggy implementation of . This check is only meaningful if a buggy implementation returns not an allocation suitably aligned for any built-in type (on x86_4 – 16-bytes) but rather an allocation aligned for the particular request?
A lack of comment is disturbing here. If git history does not reveal any such issue, then we should just remove that check entirely.
That extra check was introduced by to fix
I have opened in jemalloc to get clarification from them about their alignment guarantees. It would be nice if someone with more knowledge could chime in, in particular knowledge about where exactly that value of 16 for on x86-64 comes from. Cc
Possibly from here:
C has types with an alignment smaller than are supported in all contexts. AFAICT this includes the memory returned by any memory allocation function - not only , but also . The largest scalar type of C implementations needs to be supported in all contexts. On most platforms, this type is often which the requires it to have an alignment of 16, so on these particular platforms, will have an alignment requirement of 16 bytes. On these platforms, all memory allocation functions need to return memory aligned to a 16 byte boundary when called with a to be able to support the largest scalar type provided by the C implementation. Otherwise would return memory not suitable for storing a scalar type. However, if the memory allocation is smaller than the size of the largest scalar type, then it would be illegal to store it there, so the memory returned needs to only be properly aligned to be able to store the largest scalar type that would fit in that particular size. In practice, this means that for sizes up to , the alignment of the returned memory equals the size of the allocation rounded to the previous power of two (e.g. in a 5 byte allocation, you can at most fit a 32-bit scalar, so the allocation only needs 4 byte of alignment). And for sizes larger than , the alignment is at least (this allows storing, e.g., an array of s).


Question: #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); <del> let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); </del> <ins> // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. // Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::<usize>()); let ret = libc::posix_memalign(&mut out, align, layout.size()); </ins> if ret != 0 { ptr::null_mut() } else {

In practice, the fastest thing you can do, is calling malloc if , because if malloc will return an alignment of at least rounded to the previous power of two, which is always satisfied (remember that must be a power of two, so if its smaller than size, it is at least the previous one). will do this without having to branch on any user provided alignment argument. That's precisely what that code is doing. The else branch is calling a "generic" which should be able to handle any user-specified alignment. The implementation of based on : appears to have the bug you mention, and should probably call or similar. I suspect that the implementation of provided by jemalloc, which we use here: doesn't have this issue, because it probably just forwards the call to , which supports alignment smaller than .
So basically on the C side, one assumes that is not used with types that use the C equivalent of ? With that assumption, I agree it is enough for to guarantee an alignment of rounded down to the next power of two. (I think your post originally said "up", but now it says "down" so I guess we agree.) That's what I and our implementation indeed handles that case just fine. The bug in the way we call is fixed by Still, it would be nice not to be able to reason about "in practice", but get some commitment from jemalloc -- see And finally, this only concerns on Unixes. Does anyone know what the situation looks like with on Windows? libstd currently assumes even small allocations to be aligned there, and agrees with that (Ctrl-F "on 64-bit platforms").
EDIT: C11 to C, but yes, malloc doesn't know anything about the alignment of a type. It still can be used, but the user needs to check whether the allocation is properly aligned. The docs are quite clear IMO: Anything more concrete than that will be target specific, and those details are outside jemalloc's control - if jemalloc wants to replace the system allocator in a target, it needs to comply with the ABI there. If it were to guarantee more, e.g., all allocations are 16byte aligned, it wouldn't work on platforms using the SysV i386 ABI.
Well, with that statement from the jemalloc docs is wrong, isn't it?


Question: #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); <del> let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); </del> <ins> // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. // Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::<usize>()); let ret = libc::posix_memalign(&mut out, align, layout.size()); </ins> if ret != 0 { ptr::null_mut() } else {

And for users to manually do the alignment, getting something more concrete would be useful. And also for Rust! Currently you are deducing a whole lot of things from a few words in the spec. I have zero confidence that this is the only way to read the spec. So something like: "for we guarantee an alignment of ; for smaller sizes we guarantee an alignment of the size rounded down to the next power of two." would IMO be prudent to ask from the jemalloc devs. Or else we'll find ourselves with more bugs when someone interprets all this slightly differently.
I don't know how useful would that be: malloc only needs to comply with the C standard. Parts of it are implementation-defined, and what those are defined to is often specified by the system ABI. That's the only thing the global allocator can rely on. On most platforms, the system allocator - which is the default global allocator for Rust programs - is not jemalloc - it is the one from glibc, musl, microsoft, apple, google, mozilla, etc. In some platforms, like FreeBSD, the system allocator is jemalloc, but even there we can't exploit that knowledge because users can just and now the global allocator is a different one. That's an use case we support. So even if jemalloc were to offer extra guarantees here, Rust's system allocator cannot make use of them. The only places were we can can exploit jemalloc's specific guarantees, is when using crates like jemallocator, to explicitly hardcode the allocator to a particular one. As in, if that allocator is not linked, you get a linker error or similar. But even there, it makes sense to stick to what C and the platform ABI guarantees, because jemalloc is free to break anything else in the next version.
Well it would save us this entire discussion. If that doesn't demonstrate its usefulness I don't know what does.^^ I don't know what the "system allocator" is for Linux, but the one in glibc actually guarantees a 16-byte alignment on 64bit systems for all allocations. So by that standard jemalloc would just be incorrect.
The platform ABI guarantees that. What the malloc implementations guarantee is irrelevant.


Question: #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); <del> let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); </del> <ins> // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. // Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::<usize>()); let ret = libc::posix_memalign(&mut out, align, layout.size()); </ins> if ret != 0 { ptr::null_mut() } else {

If glibc were to guarantee that all addresses are 32-byte aligned, there is no way in which we could exploit that information in the implementation of the system allocator, because the platform only requires 16-byte alignment, and it is valid to pick any allocator at run-time that satisfies that.
So there a document somewhere saying "for x86-64 bit, 16-byte alignment is guaranteed"? But that document contains an exception for small sizes, making s behavior legal?
Yes, there are documents containing the rules of what's legal, at least for Linux x8664. Those document allow an exception for small sizes. One API that uses those is , which requires the alignment to be at least , which is 8 on x86_64, and which allows you to allocate bytes, with a smaller alignment. I still have no idea what jemalloc has to do with any of this - your original question is about , and that has nothing to do with jemalloc. But yes, jemalloc exploits this behavior, to be able to satisfy 1 byte request, and return addresses that are 1 byte aligned. Otherwise each 1 byte request would consume 16 bytes of memory within a memory page.
A document that could be relevant is the C standard. Unfortunately, as mentioned in the commit message for , it is rather tautological on this topic: The standard does not give any numeric value. Like many other aspects of C, it looks like the actual value of is implementation-defined.
When using jemalloc, becomes jemalloc. That's how happened. Do you have a reference for something that concretely calls out an exception for small types? The C standard only does this very indirectly, as you showed.
That was a bug in our implementation of system that applies to pretty much all allocators, not only jemalloc. says (emphasis mine): Since the alignment of an object is a power of two that is always smaller than or equal to the object size, rounding down the alignment of an allocation to the previous power of two always produces an allocation properly aligned for every type that can fit it. That holds for all allocations, so there is no exception for that. That's the rule. Since that would mean that large allocations must be unreasonably aligned, the standard does provide an exception for allocations of size larger than than .


Question: #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); <del> let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); </del> <ins> // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. // Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::<usize>()); let ret = libc::posix_memalign(&mut out, align, layout.size()); </ins> if ret != 0 { ptr::null_mut() } else {

These only need to be aligned at an boundary. If you believe this is incorrect, please show a counter-example for which this doesn't work.
AFAIK it is a normal way of using to make it override the symbol? Don't we still do that in rustc, or when using "jemallocator"? I don't say it is incorrect, I say it is awfully indirect. It's like reading tea leaves. I am looking for a clear definite statement. That doesn't seem to exist though. :( There clearly is some kind of "non-continuity" where all allocations are aligned MINALIGN except for small ones. Or vice versa, all allocations are aligned "size rounded down to power of 2" except for big ones. You are convincingly deriving that non-continuity from standard wording. I don't say you are wrong, but this feels like interpreting ancient scripture. A clear spec looks different. Also, an object of size 2 with alignment requirement 4 is "fundamental" according to your definition, and yet rounding down the size to the next power of 2 does not give the right alignment. So your rule does have exceptions, namely types marked .
Can you show such an object in C and/or Rust ? It's probably the most common way of switching allocators. What does is it requires to be linked to your binary, allowing (and making use of) jemalloc-specific APIs. If you do this, when using directly (not ), you can obviously rely on assumptions that only hold for . But cannot do that because, then it wouldn't work with other allocators.
The goal is not to rely on assumptions that only hold for . The goal is to make sure that we do not make assumptions that don't hold for . Because that's what we used to do, before got fixed. We were assuming something that was true for system but not for : that all allocations, no matter the size, are aligned. To make sure we don't do that again, I want to be sure that all assumptions we are making hold for . That's why I'd like jemalloc to spell out what we can assume.
Ah I forgot about the stride vs. size thing. So such an object does not exist.


Question: #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); <del> let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); </del> <ins> // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. // Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::<usize>()); let ret = libc::posix_memalign(&mut out, align, layout.size()); </ins> if ret != 0 { ptr::null_mut() } else {

But such a exists, and it is something we want to support in our allocator API (we even have a test for that). And we do have objects with align size, namely all ZST.
Yeah, I agree. The only cases for which the "round to the previous power of two approach" doesn't work is for ZSTs, and types (or allocations) with align size. Since those just cannot happen in C, the C standard doesn't mention them as exceptions. That is, we can only call when that holds, and if it that doesn't hold, we need to call a different API that supports the align size case.


Question: // Explicitly check for lints associated with 'closure_id', since // it does not have a corresponding AST node <del> if let ast::ExprKind::Closure(_, asyncness, ..) = e.kind { if let ast::Async::Yes { closure_id, .. } = asyncness { self.check_id(closure_id); } </del> <ins> match e.kind { ast::ExprKind::Closure(_, ast::Async::Yes { closure_id, .. }, ..) | ast::ExprKind::Async(_, closure_id, ..) => self.check_id(closure_id), _ => {} </ins> } }

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --I don't have a minimal example yet, but here's . Sample: The ICE happens on the and macros, which are both from the crate. <!-- 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 began with commit . <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
FYI, I think that link is only accessible to Googlers: !
Sorry, .
Minimized: Caused by
When we run on the AST, we create a definition for the desugared closure body inside an : As a result, the entry for our macro call will have the of the desugared closure. However, this desugared closure does not actually exist in the AST (it is created during lowering), so we will never check for lints with its when we emit buffered early lints.
Nightly has been broken for 3 days, if there's disagreement on how to fix the issue, can we revert while the fix is being worked on?
This will be fixed by PR
I'm still hitting this bug with the latest nightly.


Question: ignore_fmt.add(&format!("!/{}", untracked_path)).expect(&untracked_path); } if !check && paths.is_empty() { <del> if let Some(files) = get_modified_files(build) { </del> <ins> if let Some(files) = get_modified_rs_files(build) { </ins> for file in files { println!("formatting modified file {file}"); ignore_fmt.add(&format!("/{file}")).expect(&file);

When there was a change in a or other non-rust file, bootstrap tries to format it, which makes rustfmt very sad. cc and who broke this in <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I think we just need to filter .rs files before passing them to rustfmt.
This will probably be hit a lot by contributors so I'll pin it for better visibility.
claim
Normally, the walker already filters for files, per Maybe the crate docs are not fully up to date, or I didn't understand them correctly.
The workaround is to run (notice the dot at the end of the command).
I think if we add it like this: will always not ignore it anymore.
Maybe try to put the part I before the ignore part, maybe this makes the ignore list work again? The thing that intrigues me the most is the fact that the files are not ignored later by the file type filter.
For any Rust files we changed locally, our current solution will try to format it, in some scenarios we may not want to format it, such as some files in UI?
Seems right, my current fix is not completed.
I think since you explicitly add the files to , that overrides the types filter.
from my local experiment, seems is still expected, I changed some files which ignored in , they are actually not sent to formatter:
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: <ins> // check-pass use std::error::Error as StdError; use std::pin::Pin; use std::task::{Context, Poll}; pub trait Stream { type Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>; fn size_hint(&self) -> (usize, Option<usize>) { (0, None) } } pub trait TryStream: Stream { type Ok; type Error; fn try_poll_next( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Ok, Self::Error>>>; } impl<S, T, E> TryStream for S where S: ?Sized + Stream<Item = Result<T, E>>, { type Ok = T; type Error = E; fn try_poll_next( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Ok, Self::Error>>> { self.poll_next(cx) } } pub trait ServerSentEvent: Sized + Send + Sync + 'static {} impl<T: Send + Sync + 'static> ServerSentEvent for T {} struct SseKeepAlive<S> { event_stream: S, } struct SseComment<T>(T); impl<S> Stream for SseKeepAlive<S> where S: TryStream + Send + 'static, S::Ok: ServerSentEvent, S::Error: StdError + Send + Sync + 'static, { type Item = Result<SseComment<&'static str>, ()>; fn poll_next(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Option<Self::Item>> { unimplemented!() } } pub fn keep<S>( event_stream: S, ) -> impl TryStream<Ok = impl ServerSentEvent + Send + 'static, Error = ()> + Send + 'static where S: TryStream + Send + 'static, S::Ok: ServerSentEvent + Send, S::Error: StdError + Send + Sync + 'static, { SseKeepAlive { event_stream } } fn main() {} </ins>

Trying to build  0.2.5 with latest nightly results in an ICE. Bisected the regression to , cc I have tried to minimize it. This still requires 0.3, I'm not sure how to minimize if further. <!-- 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
Seems like a duplicate of
I don't think that is related, neither the error matches nor is it a recent regression. Did you link the wrong issue? fixes this ICE
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-high
Still needs a backport
(assigning self to ensure backport happens.)
Also seen in the latest (): zebra-consensus: https://crater- warp v0.3.1: https://crater- linkerd: https://crater- Along with a number of others.
Backport () was merged.


Question: /// // Calculate how many bytes can be written without flushing /// let without_flush = capacity - buf_writer.buffer().len(); /// ``` <del> #[unstable(feature = "buffered_io_capacity", issue = "68833")] </del> <ins> #[stable(feature = "buffered_io_capacity", since = "1.46.0")] </ins> pub fn capacity(&self) -> usize { self.buf.capacity() }

adds methods to and . Unresolved questions:
Can I nominate this for stabilization? It's a straightforward API with no real alternatives possible, and I had a real-world use case for it recently.
CC --^?
fcp merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [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. The RFC will be merged soon.


Question: <ins> // edition:2021 // run-rustfix #![allow(dead_code)] async fn a() {} async fn foo() -> Result<(), i32> { Ok(a().await) //~ ERROR mismatched types } fn main() {} </ins>

This code: produces: Which is invalid. Looks like the span of the desugaring of uses only the part, instead of the span of the entire expression. This results in invalid suggestions when used by the code in .
I'm not entirely sure if this means that desugaring should use a bigger span, or if the suggestion diagnostic needs to be interpreted differently.
hmm.. is the only case where the desugared expr's span doesn't cover the whole piece of code it comes from? That doesn't sound right. If wonder if the expr should have the bigger span by default, and then async-specific code could grab the tighter span for diagnostics that need to point at the operator.
Some of the desugaring only uses the span, but the parts relevant for diagnostics like this do use the full span. Not sure if there's a problem there too.
I thought I might have accidentally introduced this bug in , but right after that PR was merged, the output was correct: So something changed in the last two months in what spans are used for await desugarings, it seems.
actually I think it was introduced in in , cc Do you need someone to fix this? I'm happy to put up a quick PR.
Yeah, looks like it: I just finished bisecting, which pointed at a rollup involving .
this was introduced in the PR linked earlier to try and improve other errors. It is tricky because reducing the span to only incurs these kind of bugs. On the other hand, the errors that got improved there became much less noisy, so I wouldn't want to revert the whole change. My fix above will solve this issue, but I'm sure there will be others in the future :-/


Question: /// # Examples /// /// ``` <del> /// #![feature(osstring_ascii)] </del> /// use std::ffi::OsString; /// let s = OsString::from("Grüße, Jürgen ❤"); /// /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase()); /// ``` <del> #[unstable(feature = "osstring_ascii", issue = "70516")] </del> <ins> #[stable(feature = "osstring_ascii", since = "1.53.0")] </ins> pub fn to_ascii_lowercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_lowercase()) }

<!-- Thank you for creating a tracking issue! Tracking issues are for tracking a feature from implementation to stabilization. Make sure to include the relevant RFC for the feature if it has one. If the new feature is small, it may be fine to skip the RFC process. In that case, you can use use in your initial implementation PR. The reviewer will ask you to open a tracking issue if they agree your feature can be without an RFC. --Feature gate: <!-- For most library features, it'd be useful to include a summarized version of the public API. (E.g. just the public function signatures without their doc comments or implementation.) --<!-- For larger features, more steps might be involved. If the feature is changed later, please add those PRs here as well. --- [x] - Stabilized traits necessary to obtain [x] - Added ASCII methods on [x] Final commenting period (FCP) [x] - Stabilization PR <!-- Once the feature has gone through a few release cycles and there are no unresolved questions left, the feature might be ready for stabilization. If this feature didn't go through the RFC process, a final commenting period (FCP) is always needed before stabilization. This works as follows: A library team member can kick off the stabilization process, at which point the rfcbot will ask all the team members to verify they agree with stabilization. Once enough members agree and there are no concerns, the final commenting period begins: this issue will be marked as such and will be listed in the next This Week in Rust newsletter. If no blocking concerns are raised in that period of 10 days, a stabilzation PR can be opened by anyone. --<!-- Include any open questions that need to be answered before the feature can be stabilised. If multiple (unrelated) big questions come up, it can be a good idea to open a separate issue for each, to make it easier to keep track of the discussions. It's useful to link any relevant discussions and conclusions (whether on GitHub, Zulip, or the internals forum) here. --- None yet.
Just needed to manipulate paths on windows -- I need to lower case driver letter, -.
Currently, SQLx contains The UTF-8 check that is included in there, while not a problem in practice, seems pointless. Changing to lands me here because of the .


Question: /// # Examples /// /// ``` <del> /// #![feature(osstring_ascii)] </del> /// use std::ffi::OsString; /// let s = OsString::from("Grüße, Jürgen ❤"); /// /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase()); /// ``` <del> #[unstable(feature = "osstring_ascii", issue = "70516")] </del> <ins> #[stable(feature = "osstring_ascii", since = "1.53.0")] </ins> pub fn to_ascii_lowercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_lowercase()) }

Also, if somebody did a similar thing with instead of , the version could drop that and would then be a bit less noisy.
is a stabilization PR. Since lib team wants to do fcp in the tracking issue. could you start one ?
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] [ ] Concerns: 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.
Slight question about -- normally when dealing with AsRef args, they come in without an explicit reference in the signature (), except when necessary to support a lifetime in the return value (). Currently is declared as: Is this supposed to be instead? concern eqignoreasciicase &S
I think it should be. I'm not sure why I wrote it like I did originally, but this makes more sense to me. I can make that PR if needed. Or can it be done in the stabilization PR? Not sure what the process is from here.
resolve eqignoreascii_case &S reviewed Fixed in .
: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. The RFC will be merged soon.
you can tick the FCP box, as the FCP is complete.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ad378a; --trait-link-color: #6e4fc9; --assoc-item-link-color: #3873ad;

Following , we realized that rustdoc users would prefer to have a syntax extension rather than using plain HTML to have warning blocks. suggested the following: suggested: What do you think? cc
Personal Opinions: The first style will look fine for short forms, but I'm not sure for longer text. A possible syntax: Which to me pushes the text too far right. Not having any spacing, but just separating with newlines, seems hard to parse at a glance what is part of the WARNING, and prevents multiple line breaks inside the warning. Also, it's not as extensible. INFO can be , but if we ever want more extensions, they would increasingly possibly conflict with other things. The second style makes it immediately clear what is part of the block, and is unlikely to accidentally conflict if we ever want to add more block styles. It also supports multiple lines or inner blocks trivially. A final advantage is that it may support nested blocks, in case those ever come to be useful. Overall: I prefer the second form, both aesthetically and for future-proofing
I think I agree with in preferring the second form. I like the first form's simplicity, but it also seems surprising that is treated as a 'keyword' and will change the formatting of the docs.
That's why we have this debate. :stuckouttongue:
I personally actually prefer stabilizing a CSS class, I think we should do more of that, just because parsing can get annoying. But this is not that hard to parse anyway. The problem with is precisely that you can't scope it easily: what if you want to add code blocks? bullet points?
The problem with this is it ties rustdoc to the HTML backend; like I said nothing rustdoc currently does guarentees that it will generate HTML from the markdown. Changing that means that to make the JSON backend have the same info, we'd have to add a full HTML parser to rustdoc just to read the HTML in the markdown, because pulldown does not parse HTML for us. I really think we should avoid making the JSON backend a second-class citizen.
Also there's not much point to this if it's just a little CSS IMO, you can add that yourself with and it will look just as good and be more flexible since you can control the styles yourself.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ad378a; --trait-link-color: #6e4fc9; --assoc-item-link-color: #3873ad;

I'm not a giant fan of the syntax because it looks odd when rendered by anything other than rustdoc, which I'd rather avoid, one of the major design concerns for intra-doc links was compatibility with other markdown parsers:
So, I agree, but I'm not convinced that the warning class is something that needs to be surfaced in the JSON backend as anything special. Also, bear in mind, HTML is a part of markdown: valid HTML (well a subset of HTML) is valid markdown. Users already can , and they do that in many cases. Markdown parsers already need to be able to handle HTML. There's nothing new there. Whatever consumes the JSON backend will need to be able to handle that too. I mean, yes, in theory, in practice people don't do this because of the barrier to entry (you have to get your tools to use that, including )
Also, this is incorrect, pulldown absolutely parses HTML. It has to, like I said valid HTML is valid Markdown. It doesn't parse it thoroughly, I believe you can mess it up with sufficiently complex HTML, but it parses HTML. What this changes is subtler: up till now you did not need any particular stylesheet to acceptably render rustdoc markdown from the JSON backend on your own (just use your favorite markdown renderer's stylesheet), but now you will need other css classes to handle rendering warnings as warnings.
I do not agree that this is a problem. I've used Phabricator's implementation of this approach happily and it is by design that warning banners are one paragraph. It is not the intention that you would put entire sections of documentation into a warning banner. They are for a brief callout. It's fine to refer to a subsequent section of the documentation from the callout if needed. I suppose this is a matter of taste but it's one where I believe the opinionatedness of the syntax is a positive thing.
So I discussed this a bit with on the side, we agree that the effect on the JSON backend isn't major since HTML is already a subset of markdown and docs use HTML already (especially for images and tables). My position is as follows: I strictly prefer HTML over some other scoped syntax with nuances people have to learn. I don't think there's as much value in unscoped syntax which makes my position "HTML or nothing", basically.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ad378a; --trait-link-color: #6e4fc9; --assoc-item-link-color: #3873ad;

I'm not wholly against unscoped single-line syntax. We and syntax in W3C specs and you invariably need to add more stuff to it (there's an HTML class in these specs for this reason). Furthermore, Rust has a strong culture of wrapping text, so this means we need to work well while wrapped, and that means we're again introducing some form of scoping mechanism (e.g. indenting the text), which editors will have to learn, as well.
I don't know about admonitions specifically but there seems to be something of a community habit to use "magic tags" on fenced code blocks for this sort of features (e.g. github has a tag), maybe that could be an option? I don't know if pulldown_cmark has a hook for manipulating code blocks but… So a warning would be or maybe the tag would be to leave room for things like note/todo/danger/… Alternatively, take a gander at how other markdown implementations extend the language for this sort of features? e.g. seems to be using for admonitions.
Hmm, but is still for code, even if it has some extra behavior. Aside from the design concerns, this would be feasible to implement: we just extract the language string from the code block with pulldown.
Could you use something that's already built into markdown? For example, rustdoc could take and render it as an admonition.
That's what suggested: to use markdown and make some changes on rustdoc side. I think the codeblock approach is the best personally.
My bad, I didn't see that.
I wonder if it makes more sense to add this as a proc-macro. Rustdoc can still provide the CSS classes and things, and you could use them with HTML directly, but you could use or something and it would expand to the correct HTML tags and classes.
Might be better to have a then, no?
Is that going to be a special header similar to the "unsafe"/"experimental"/etc ones, or is that going to also be used within docs in an order-sensitive way? If the latter we should probably just use a CSS class; mixing and is ugly
Agreed.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ad378a; --trait-link-color: #6e4fc9; --assoc-item-link-color: #3873ad;

Among the suggested ideas, my favourite one remains the code block with "warning" as tag:
Yeah, but triple backticks is also for preformatted text without further markup, so you won't be able to e.g. use text formatting (or other code) in there
True... Finding the right syntax is much more complicated than expected...
That's the issue of using markdown, for all that it has a pretty nice baseline syntax it really was not designed for extensibility.
We can always use : it'd allow to have text formatting inside it.
I would use , it's not quite kosher to invent arbitrary HTML tags (though you can use Custom Elements, which is more heavyweight)
Sounds good to me. It's funny because we kinda came back to the . :rofl:
I just thought: we could use tag in the markdown and then transform it into in the generated HTML?
My main objection to all of these is that rustdoc shouldn't be adding custom markdown syntax that no one else supports. Any new syntax we use should look reasonable even if rendered with the default renderer.
Well, it remains valid markdown since it's HTML (even though it's custom tag). I'm completely fine with , but it might be simpler/better for users to simply write .
Coming back to this (because of ), it seems like the conversation kinda agreed on adding a CSS class directly and then it would look like this in the docs: . I'll send a PR in the next days and then we can open an FCP to see if everyone is ok with it (and if not, we'll have code to help the debate).
This indeed seems like a better solution than the HTML block. It also plays better with something said about not linking it too much too HTML. This will look like a proper warning or note, mostly independent of the HTML generation.
They also seemed to not be too favourable to anything that needs some extra parsing from rustdoc iuc. I'm fine with bot the github solution and the CSS class.
Maybe one more comment to make here. The note-taking app, which uses Markdown also has a similar syntax to create these blocks. It is called . It uses a syntax similar to the syntax that is used for doc intra-links currently, and it is fully compatible with them.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ad378a; --trait-link-color: #6e4fc9; --assoc-item-link-color: #3873ad;

I am uncertain if this is any better than what suggested from the GitHub syntax, but because of the similarity to the doc intra-link syntax. I do feel like this might be interesting because it should go well with backwards compatibility. However, this may look worse than the GitHub syntax solution when not going through cargo doc.
I thought I'd already left this comment, but I'd really like to avoid adding more markdown syntax where possible. This feature works fine without special syntax, I don't think we need it. edit: copying over the reasoning from the :
Although, I might not agree fully, I can fully appreciate and understand the reasoning you left in the corresponding PR. Still, I do think it might be worth to standardize some kind of syntax for some kind of warning block. This does not actually require customized markdown. Alternatively, I can suggest adding the GitHub flavor with emojis to the . This may help in standardizing short form warnings and notes within documentation. We could for example propose to standardize: which should look like the following I do value people's opinion on this. Is this a possible compromise?
That's a valid alternative, I think the yellow color is pretty important though, and it's useful for themes to be able to make styling decisions about warnings so I do think that having some way of marking it is important. I just don't think the way of marking it should be some magic invocation as opposed to CSS classes. (And I think that the bar for a feature that is adding new semantics to the Rustdoc markdown parser is much, much higher than that of one stabilizing a CSS class)
100% agree. I will look at the Rust API guidelines issue and possibly an RFC to rust to track the adoption in GitHub and possibly eventually merge. Thank you :smile:
Beyond all this discussion of third-party tools, I'd really like to make sure that whatever new syntax and presentation we add to rustdoc can also be to [mdBook]. That way, when the standard library starts using callouts, we can make sure the same style also gets used in The Book. Mostly, The Book seems to just use blockquotes, often with headings like [this one about ownership]. mdBook doesn't do anything special with it: it's [just a block quote with a header].


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ad378a; --trait-link-color: #6e4fc9; --assoc-item-link-color: #3873ad;

[mdBook]: [this one about ownership]: [just a block quote with a header]:
This is a good point. Once we have something merged here, I'll send a PR there to have an equivalent.
CC
I'd be happy to add some CSS rules to mdbook if that is what you are proposing.
Yeah, it is.
FYI, using a is not semantic and Microsoft GitHub is setting a bad precedence. — CommonMark Spec v0.30, denotes a in Markdown and is rendered as such. — W3C HTML spec, Unless you are quoting a source, this is not the correct element to use. While I disagree with even using altogether, at least some tools out there are at least translating the blockquote in admonition context into a (div has no semantic meaning which is unfortunately the best HTML option for admonitions). It would be ill-advised to follow Microsoft GitHub’s Markdown syntax fork—especially with their disregard for semantics. Similarly using a block would also be breaking semantics as an admonition is not preformatted text. CommonMark does have that could be used if the solution was preferred. There’s also other reasonable options noted here that don’t break semantics.
I agree that block quotes for callouts are bad, and would like to work with mdBook to roll out a common syntax (probably ) that will replace the ad-hoc, unsemantic markup that they use right now.
Using is what we agreed upon in The debate now is on the look itself.
Unfortunately isn't great because markdown has a "boundary" when HTML tags are used. I wanted to add a warning indicating that users probably wanted another trait, but intra-doc links don't work (which is the correct behavior per markdown spec).
Works perfectly fine though (well, minus the UI bug I just discovered haha): ! I used this code: I'll send a PR to improve documentation.
Ah. Well I suppose the issue wasn't with intra-doc links, but with inline code blocks. What I tried was that but with bar`, and it failed.
Works too: !
I opened which adds extra explanation on how to use markdown inside html tags. That should solve your issue.
That note is exactly what I was just looking in to. I had it inline, given my familiarity with HTML. TIL that matters.


Question: --codeblock-error-color: rgba(255, 0, 0, .5); --codeblock-ignore-hover-color: rgb(255, 142, 0); --codeblock-ignore-color: rgba(255, 142, 0, .6); <ins> --warning-border-color: rgb(255, 142, 0); </ins> --type-link-color: #ad378a; --trait-link-color: #6e4fc9; --assoc-item-link-color: #3873ad;

It doesn't hurt to have it and if it can helps users, well, why not doing it. :)