jiebi/CodeConvo huggingface dataset:
, let FRU keep its current hygienic (aka "privacy violating") semantics, but also make FRU something one must opt-in to support on a type. E.g. make a builtin trait that a struct must implement in order to be usable with FRU. (Or maybe its an attribute you attach to the item.) Advantages: Also seems really simple to implement (in the language). Accommodates users of FRU for the example. Drawbacks: If we did this, it would impose a burden on all code today that makes use of FRU, since they would have to start implementing . Thus, not simple to implement for the libraries and the overall ecosystem. , a hybrid between the previous two bullet-points: By default, treat FRU as non-hygienic expansion, but add a builtin trait that one can opt-into to get the hygienic (aka "privacy violating") semantics. As a bonus, perhaps implementing on a struct would also imply implementing on that struct, which seems like it would basically give us something very similar to the semantics desired by (Or, again, maybe its an attribute you attach to the item. This detail does not particularly matter to me.) Advantage: While this is obviously more complicated than the previous two bullet-points, it has the advantage that it has a staged landing strategy: We could just_ implement the change to FRU to be non-hygienic expansion for 1.0 beta. We could add at an arbitrary point in the future; it would not have to be in the 1.0 release. Drawback: People have claimed that some of my past proposals were a bit ... baroque. I imagine this one is no exception. :) (In other words, this semantics is a little complicated to explain to a newcomer.)
I don't want to make a big fuss about it, but I do want to note, again, that our "deadlines" are entirely self-imposed, and that under these circumstances "we don't have time" is slightly odd, because we can make time, any time we want. The blanket refusal to even contemplate doing that - even in light of new information - and to weigh the tradeoffs on their own merits is something I still don't really understand.
That out of the way, an additional possibility, let's call it 6., for list: We could just make the "abstract type" vs. "data type" distinction based on "does or doesn't the type have a private field". This doesn't entirely fill me with satisfaction (as with "worse is better" solutions in general), with specific drawbacks being that it doesn't extend cleanly to the nullary case (no fields at all), and that in terms of UX a change of semantics based on the presence or absence of a private field may be unexpected, but on the plus side, it's simpler, and would, I think, work.
Sure, hypothetical show-stopper issues could cause us to revisit our self-imposed schedule. I personally don't think that this issue, on its own at least, provides sufficient motivation for schedule revision. I admit that your draft RFC seems like it addresses a host of issues, so maybe all of them taken in unison would be a different story. (But then again, that's not even my call to make.)
There were a couple more options that I should have put on the list, for completeness, but overlooked. 6 note, the "has any private fields ==abstract-type; all public fields ==data-type", is one of them. This would (probably) be less work than adopting the draft RFC in full, but I am not sure what the other Advantages/Disadvantages are. I invite others to write an Advantages/Drawbacks for this approach (perhaps in an RFC PR). 7 We could add a way for a struct to opt-out of FRU support entirely. So in this approach, one would attach the appropriate attribute to , , etc. Advantages: won't break any existing code Drawbacks: Seems quite fragile; we may be good about auditing our own stdlib, but clients who are not aware of the attribute may inadvertently expose themselves to the same bug that currently plagues .
Also, I just wanted to mention: when I wrote my comment 6 hours ago, I came to the keyboard thinking that the FRU support for adding new private fields to and having still work was an important use case. But after some reflection in the hours since, supporting that use case does not seem as important to me.
Here is why: It is relatively easy for a developer who wants to provide that sort of extensible abstraction can still do it, by factoring the type into a all-public front-end with a single public field that holds the all-private back-end, like so: So, given that there exists a reasonable pattern to bring back usable FRU even under the option "(3.) change FRU into a non-hygienic expansion into the record construction form with all fields listed, in the sense that is synonymous with and subject to privacy checks.", I would not object to us adopting (3.) aka solution.
I think that "has any private field" is a decent way to handle abstractness (you can always add a private unit field). On the other hand, Rust supports trait bounds of types – these should handle roles just fine – you shouldn't be able to coerce past a trait bound. By the way, this is somewhat subtle, because coercing to is wrong (as it leaks memory – it coerces past the implicit bound), but coercing to is fine (as the bound isn't used by ). However, this isn't a property of – you still can't coerce to – so we probably want a relatively-sophisticated way to occasionally ignore roles.
I mean, Rust already has a mechanism for ensuring representation-abstraction – private fields – which are semantic (they are handled after type-checking, we probably want to handle them during it, but they definitely aren't handled syntactically or during resolution). It is just that FRU currently accesses them improperly. Also, it doesn't have much to do with e.g. roles – is an abstract type, but it doesn't use any bound on . only uses the implicit bound. A for data-only types would be nice, through.
Another alternative came to me while I was drafting an RFC about this. (But its an alternative that I do not particularly like.) 8a Instead of making "has any private fields" the thing that makes FRU unavailable, instead make the rule be "has all private fields." Thus types like and will not be subject to the vulnerability outlined here. Adding a single field to an otherwise private struct is what changes the nature of a struct with respect to abstraction and FRU, rather than adding a single non- field to an otherwise public struct.
8b, which is so similar to 8a that I gave them both the same numeral: Outlaw the trivial FRU form . That is, to use FRU, you have to use at least one field in the constructing expression. Again, this implies that types like and will not be subject to the vulnerability outlined here. (This may be a decent change to make to the language regardless of whatever else happens on this ticket; the only argument in favor of keeping support for such a trivial form is maybe for supporting certain macro-expansions. But fully-general macro-authors already have to tread very carefully around corner cases on structs, due to issues like the empty braces problem (see )
That would leave the vulnerability intact in the case where the type has both public fields and private fields, the fact that no such type currently exists in the standard library notwithstanding (just as a very artificial demonstration, consider a with ).
yep. Library authors would have to factor their structures very carefully. (I described the drawback you mention in the RFC I posted shortly after you wrote your comment, though I did not include the detail of having the private fields be , which does seem like it could make the situation all the more subtle. Not insurmountable, but a definite drawback.) Just to be clear, I'm not saying I prefer (8a) or (8b); I'm just trying to be complete in my exploration of the solution space.
Repurposed as the tracking issue for rust-lang/rfcs
I'll just go snag
I found that current rustc 1.13.0-nightly can't compile'Rust by Example - 8.2.5 As output parameters' code, both on my linux pc and . I tried this code: see Executing code above on Rust Playground produces the message below when selecting nightly. ( but stable and beta do not produce this error). error: linking with failed: exit code: 1 | = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib" "./out.0.o" "-o" "./out" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libstd-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libpanicunwind-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libunwind-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/librand-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libcollections-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/librustcunicode-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/liballoc-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/liballocjemalloc-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/liblibc-" "/usr/local/lib/rustlib/x8664-unknown-linux-gnu/lib/libcore-" "-l" "dl" "-l" "pthread" "-l" "gccs" "-l" "pthread" "-l" "c" "-l" "m" "-l" "rt" "-l" "util" "-l" "compiler-rt" = note: ./out.0.o: In function drop::hf3564cae7b79f1cb': (.text.
ZN4drop17hf3564cae7b79f1cbE+0xd): undefined reference toLTGTasGT$::drop::h4c07c16183524d21' ./out.0.o: In function drop::hc5f0e028c3876d25': (.text.ZN4drop17hc5f0e028c3876d25E+0xd): undefined reference toLTGTasGT$::drop::h7a8bb753832b1af2' collect2: error: ld returned 1 exit status error: aborting due to previous error Compilation failed. This happens on my Linux Laptop pc as well. This is my laptop's rustc version(installing current latest) . : rustc 1.13.0-nightly ( 2016-08-25) binary: rustc commit-hash: commit-date: 2016-08-25 host: x86_64-unknown-linux-gnu release: 1.13.0-nightly
Nominating since this appears to be a regression.
is still good, does not exist and fails. . Reduced:
This may be a related to . Edit: not a duplicate I think, since was introduced in a different nightly.
Running with the above sample and leads to an ICE in printing a log message
This is from the removal of old trans. We should've been covered by on-demand drop glue generation still, though. cc
Looking at the IR - the missing methods are d, and called from drop methods taking e.g.
Oh, this is bad. The collector needs to know user definitions being instantiated ahead of time (including impls), and these can be used from drop glue which is not guaranteedly known ahead of time. We might need to temporarily detect the shim'd cases in the collector and trigger drop glue generation. cc
I'm looking into a short-term fix right now.
yay! Thanks
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.
<!-- [31mICE[0m: Rustc '' 'error: internal compiler error: cannot convert to a region vid', 'error: internal compiler error: cannot convert to a region vid' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirborrowck] borrow-checking [analysis] running analysis passes on this crate --
cc
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Is this a duplicate of
i think so
I wish there were a "close as duplidate" for this. Ah well.
there is actually, if you click the drop down on the close button
Hunh, they mean to include that in "not planned". Strange.
the "duplicate" issue is closed but this is still failing.
Also ive found that even if you do this without nesting the impl trait it still ICE's.
And if you do it succeeds.
<!-- 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. --error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: rustc 1.57.0 ( 2021-11-29) running on x8664-unknown-linux-gnu note: compiler flags: -C embed-bitcode=no -C debuginfo=2 -C incremental --crate-type bin note: some of the compiler flags provided by cargo are hidden query stack during panic: end of query stack <!-- 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 --<!-- TRIAGEBOT_END --
reduced:
Minimized this a tiny bit further, and I have a detailed explanation why this occurs: So this bug first starts going wrong in late resolution. Specifically, , we define the as a binding when we see the second element (ident subpattern) of the slice pattern, and then bind it later when we walk thru the (expression!) in the first slice pattern element. Essentially, since we treat as being defined here: and then resolve that as the path for we reach a situation where we expect a variable to have been defined before it has been lowered in HIR, which leads to the ICE later on, since we expect to have lowered that path element.
Wonder how difficult it would be to make have subpatterns instead of subexpressions... edit: wouldn't help, see below..
Actually, I don't think fixing this just for ranges is sufficient. I can reproduce this same issue with this: Maybe I can just delay this panic as a span bug, since we're always gonna error out anyways. I think I would ideally like to fix this by making sure we separate bindings in patterns from affecting resolution for expressions in patterns. edit: Ended up fixing it the right way.
claim
The commit a check that stars firing due to the changes to the default target layouts in LLVM 18 ():
Having this issue on as well: Why it's trying to compile for a 32-bit target is clearly beyond me because I'm using an entirely 64-bit host ― since happens to be the author of the crate this is failing on (namely, the 32-bit BIOS version of the bootloader crate which I explicitly avoid depending on for my intendedly UEFI-only kernel), pinging him for assistance.
I think this issue thread is about some failing tests in the Rust repo. Your issue seems to be specific to the crate, which required some updates to the custom targets it is using. I published a new version already, which should fix the issue. If you still have issues with the crate after a , please open an issue in the repository.
I tried this code: I expected to see this happen: The reference is aligned Instead, this happened: : label I-unsound A-mir
We have a pass to add moves for drops in packed structs, but it doesn't fire in this case. That's because there's a bug - this computation cannot just take into account the innermost field, it needs to compute a minimum of some sort.
is this a regression? What did you exactly expected the output to be? (I'd like to run a bisection). thanks.
This was right in . Getting a consistent reproduction of this is slightly difficult because the reference might happen to align correctly by accident. In other words, the fact that the example above prints a pointer that is not 2-aligned means that something is certainly wrong. However, if the address were to be 2-aligned that could either be because the bug is fixed or because we happened to get lucky. The consistent way to check this is by looking at . In 1.52.0 the MIR contains which is correct (the move ensures that the resulting place is aligned) while 1.53.0 contains Note that there is no move.
WG-prioritization assigning priority (). label -I-prioritize +P-high E-needs-bisection
I have run a bisection with on your . The bisection could not pinpoint a single commit, maybe it sinked into a rollup merge. But if it helps, the regression should be in and coming from one of these PRs do you see in any of those a possible culprit? (I don't have the context to)
Yeah, it's , cc
Not sure how would have an effect here, it should be a NOP for with . Looks like something else is amiss as well and that PR surfaced the bug? Where is the logic that moves packed structs to a new place before dropping implemented? That's odd, I would have expected this to be inside ... after all calling on a packed struct also has to do this move. Why does MIR building adjust the caller to satisfy a requirement that the callee should be responsible for?
the pass is called or something like that.
And this can't take place inside the callee because the callee receives a , and if that reference is unaligned then UB has already occurred and there's nothing the callee can do to fix things anymore
takes a raw pointer, so it could very well be the place where the packed struct alignment trouble is handled. And IMO it'd be a much more natural place than doing this by transforming caller MIR.
I don't understand the suggestion. The example above never calls for a packed struct. The offending drop in the MIR in the example above is . The type of that place is - but if were to be responsible for moving, then we would need to emit a move in literally every drop shim for a non-trivial alignment type.
Oh I see, I didn't quite read the example correctly. The problematic drop is the one that happens on field assignment, and we know it's a packed field because of the path we are accessing it with. EDIT: no wait this makes no sense. Now I am confused by your comment.
No what I just said makes no sense. What happens is that this is a partial drop -- one field has been moved out () and then the logic for dropping the remaining fields seems to be wrong. So is relevant because it changed . And it looks like somehow the change is wrong; here is also despite the reference being unaligned.
should fix this.
PRs are bouncing due to test timeouts. Nothing has landed since cc
Very, very unfortunately, just landed. This means that the breakage is not unconditional.
Segfault!
had also been reporting segfaults on master.
I got a segfault on
What is causing this?
Weird, seemed to make it through.
This appears to be because of a channel deadlock. Investigating now.
Fixed the deadlock, investigating the segfault now.
The following code compiles: Nominating for 1.0, P-backcompat-lang. I may well just fix this along with , since the solution is likely going to be similar to what pointed out, but I want to get it on the radar.
Hmm, OK. So the code does attempt to handle this, but I don't know if it is handled in the right way. Specifically, it creates fresh region variables for each region and checks to see whether they unify. The trouble is that does unify with —it unifies if and only if and are the same region. But this is precisely what claimed to be a problem in . So I'm not sure what the right thing is to do here.
I'm going to assign to because I'm blocked on his opinion on what to do here.
Assigning P-backcompat-lang, 1.0.
Right thing to do is to use .
Argh. The right fix is to substitute some skolemized lifetimes in for the early bound regions before doing the unification rather than fresh variables.
Actually I think the problem is that we're just not calling on the inference context
<!-- 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. --Example code: In rustc 1.67 stable this generates a number of moves (I suppose for calling convention?) that I don't think need to be there, especially when inlining: See While this is a pretty pointless example, this comes up in situations where you might want to convert a tuple of slices into a struct of slices in order to assign names to the tuple members.
LLVM should probably be able to elide the below and pass the original pointer. label +A-llvm +I-slow
This seems to be resolved on current nightly by & Thanks :tada: (I'm not so sure about an incoming inherent problem on alignment attribute)
Fixed as part of the LLVM 17 update (), needs codegen test.
Making the sum a little more vague than the above code prevents the removal of memcpy. Edit: It seems like not so, precisely, the above argument is a function pointer, not a closure, and I now think function pointers never capture any variables (because of ?, ). So is this another missing opportunity?
Yes, the removal is only allowed in the original example, because the called function is known. It does not work with an unknown function due to missing . Note that the is on the by-value argument of , not the by-reference argument of the function pointer .
That sounds reasonable. Thanks! So, in this case, if the assumption that the function pointer never captures the argument was correct, missing attribution opportunities for the callbase?
I don't think there is any missing attribution opportunity here. In your example, if is nocapture, then that does not imply anything about being nocapture (it's a completely different object). Even if you directly passed through the argument to the call (without intermediate memcpy to alloca), inferring nocapture is still not straightforward, because allows interior captures (i.e. it's possible to capture the pointer within the function, as long as it does not stay captured after the function returns).
(Edit: Now I think that on case, capturing in LLVM might happen. Thanks!