Skip to content

Commit dc96159

Browse files
committed
SemVer: Add section on RPIT capturing
1 parent 88edf01 commit dc96159

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

src/doc/src/reference/semver.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ considered incompatible.
8181
* [Minor: generalizing a type to use generics (with identical types)](#generic-generalize-identical)
8282
* [Major: generalizing a type to use generics (with possibly different types)](#generic-generalize-different)
8383
* [Minor: changing a generic type to a more generic type](#generic-more-generic)
84+
* [Major: capturing more generic parameters in RPIT](#generic-rpit-capture)
8485
* Functions
8586
* [Major: adding/removing function parameters](#fn-change-arity)
8687
* [Possibly-breaking: introducing a new function type parameter](#fn-generic-new)
@@ -1616,6 +1617,47 @@ fn main() {
16161617
}
16171618
```
16181619

1620+
### Major: capturing more generic parameters in RPIT {#generic-rpit-capture}
1621+
1622+
It is a breaking change to capture additional generic parameters in an [RPIT] (return-position impl trait).
1623+
1624+
```rust,ignore
1625+
// MAJOR CHANGE
1626+
1627+
///////////////////////////////////////////////////////////
1628+
// Before
1629+
pub fn f<'a, 'b>(x: &'a str, y: &'b str) -> impl Iterator<Item = char> + use<'a> {
1630+
x.chars()
1631+
}
1632+
1633+
///////////////////////////////////////////////////////////
1634+
// After
1635+
pub fn f<'a, 'b>(x: &'a str, y: &'b str) -> impl Iterator<Item = char> + use<'a, 'b> {
1636+
x.chars().chain(y.chars())
1637+
}
1638+
1639+
///////////////////////////////////////////////////////////
1640+
// Example usage that will break.
1641+
fn main() {
1642+
let a = String::new();
1643+
let b = String::new();
1644+
let iter = updated_crate::f(&a, &b);
1645+
drop(b); // Error: cannot move out of `b` because it is borrowed
1646+
}
1647+
```
1648+
1649+
Adding generic parameters to an RPIT places additional constraints on how the resulting type may be used.
1650+
1651+
Note that there are implicit captures when the `use<>` syntax is not specified. In Rust 2021 and earlier editions, the lifetime parameters are only captured if they appear syntactically within a bound in the RPIT type signature. Starting in Rust 2024, all lifetime parameters are unconditionally captured. This means that starting in Rust 2024, the default is maximally compatible, requiring you to be explicit when you want to capture less, which is a SemVer commitment.
1652+
1653+
See the [edition guide][rpit-capture-guide] and the [reference][rpit-reference] for more information on RPIT capturing.
1654+
1655+
It is a minor change to capture fewer generic parameters in an RPIT.
1656+
1657+
[RPIT]: ../../reference/types/impl-trait.md#abstract-return-types
1658+
[rpit-capture-guide]: ../../edition-guide/rust-2024/rpit-lifetime-capture.html
1659+
[rpit-reference]: ../../reference/types/impl-trait.md#capturing
1660+
16191661
### Major: adding/removing function parameters {#fn-change-arity}
16201662

16211663
Changing the arity of a function is a breaking change.

0 commit comments

Comments
 (0)