-
Notifications
You must be signed in to change notification settings - Fork 606
UB does not time travel #2320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
RalfJung
wants to merge
1
commit into
rust-lang:master
Choose a base branch
from
RalfJung:ub-time-travel
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
UB does not time travel #2320
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a simpler, smaller carve-out?
I don't feel super strongly about this – not enough to block FCP. IMO it'd be nice to at least nod at this so that careful authors understand the distinction. That said, I wasn't able to come up with a clear example of relying on "this generic observable operation prevents UB time travel".
View changes since the review
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "marked" mean?
The way I think this would go, if we ever wanted to support such operations, would be by adding a
willreturnflag on asm that's similar topurebut allows I/O as long as the asm block can guarantee that that I/O will always return. A similar#[ffi_willreturn]attribute could be added for extern blocks. The documentation for those flags/attributes would then say "this can cause UB after the operation to time-travel to before the operation, causing whoever has to debug this code a loss of most of their hair".Are you saying that we should promise that if we ever add such an attribute, that we will document it thoroughly to mention this caveat? That seems like an odd thing to say, I think the expectation is that we document every attribute we add. :)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is my attempt to steelman your proposal. I still would prefer not to add such a note, but this is the version I dislike the least. ;) I'd like to hear from the rest of the involved teams regarding whether we should add this or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RalfJung The only case I can think of where we might want this in the future would be much narrower than that. Essentially, if we add some specific operation which is allowed to time-travel, then UB interacting with that operation could time-travel to the extent that operation can time-travel.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what you mean by "time-traveling operation". UB isn't an operation, so what we call "time-traveling UB" doesn't mean an operation is doing time-traveling. "no time-traveling UB" really just means "observable behavior is an optimization barrier for potentially-UB operations", or colloquially "if you print something before doing UB then you'll see the print".
We obviously allow e.g. two adjacent calls to
read()to be reordered. That's not time-traveling, that's just a standard semantics-preserving transformation. And we don't allow observable behavior to be reordered; if you print first A then B you'll always see them in that order. There's not really any degrees of freedom here I can think of.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure – it makes it so that the default (ie, if an operation provides no documentation one way or another) is that UB can't time-travel over an operation, but saying "unless it documents otherwise" reserves the possibility that some operation might document it, which prevents the kind of generic reasoning I'm worried about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it would be wrong for an operation to document this. Docs can't change the opsem. We'd have to first add a new language feature that makes such operations exist. That's what I expressed in my variant of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can think of any number of such operations I'd like to see us have that would be perfectly reasonable. (You can have things observable before their apparent invocation, through compiler or processor reordering.) Let's not go on this tangent right now, it's not a blocker for the current proposal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have written papers about operations that have this flavor so this is a topic I thought about quite a bit. I think this would break the ability for people to reason about what their program does; I don't think any sensible language can have operations like that. You get into causal loops and internal inconsistency basically immediately. Compilers and processors already do all sorts of reordering, none of them have this effect.
But anyway -- what do you propose for this PR then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RalfJung For this PR I would propose that we not add any extra language disclaiming future things we might do, and close this subthread.