jiebi/CodeConvo huggingface dataset:
CC Pushing this idea further, it’s tempting to maybe remove entirely and instead have a whose dynamic type can be . But that doesn’t work because is a method of and is not .
I thought the point of the message field was that core can't make a payload since it can't allocate?
The struct is: Both the and fields involve borrowing. As far as is concerned, they could both be borrowing form a stack frame. (And as far as I understand they are, in practice today.) It’s in the case of unwinding that there’s an owned that can return, which requires allocating.
Based on the timing of it looks like you may have thoughts on this :)
Ah, goes into how and why the panic handler in libstd (which is called by if libstd is linked) ignores the it receives. We could probably change this but it gets tricky: while most implementations of for environments would be fine with receiving a borrowed payload, libstd wants to potentially take ownership and box it for unwinding.
I have zero recollection for why this is the way it is, and I'm not really particularly interested in doing all the archaeology to dig up why it is the way it is. I'm not a huge fan of just stabilizing things because they happen to be there, but I don't really see why we wouldn't want to stabilize this. If there were a reason to not stabilize this though an investigation would presumably turn that up, but I'm not up to do that investigation myself.
That’s totally fair. I’m confident that this was more likely forgotten than deliberately left unstable. If deliberate we would have kept the tracking issue open or made a new one for the remaining bits. This is what lead me to propose stabilization. Having dug a little more, and thanks to Ralf’s blog post, I think we may want at some point to revisit what data we expect to contain or not in various situation. In particular it could be interesting to extend to support payloads other than and make it closer to . Given those possibly-desirable changes, it may not be the time to add more constraints: fcp cancel
proposal cancelled.
Lol, I had no idea. ;) So, indeed, I was wondering if we could do something about the duality of the and fields in . I assume we cannot change the fact that the same type is used both of panic handlers and panic hooks.
Concretely, I was thinking of adjusting somewhat like this: That would at least remove the need for the hack in . (The hack would likely move to instead, but that is a smaller hack IMO: the hack is now not encoded in the state of any more, just in its dynamic API.) I think this would retain all current functionality while clarifying the invariant of wrt. the payload (and explicitly calling the message a "payload"; right now it seems to be something that sits next to the payload which is inaccruate). But there are enough subtleties here that we'll only really know once someone implements this. With this change, the panic hook would always get a . We should likely provide a method somewhere in libstd to factor out this code: I was imagining something like an extension trait on with a type like . However, the panic hook is not the only place where that conversion is useful; another situation is code that caught a panic and wants to extract the message. I expect most instances of that to just handle payloads, not knowing that payloads are also common (that is certainly what happened when I wrote such code). So ideally we'd have a method that takes and returns , but I do not have a good idea where to put that. This is the hard part, as we cannot use . I wonder if we can use a take-based approach, similar to ? Conceptually, would put the panic into an , and somehow pass an to the panic handler, and the implementation of said handler could then the payload if it needs full ownership (like for unwinding). Except the panic handler cannot be generic, so it would have to be , which is not a thing. But with enough unsafe code we could re-implement something that behaves like that. I don't see any way to do this entirely safely; the panic handler that wants to take out the payload and put it somewhere needs to dynamically determine the size of the payload and arrange for there to be enough space. In liballoc, we could provide a safe wrapper for this that puts things into a , but in libcore, I don't think there is a safe API that we could provide to grab ownership.
But maybe it is enough for the public API to expose ways to borrow the payload (should work for all non-unwinding handlers); if only libstd needs to take the payload (for unwinding) we could keep the unsafe part of the API internal. Also, we certainly do not want a panic hook to the payload out of its . At this point it seems to be quite a problem that panic hook and panic handler both use the same type. In fact, a panic handler likely wants a to be able to things without interior mutability. Is there any way we could make the attribute support both signatures, and then (based on the types of the methods) only -based implementations will actually be able to or the payload?
I agree, but it’s can easily be an inherent method of nor of because those are in libcore which doesn’t have access to . It feels slightly unfortunate that we’d need an extension trait just for this. I considered this yesterday and come to pretty much the same conclusions. To take ownership of a payload of unknown size through a non-generic API we pretty much heap allocation, which for libcore means something like receiving an , unsafely using , and returning that is to be passed to . It’s not pretty, but if only libcore and libstd deal with this internally maybe that’s ok? Is there a use case for a other than libstd’s to take ownership of the payload?
I was thinking of a slightly different API actually: Here, does to put the payload into caller-allocated storage; that storage must have (at least) size and align as given by . What I did not consider is how to get out the vtable, so maybe that higher-order approach is better.
We discussed this in the libs-api meeting today. We concluded that before stabilizing this, we need to make sure it works (doesn't return ) for std::panic!() as well. That is already the case with Rust 2021's std::panic!() (since it's identical to core::panic!() in this edition), but not for Rust 2015/2018's std::panic!(). Once that is fixed, we feel okay with returning a placeholder message for non-string panics (panics from or Rust 2015/2018's ), at which point the function can return an unconditionally, rather than an .
(And also, should be returned by value, not by reference.)
Any progress on stabilization?
It would great to have this little feature.
Still nothing? What's missing?
can this be stabilized after was resolved in the pull request ?
Yes, soon, hopefully! I've updated the overview at the top of this tracking issue. The main question left before stabilization is the return type of the method. Should this return (as the unstable method does today), or should it return an opaque type that wraps that fmt::Arguments, so we can still change in the future? (In case we want to support different types of no_std panic, such as panicking with an Error or something.)
Can it return or so?
I would vote for an opaque type that would also implement .
Did that in this PR:
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] 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.
On identifiers that have more than one word, it is relatively common to write them in the wrong order ( → ). These are normally not found by Levenshtein distance checks, but we could do a basic "split on ``, sort and join before comparison" so that we could suggest the right identifier. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
I'd like to try to work on this. As is short enough to be caught by the Levenstein distance, I wrote for testing: claim
I'm thinking about the priority of the different possible matches. I tend to think that a match found by levenstein distance should have a greater priority, but what do you think?
it's tricky. I feel that your instinct might be right but we'd only know when looking at real world usage. The nice thing is that the lev distance check by its very nature it is limited, so doing the swapped words check as a fallback should work out ok in practice.
Releasing my assignment, as I am not sure to be able to commit. In case someone want to take on this, here is the function that should be modified. release-assignment
(I think this is appropriate, please tell me if it isn't) modify labels to +E-Easy
I can take a stab at this, seems reasonable with previous comments. claim
Happens on WIndows 7 x64 with latest Rust 32-bit nightly. : (On a side note, is there any way to work out what the latest released nightly version is?) : Compiling with produces: is there to suppress the warning, can be removed if you compile the rest as a library. Also works if you substitute the expression for directly and if you pass two arguments (the original use case). The original intent was to tell if two s were identical as a sanity check.
Can confirm this still results in an ICE.
Triage: still ICEs.
cc rust-lang/rfcs
fixed this.
I'll add a regression test for this
<details<summaryBacktrace</summary</detailsWindows 10 (64-bit)
Which code had caused this assertion? Caused by this assertion: Which was introduced in , which is beta-nominated. cc
I'm glad I that assertion! What it likely means is that isn't a multiple of . I'd be quite surprised if and/or weren't involved.
In my case this error is caused by the crate. Simply including it in your and compiling crashes rustc. <details<summaryBacktrace</summary</detailsI'm on Arch running the latest nightly rustc.
Looks like triggers the assertion, and it has alignment but size (which is illegal), IIRC, includes some types that are ( this is indeed which has a packed ) and has caused issues in the past as well. EDIT: minimal repro:
When setting the directory to persist doctests to if an UNC path is used on windows there's a segfault. The offending setting of persist-doctests: . cargo-tarpaulin sets this programatically using a path it gets for the target directory from cargo-metadata. The path from cargo-metadata is an UNC path and this then causes a segfault. I'm going to detect UNC paths in my code and remove the on windows, but I felt this warrants a bug report as someone else will hit it eventually. Also, I'm not sure if other parts of the compiler fall prey to this issue? Compiler version is: the latest nightly (1.64.0-nightly 2022-06-28) The stack trace: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
This panic is also triggered in Linux if e.g. trying to write into a directory that the user has no permission to write. I PR'd fix to change the unwrap to more orderly panic and relaying the underlying error detail via eprintln! ~/gg/rust/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc --test -Z unstable-options --persist-doctests /tmp/foobar Couldn't create directory for doctest executables: Permission denied (os error 13) instead of:
The lack of ICE is definitely nicer, but this still won't handle UNC paths on windows will it? Which is the main issue I personally have with the code
That's a problem for std::fs::createdirall(&path) me thinks has to be fixed there
Makes sense looking at the code, should I raise another issue for the libs team?
Actually, yes it would be great to raise another issue targeting std::fs::createdirall - as it is wider issue. you are right. Thanks!
So isn't this an issue with the tool generating an incorrect argument?
So the paths are weirding me out (I normally only use linux), because they seem to sometimes print differently given different display methods. It shows up as printing the path in my rust code before making the env var, and if I print the rustdocflags I'm setting it's correct.
But if I do it returns false, I have to do for it to return true. I'll raise the other issue and after work look into it more properly try to make a better MRE for windows
do you mind changing title s/UNC/invalid/ to address the panic on this issue, thanks! :)
also please remove s/on windows// thanks a lot :+1:
Done, and I realised what was wrong with the path, it's correct in the code, it's just when it got set into the environment variable it seems it needed the first slash to be escaped and that caused the invalid path (so no issues in std::fs need fixing)
claim label +I-ICE +T-RUSTDOC
STR (on Linux): file that has generics usage () code DWARF info Notice that contains such entries as , possibly produced by the fact that "" is a relative path and DWATcompdir is set to "/home/yury". It is expected for core files to have absolute path e.g. ""
cc I wonder what interaction (path rewriting?) causes this result.
FWIW, produces that shows that !DIFile entries has the directory field empty (and the filename is relative)
It is a regression, since +stable has absolute locations, e.g.
could this have to do with
Likely so! I'll try to look into this in the near future
Ok so the change here can be exhibited with this script: If you execute that script you see: but if you remove you see: It appears that if upstream crates (like libstd) use then their filename is listed as the original relative source file instead of the absolute path name that it had previous to when it wasn't compiled with . So somehow using to compile libstd is affecting downstream crates to have relative path names instead of old absolute path names. It makes sense to me that the absolute path name goes away with (that is the whole point after all) but ideally it'd still be an absolute path, just applying the mapping. would you be able to help point me in the direction of where this change in logic might happen? If so I can test out a patch!
This should be what you're looking for: One solution would be to compile libstd with absolute paths and apply proper remapping to those.
Ah that's perfect! I'll see if I can work up a solution to that soon
<!-- 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. --(reduced) (original) <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Please try to minimize the example as much as possible:
claim
heads up that already put up a fix
Thanks Just want to add that some other intrinsics also ICE. For example: ICEs as well.
Interesting -- I wonder if we should perhaps fix this in a less specific way than . I wonder if we should instead detect that the declaration is not valid b/c has not been enabled in the crate... If not, then I'd be glad to review a PR that fixes whatever other intrinsics you find to make too many assumptions in the compiler.
Even adding does not prevent the ICE unfortunately. It happens in due to the wrong number of arguments e.g. here for : occurs for a lot of intrinsics in this file. I'm guessing all of them will ICE under the conditions in this issue. To fix it, we could extend what's done for in to all intrinsics, maybe leveraging this code to know how many args are expected for any given intrinsic:
I have opened
Looks like intrinsics are expected to ICE if used wrongly (see comment: ) so I opened has been rightly closed. But that mean that should also ICE in these conditions. However, in the present issue it was ICEing for the wrong reason i.e. out of bound access . So does the right thing by stopping that. However, IMHO it should not taint the context and let it go to MIR lowering and then let it ICE there. That keeps consistent with other intrinsics' behaviour as noted above. Thoughts & If you guys agree I can open a PR to remove the tainting.
See which takes a different approach
Nice!
When encountering a , there must be a corresponding in the MIR body. If there isn't, later passes can panic due to indexing out of bounds of the array. The validation pass could detect this problem earlier. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Instructions: Extend the validation pass in by implementing for the MIR visitor: The trait is documented . The method should check that the local exists in , and fail with a descriptive error message if not (by calling , not by panicking directly).
claim
FYI, the validation pass currently fails on even libcore until is merged, so you need to either wait for that, or cherry-pick some commits from there to get it to work. You can test your changes by running (the validator only runs on very little code by default, turns it on for everything).
I wanted to double check, running should fail when I run it, right? It actually passed for me after I merged in your branch from I wonder if I should try clean and build stage 1 again. :
It should pass with applied, but fail on current master.
So your PR fixes this issue () as well?
Ah, no, this issue is just about adding additional validation. It shouldn't actually detect any locals that don't exist. So the command should work both before and after implementing this. If it fails after implementing this, something else is going on that we should look into.
are you still working on this?
No, sorry. Didn’t have time for it. Go ahead.
release-assignment
Would like to work on this, but it seems there is another check, not on the declaration like this one, but on the memory liveness. This should cover the case that the local is not declared (I think), or would it not?
<!-- 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: /// let example = Example::new() /// .first("hello") #[cfgattr(not(feature = "one"), doc = " .second("hello")n")] /// .third("hello") /// .build(); /// with I expected to see this: ! Instead, this happened: ! <!-- 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. --: running over the code gives me /// let example = Example::new() /// .first("hello") /// .second("hello") /// .third("hello") /// .build(); ///
As explained on discord, <strikethe attributes aren't applied to doc comments</strike(EDIT: they are applied, the problem seems to be that it results in two doc comments for rustdoc). However, your doc comment is split in two so the second half isn't considered as being inside a code block, explaining why you have this display. Even if shows it as one doc comment, rustdoc sees two of them. <strikeMaybe we should add a warning or something that attributes aren't applied to doc comments... What do you think ?</strike
How can an attribute get applied to a doc comment? Both are, under the hood, attributes, no? I would expect that to be equivalent to expecting to only derive Debug if is passed, which is not how that works. I'm guessing what is true is that attributes directly written don't actually merge with -style comments. Potentially relevant: , ,
Simplified reproducer rust //! foo(); #![doc = " bar();"] //! Checking with 1.31.0 it still ignores it (so likely not related), but checking with 1.21.0 (and 1.0.0) it worked as expected, so somewhere within that range (but I don't have any other versions installed at the moment to check).
Compilation broke somewhere between 1.23.0 (works) 1.24.0 (does not work) I tested it with rust //! let x = r#" #![doc = " bar();"] //! "#; //! assert_eq!
(x, "n bar();n"); //!
They are not supposed to be applied to a doc comment I do not think that. Your example would make sense for which I also consider to be wrong, but I am talking about which should insert the attribute conditionally but that is not the point. It might help to illustrate my thought process; We have some kind of documented item: rust /// let example = Example::new() /// .first() /// .build(); /// and each of those is turned into a doc attribute rust"] #[doc = "let example = Example::new()"] #[doc = " .first()"] #[doc = " .build();"] #[doc = " In a later step those attributes would then be concatenated and parsed as markdown or whatever. I want to use this behavior to document items conditionally, depending on which features the crate user has enabled. One way to do this would be to do rust let example = Example::new() .first() .build(); rust let example = Example::new() .first() .second() .build(); but that would blow up the source code with many duplicate lines, where only some minor things were changed. So I thought that it might make more sense to conditionally include a doc comment like this: rust /// let example = Example::new() /// .first() #[cfgattr(feature = "one", doc = " .second()")] /// .build(); /// which would turn into rust"] #[doc = "let example = Example::new()"] #[doc = " .first()"] #[doc = " .second()"] #[doc = " .build();"] #[doc = " or rust"] #[doc = "let example = Example::new()"] #[doc = " .first()"] #[doc = " .build();"] #[doc = " depending on whether the feature is enabled. So the attribute should not be inserted and not applied to the following doc comment. The weird thing is that the manually expanded version is working as expected. rust"] #[doc = "let example = Example::new()"] #[doc = " .first()"] #[cfg_attr(feature = "one", doc = " .second()")] #[doc = " .build();"] #[doc = " but this is very unhandy to work with :/
I was randomly looking at passes for another reason and noticed what is likely the source of this issue.
There are two relevant passes: runs second and removes leading columns of whitespace from the docs. This runs on a single "doc fragment" at a time, because of merging that normally means the entire documentation string, but since sugared and raw docs aren't merged they remain as separate fragments and use their own widths of leading whitespace to strip.
That also matches up with first released in 1.24 which introduced this distinction between doc kinds in order to fix , which IMO was user error in not matching the indent depth.