Change:
Tracking issue for This RFC is a breaking change for most users of slice patterns. The main change is that slice patterns now have the type instead of . For example, in the old semantics the would have the type , would have the type and the type . With the new semantics, would have the type and the type - which are the wrong types. To fix that, add a before the slice and a before the tail as if you were matching a struct (of course, use if you want a mutable reference): . [ ] Matches on &mut[] move the .. match & don't consider disjointness [ ] cannot move into irrefutable slice patterns with multiple elements [x] double drop with slice patterns [x] (Only E-needstest) Yet another bug with slice_patterns [x] (Only E-needstest) LLVM Assertion: Both operands to ICmp instruction are not of the same type!Implemented in Still needs better integration with MIR borrowck to resolve soundness concerns, I believe
triage: P-backcompat-lang (1.0 beta) -- at least for the backwards incompatible parts of rust-lang/rfcs. This is something of a nice to have, we can live with it if it doesn't get done.
I'm on it, by the way. I'll open a PR soon.
go go go!
:racehorse:
(this is puntable to 1.0 if necessary, but we hope to have it by 1.0 beta.)
We are going to feature-gate array patterns, in order to ensure that we can soundly land these changes to the semantics in the future.
Moving off of milestone, since these are now gated.
triage: I-nominated ()
P-high, not 1.0.
I've repurposed this as a general tracking issue for the and features.
Syntax for named subslice conflicts with potential future exclusive slice patterns. Either it should be changed, or exclusive slice patterns should be forever rejected, or something else.
So, once MIR is around, I'll feel much better about this feature from the POV of soundness. It's certainly convenient once in a while. But I have realized a few quirks recently: think there is still some debate about whether patterns should match values. I think no, you should write the . don't think that there is a syntax for taking a mut subslice. syntax conflicts with exclusive slice patterns (as pointed out). 's a bit unclear to me if the slice part is intended as a fresh subpattern. Seems like it should be.
It would be also nice to have unnamed or even named sublists in tuple and especially tuple variant patterns, but whatever syntax choice is made for slices it probably can be reused there. seems to compile, its just not have been updated to by-value semantics from Subslice is an arbitrary pattern after all.
On Thu, Nov 05, 2015 at 12:02:03PM -0800, Vadim Petrochenkov wrote: I would expect that to produce a value. Is that not what it does? (In particular, the isn't normally required to get a value of type , is it?)
Currently it isn’t, but according to rust-lang/rfcs, array patterns should be changed to make be required to get a : Because of this, a binding should give a or (according to the RFC). For example:
But that's one of the main points of RFC 495.
On Mon, Nov 09, 2015 at 11:49:37AM -0800, P1start wrote: OK, seems good. So I definitely wouldn't want to stabilize until we've implemented these semantics and gained some experience with them.
Currently, needing to create a for the "rest" sub-pattern causes issues in MIR. I'll add a hack to generate the len switch followed by treating the slice pattern as an array pattern, which is capable of generating that "rest" slice rvalue. We should probably switch to the RFC semantics in MIR trans, once we get rid of the old trans code, as they simplify things quite a bit.
What are the remaining blockers for stabilizing this? Is there anything I can do to help?
Implementing the RFC is necessary. started in but there hasn't been any activity on that PR for a while. I'll take over if he's okay with it.
My implementation of slice patterns is done. I only have to figure out what is the best way to get match checking to work (maybe just re-add that hack?)
Hmm perhaps my regarding should have been posted here instead.
I just tried to follow this snippet for . The example failed and pointed me to this issue. I based on what was said here but running it results in "Program Ended". No errors are thrown :(
It's not supposed to print anything, so that means it worked. The assertions were satisfied and the program ended normally.
Oh right... I have been used to running examples that printed out something and the was unexpected, no idea why it didn't click that there was no actual print statements. Sorry about that!
Possible problem:
Status (iiuc) implementation is complete, but recent (2016-06-09) so probably some bugs to iron out (see also , ). I believe there is also general uncertainty among the lang team that slice patterns are generally 'right'. Hopefully, we can get some experience with the implemented feature and think about possible interactions with other features. Question: there was a conflict with exclusive ranges mentioned above by and - is that still an issue or has something changed there?
Note PR in particular is pointing out an issue with allowing moves of elements out of slices, and is disallowing it (a that it notes in the description on that commit).
[ ] Matches on &mut[] move the .. match & don't consider disjointness [ ] cannot move into irrefutable slice patterns with multiple elements [ ] double drop with slice patterns [ ] (Only E-needstest) Yet another bug with slice_patterns [ ] (Only E-needstest) LLVM Assertion: Both operands to ICmp instruction are not of the same type! ~~ EDIT by moved list to main issue
The slice-patterns vs. borrowck bugs do not really drop anything. I just have to fix the double drop problem.
Note the concern about how the syntax here conflicts with . Not that this is new, just don't want it forgotten.
Proposal to resolve the conflict with inclusive range patterns: add an symbol: It already has a similar role in other places in patterns:
From The second one would not work, right? Since is dynamically sized and therefore cannot be directly on the stack. in the pattern would need to be at least . (And the discriminant would need to be behind or another memory indirection, with a corresponding pattern.)
is start of a pattern with binding and while itself is not a pattern, pattern can start with , for example a half open exclusive range pattern The syntax is still viable though, but the solution is a bit hacky - disambiguate in favor of subslice if is followed by or . One more problem is that the current syntax is and your suggestion reduces it to , i.e. the subslice cannot be further deconstructed in place anymore.
Oh, but, range patterns with missing bounds , , , are not implemented yet, so won't be a problem if they are never implemented.
There is no pattern for , right? So one token of look-ahead disambiguates from . Can you give an example of how the previous syntax could do that?
Something like works now. Actually is a special case of as well. To make disambiguation simple and also keep the current functionality it would be ideal to use some prefix disambiguator. where PREFIX immediately means that we are going to parse a subslice pattern and not an element pattern. For example, your syntax in "inverted" form:
is the same as , isn’t it? As to , well… I could live without it. It could be replaced with slice-indexing expressions:
Yeah, I didn't say it's useful, only that it works at the moment One more problem about is that simple stops being a convenience sugar for (where is ..<dummyname@ ..BINDING @ ....` doesn't). This problem doesn't arise for (or any other ). EDIT: Basically, would be the least hacky and simultaniously the least invasive re-syntaxing. EDIT2: Actually, (instead of ) is good too if never considers to be a part of the pattern if it's followed by or . Just a bit more hacky.
Is it too late to change the syntax in more drastic ways? If no, I'd have this proposal: Add "++" as a concat operator to the language in both expression and pattern form: No more conflict with a pattern We can stop using the operator for things that are not commutative addition Uniform treatment of slices and string slicesHuge change More verbose syntax Update: Added tuples
Another con is that itnwould complicate the choice for VG further, unless we use it there too. That is, I sort of want something like within and to desugar to outside them.
why not use in patterns?
We already support matching on &str on literals and constants. Could we similarly allow (stabilize) matching slices on array literals and array/slice constants, while we're still pondering on some of the more advanced uses?
How about this syntax:
I agree with in that it would be amazing if we could move towards stabilising the simple, unambiguous cases for fixed-size arrays first. Most of the games/graphics ecosystems use something like for / types, or for matrix types, etc. It would be a big ergonomic win to be able to pattern match on these as they are used very frequently.
Matching on or types sounds like a bad idea considering and
ahh true, avoiding matching on float literals is a good point. However even without matching on literals, being able to "destructure" fixed size arrays would still be massively useful.
Yup, that sounds like a much better motivating example.
It would, but I don't think that would be covered under a fast-tracked stabilization of trivial slice patterns.
and (without attaching a pattern to ) have no syntactic problems and can be stabilized right now if all the bad codeged was fixed (cc is it fixed?). EDIT: I see is still open. I don't think borrow checker limitation like (e.g. less code is permitted than it potentially can be) are blockers for stabilization.
The compiler doesn't do tail call elimination for this snippet: Would it be possible have it? If so I'd like to request taking it into account.
I guess the lack of tail call elimination is a more pervasive problem, e.g.
I'm not sure this is the right place to post it, but destructing arrays is resulting in broken codegen. It took me something like 2 full days of work to track the cause of a SIGSEGV in my program to something like: If you look at either MIR or Assembly it looks like both and are being freed twice.
I'm confused, how does drop elaboration not simply take care of it? Is drop elaboration just broken for const indexing?
Is there any way I can use this on stable and beta? I'm not doing anything fancy. Just matching against the last two vector items and the first vector item as a separate match. I don't want to turn my crate into a nightly only package just for this. UPDATE: Nevermind; I figured out how to do it with indexing, cloning the innards, and tuple results.
Based on comment back in July, it seems like we could consider a subset of this for stabilization. thoughts?
Hmm, I'd like to see the subset clearly defined (and see the relevant tests). I am somewhat nervous about stabilizing things here until we have the drop elaboration story fully worked out.
Summary from the meeting: We need a fix for first. As soon as we have that fix, let's revisit this and decide if we should stabilize a subset or wait to stabilize the whole thing.
My take is that I would rather that we stabilize the whole thing at once. I'm a bit nervous to stabilize syntax involving if we haven't yet figured out how to give a name to the slice or otherwise define the recursive pattern.
There's no good alternative to the plain (without a name), all other patterns (structs, tuple structs, tuples) use it to mean "rest of the list". There are few viable alternatives for syntax " + name" in this thread, but I wouldn't want to have stabilization of the most useful subset blocked on bikeshedding them.
I'd bet $5 that if we made it an error to use on a or on a that nobody would ever notice.
I am not sure that is the most useful subset. I would have thought that the most useful subset is or -- that is, extract something from the front or back and slice the rest. Certainly that's the main thing that I ever want. (Though we have handy methods for it.)
I just want matching against constant fixed-length arrays. The .. stuff you can already do with .
I could get behind this plan (i.e., no at all).
Why not ? If you have something like , what's wrong with having a mutable ref to a, a mutable ref to b, and a mutable slice x that doesn't include a or b? The aliasing still holds up, no? Edit: Oh I see, I should've read the full thing. Why not remove the entirely? if you don't want the thing, to capture the thing? (Not sure if this has been suggested)
was fixed by Any other codegen bugs blocking stabilization?
of what specific subset? If you want to stabilize, can you please open up a new issue that describes the behavior we are stabilizing, giving examples of tests that show how it works? It would be great to also specify what is not being stabilized. Example: I don't know if there are other bugs, I know that has been working on improving various double-drop bugs and analysis, but I think more for slice patterns.
my view of current state item | state -----|------ The syntax conflicts with exclusive range patterns. | completed Matches on &mut[] move the .. match & don't consider disjointness | I will look, need to check is nested cases support needed cannot move into irrefutable slice patterns with multiple elements | bug only in AST borrowck double drop with slice patterns | fixed (Only E-needstest) Yet another bug with slice_patterns | doesn't relate (Only E-needstest) LLVM Assertion: Both operands to ICmp instruction are not of the same type! | marked done
Excellent, looks like there are no codegen issues and no issues that may require breaking backward compatibility in the future. In this case I'll prepare a stabilization PR for slice patterns without , and a mini-RFC attempting to finalize syntax for slice patterns with .
I just proposed stabilizing the subset without patterns in this issue:
Given the mutual impls of for and , I expected this to work: It seems too strict to require the pattern to have the same element type as the matched slice.
This looks more like some extension to using rather than something specific to slice patterns.
Any update on this? Being able to pattern match against Vecs and arrays is hugely important for many people coming from functional languages.
Rust has had basic slice patterns since 1.26. More advanced patterns are being discussed in
Ah gotcha, what's the current recommended approach to destruct a into head/tail?
 might work for you, depending on your usecase.
Ok, thanks. I'm hoping to be able to match against vs in one fell swoop, but with an would technically work.
You can match on for that.

Discussion:
# `slice_patterns` <del> The tracking issue for this feature is: [#23121] </del> <ins> The tracking issue for this feature is: [#62254] </ins> <del> [#23121]: https://github.com/rust-lang/rust/issues/23121 </del> <ins> [#62254]: https://github.com/rust-lang/rust/issues/62254 </ins> ------------------------

match ty.sty { ty::Array(..) | ty::Slice(..) => { err.help("the semantics of slice patterns changed  <del> recently; see issue #23121"); </del> <ins> recently; see issue #62254"); </ins> } _ => {} }

(active, nll, "1.0.0", Some(43234), None), // Allows using slice patterns. <del> (active, slice_patterns, "1.0.0", Some(23121), None), </del> <ins> (active, slice_patterns, "1.0.0", Some(62254), None), </ins> // Allows the definition of `const` functions with some advanced features. (active, const_fn, "1.2.0", Some(57563), None),

(removed, allocator, "1.0.0", None, None, None), (removed, simd, "1.0.0", Some(27731), None, Some("removed in favor of `#[repr(simd)]`")), <del> (removed, advanced_slice_patterns, "1.0.0", Some(23121), None, </del> <ins> (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, </ins> Some("merged into `#![feature(slice_patterns)]`")), (removed, macro_reexport, "1.0.0", Some(29638), None, Some("subsumed by `pub use`")),

LL |         [1, 2, ..] => {} |                ^^ | <del> = note: for more information, see https://github.com/rust-lang/rust/issues/23121 </del> <ins> = note: for more information, see https://github.com/rust-lang/rust/issues/62254 </ins> = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized

LL |         [1, .., 5] => {} |             ^^ | <del> = note: for more information, see https://github.com/rust-lang/rust/issues/23121 </del> <ins> = note: for more information, see https://github.com/rust-lang/rust/issues/62254 </ins> = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized

LL |         [.., 4, 5] => {} |          ^^ | <del> = note: for more information, see https://github.com/rust-lang/rust/issues/23121 </del> <ins> = note: for more information, see https://github.com/rust-lang/rust/issues/62254 </ins> = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized

LL |         [ xs.., 4, 5 ] => {} |           ^^ | <del> = note: for more information, see https://github.com/rust-lang/rust/issues/23121 </del> <ins> = note: for more information, see https://github.com/rust-lang/rust/issues/62254 </ins> = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized

LL |         [ 1, xs.., 5 ] => {} |              ^^ | <del> = note: for more information, see https://github.com/rust-lang/rust/issues/23121 </del> <ins> = note: for more information, see https://github.com/rust-lang/rust/issues/62254 </ins> = help: add #![feature(slice_patterns)] to the crate attributes to enable error[E0658]: syntax for subslices in slice patterns is not yet stabilized

LL |         [ 1, 2, xs.. ] => {} |                 ^^ | <del> = note: for more information, see https://github.com/rust-lang/rust/issues/23121 </del> <ins> = note: for more information, see https://github.com/rust-lang/rust/issues/62254 </ins> = help: add #![feature(slice_patterns)] to the crate attributes to enable error: aborting due to 6 previous errors