-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Cannot use select!
with Receiver contained in a struct
#12902
Comments
Maybe the syntax could be changed to something like select! {
s from a.p => ...,
() from timeout => ...,
} so that the port can be a full expression. (Although, those idents are used for new variable names... so this may be tricky.) |
The macro is what tripped me up when I wrote, this. Ideally you want something like:
But |
I've hit this a few times myself. Would it be OK for the select! macro to be implemented as a syntax extension? It'd then be possible to allow an arbitrary expression on the LHS of => and extract the method name at the AST level. It could also provide better error messages on errors such as leaving out the method name. |
I've hit this and it seems I can't move forward until it's resolved. (Well, "can't move forward" is strong; for now I'll just unwrap the macro manually.) Is there any consensus on how this should be resolved? I'm happy to cut code but it's seems pretty open what direction to go in. |
Here is my suggestion: select!{
obj1 from rx1 => {
// Do stuff with obj1
},
obj2 from rx2 => {
// Do stuff with obj2
}
} If people want to use something other than select!{
obj1_opt from rx1 using recv_opt => {
// Do stuff with obj1_opt
},
obj2_opt from rx2 using recv_opt => {
// Do stuff with obj2_opt
}
} Here is a sample implementation which makes no use of the Note that this is "all or nothing" regarding the optional |
I just hit this bug on my code. Had to expand all our use of select! because of ownership errors. Maybe multiple macros for multiple uses will do the trick ? |
Hi guys, I have been using the |
@apoelstra Did you ever send a PR for it? |
No, I'll do that now. |
The old `Select` structure was very inefficient and required the user to use unsafe code (and manually maintain a "this variable will never move" invariant). Searching through several popular repositories, the only instance I found of it being used was in servo --- to avoid the setup cost of putting `select!` in a loop, which would create a new `Select` on every iteration. This commit deletes the `Select` structure entirely and moves all of its code into the `select!` macro. The benefit of this is that there is no more need for allocations, no more need for unsafe code, and no setup costs (so servo can now use `select!` directly). This also changes the interface to select! to fix rust-lang#12902. Fixes rust-lang#12902. [breaking-change]
I just ran into this issue as well. It's especially vexing since the struct that contains the receivers must be borrowed as a mutable reference inside the select! -- so this fails: fn do_something(&mut self) {
let r1 = &self.r1;
let r2 = &self.r2;
select! {
a = r1.recv() => a.unwrap()(self), // ERROR! self.r1 is already borrowed!
b = r2.recv() => (),
}
} It seems that the only reason select! only allows expressions of the form "ident.ident()" is so that the macro can use that first ident as a unique local variable name inside the expansion. This could be solved if we could generate unique symbols in a macro expansion. Issue #9031 mentions this but was closed back when macro hygiene was implemented. Sadly, macro hygiene does not help here, since all the identifiers we need to distinguish have the same syntax context. I've been poking and prodding at the macro syntax trying to figure out a way to do this that isn't horrible, special-cased, or just plain inconvenient, but I'm not sure it's reasonable to do without the ability to generate symbols. Maybe we do need a syntax extension after all? |
Looking at it with a little less sleep deprivation, I think the current syntax of the select! macro just doesn't make sense. It uses a matcher for the method invoked on the receiver -- ostensibly supporting receivers whose receive method is spelled differently than Removing the spurious |
Apparently I was wrong about not being able to do this with the current macro system. User talchas on #rust came up with this formulation that allows the use of an arbitrary expression as the receiver in a select! expansion: http://is.gd/F6Wy5D A little bit hairier than the original, and it doesn't solve my borrowing problems, but I think it does make the macro much more generally useful. Any thoughts? |
@tripped just a simple change to your suggestion, to stop macro clutter (this style is used in a bunch of internal macros) http://is.gd/bMLJK9 |
The |
fix: Order ItemScope::entries results
The select! macro doesn't work if you try to reference a Receiver (Port) in a struct. huon reviewed this in the IRC room and agreed I should file an issue on it.
Here are two attempts to do this and both fail at compile time:
The text was updated successfully, but these errors were encountered: