-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
tracking issue for default binding modes in match (RFC 2005, match_default_bindings) #42640
Comments
I'm actually not 100% sure the best way to implement this. It seems like we will need to add adjustments to patterns, and then integrate those into the various bits of the compiler. @eddyb, have any thoughts on that? You usually have some clever ideas when it comes to this sort of thing. =) |
We should be able to treat adjustments more uniformly now, although it'd still be a lot of plumbing. |
How does this interact with slice patterns (#23121)? |
My expectation would be that, when we encounter a pattern like |
@eddyb do we want to use general purpose adjustments here, or something more limited (the current RFC, after all, only requires autoderef of |
@nikomatsakis Autoderef or autoref? If it's one bit per pattern making it separate for now is fine. |
autoderef -- that is, where you have a pattern like |
Here is a rough and incomplete implementation plan for the match ergonomics RFC. There are a few high-level things we have to do:
Right now, the code is setup to scrape this information directly from the "HIR" (the compiler's AST). The HIR node for a pattern is
We want to make this equivalent to
We don't however have enough information to do this when we construct the HIR, since we need type checking results to do it, so we can't change the HIR itself. The way we typically handle this sort of thing then is to have the typeck encode "side tables" with auxiliary information. These tables are stored in In this case, I think we want two tables:
Probably a decent first PR is just to introduce the second table (
This is not a comprehensive list, but it does have the major use-sites. You can get a more comprehensive list by doing OK, no time for more, but hopefully this helps somebody get started! Please leave a note if you are interested in taking this on, and feel free to ping me on IRC ( |
I'll look into the first step:
|
@tschottdorf woohoo! |
This PR kicks off the implementation of the [default binding modes RFC][1] by introducing the `pat_binding_modes` typeck table mentioned in the [mentoring instructions][2]. `pat_binding_modes` is populated in `librustc_typeck/check/_match.rs` and used wherever the HIR would be scraped prior to this PR. Unfortunately, one blemish, namely a two callers to `contains_explicit_ref_binding`, remains. This will likely have to be removed when the second part of [1], the `pat_adjustments` table, is tackled. Appropriate comments have been added. See rust-lang#42640. [1]: rust-lang/rfcs#2005 [2]: rust-lang#42640 (comment)
…sakis default binding modes: add pat_binding_modes This PR kicks off the implementation of the [default binding modes RFC][1] by introducing the `pat_binding_modes` typeck table mentioned in the [mentoring instructions][2]. It is a WIP because I wasn't able to avoid all uses of the binding modes as not all call sites are close enough to the typeck tables. I added marker comments to any line matching `BindByRef|BindByValue` so that reviewers are aware of all of them. I will look into changing the HIR (as suggested in [2]) to not carry a `BindingMode` unless one was explicitly specified, but this PR is good for a first round of comments. The actual changes are quite small and CI will fail due to overlong lines caused by the marker comments. See #42640. cc @nikomatsakis [1]: rust-lang/rfcs#2005 [2]: #42640 (comment)
I see nothing wrong with the current rules, and certainly see no motive to rollback stabilized functionality. In fact I like the extension that makes strictly more things compile, it's a DWIM approach. The interpretation is that a |
@leodasvacas I agree with that sentiment, now that I've seen examples with nested references. |
Ah, I hadn't quite realized the difference between @Boscop's and @eddyb's proposals. I agree we probably want to keep the ability to match multiple non-reference patterns without "accumulating" references. (Those extra "layers" of pointers do exist in the match-ee, but they can't be reused in the I do still think that a) we definitely want something like @Boscop's extension (which should be backwards-compatible) and that b) it interacts weirdly with the change from #46688. That is, I would like a single way to reset the binding mode that applies anywhere; not just at pre-existing references. The confusion in #46688 comes from the fact that the RFC "hasn't quite made up its mind" on whether So here's an idea to solve both of these problems: once we're in a This gives the same result as the current implementation for #46688- matching Or in other words, you can no longer match against actual Edit: Actually the more I think about this version, the more it feels like 50% pedagogical change and 50% just adding @Boscop's extension. Which is great, because that means it's more likely to be compatible and also more likely to offer better error messages! |
@rpjohnst Just to clarify: You propose that all It works well for read-only ( So, if we want to preserve the ability to keep all the So then we can't auto-remove all the (But I think it makes sense to allow undoing a |
Yes, exactly. Kind of doubling down on the idea that
IMO we shouldn't do this at all- the move binding mode is sufficient to control the levels of references. If you need that control, just switch back to that mode with a The idea of accumulating extra reference levels, as you propose, is basically the thing that we (mis)interpreted @eddyb's version as, and which has the problem of introducing dummy temporaries, and which is backwards-incompatible with the #46688 fix. |
Hm, which dummy temporaries would it introduce? Wouldn't your proposal also be backwards incompatible (because currently, matching |
It introduces dummy temporaries when you have some structure in between the layers of references. If you're just matching against an And yes, my proposal is backwards-incompatible in cases like matching |
Any update on this issue? :) |
So I think the place we're at now is @Boscop's original proposal, summarized by @nikomatsakis in #42640 (comment) as "make While in a sense this gives I'd like to solve this---it came up again on Reddit and it's kind of a pain. Is the next step just to write an RFC for it? |
@rpjohnst The blocker I think is that there are several possible solutions to this problem and considerable dissensus among the lang team (and certainly the community also) about what would be best:
Personally, I lean toward one of the latter two options because I think the use of |
@withoutboats Ah, I didn't realize this would be in conflict with the second two options, especially in light of #48448. So would the next step be to get consensus on which approach to take? Do we need to stick with just one, or could we have both to round out the existing behavior? |
@rpjohnst yea, we need consensus building to move forward here. as far as i know, we don't even have consensus that we shouldn't do more than one of them. |
Always, unconditionally? But (Also, wouldn't this solution break existing code (on stable) that uses
Please don't forget, it should be possible to mark the moved-out copy as
I really think the best option is to use the Btw, what I would like (in addition to going with the
I've talked to several people who expected it to already work like this because it also works like this when the reference wasn't created implicitly by |
Having thought through this some more, this is one place in the language where I can easily see supporting both So people (and, more importantly IMO, particular pieces of programs given their context) can use the one that expresses their intent more clearly. When Does this make sense to anyone else? Or would people rather stick to just one solution? Or do people like the "coerce |
This is implemented and stabilizing, but we never closed it! The only real remaining question is #44849 and we have a separate issue for that. |
@withoutboats @rpjohnst Any update on this? |
One of the examples in the RFC cannot be built: fn main(){
let x = &Some((3, 3));
match x {
// Here, each of the patterns are treated independently
Some((x, 3)) | &Some((ref x, 5)) => {}
_ => {}
}
} Why? Related: #77358 |
This is a tracking issue for the "match ergonomics using default bindings mode" RFC (rust-lang/rfcs#2005).
Status: Awaiting stabilization PR and docs PR! Mentoring instructions here.
Steps:
Unresolved questions:
The text was updated successfully, but these errors were encountered: