Skip to content

Commit 9a72afa

Browse files
committed
Auto merge of rust-lang#83772 - jhpratt:revamp-step-trait, r=Mark-Simulacrum
Make `Step` trait safe to implement This PR makes a few modifications to the `Step` trait that I believe better position it for stabilization in the short term. In particular, 1. `unsafe trait TrustedStep` is introduced, indicating that the implementation of `Step` for a given type upholds all stated invariants (which have remained unchanged). This is gated behind a new `trusted_step` feature, as stabilization is realistically blocked on min_specialization. 2. The `Step` trait is internally specialized on the `TrustedStep` trait, which avoids a serious performance regression. 3. `TrustedLen` is implemented for `T: TrustedStep` as the latter's invariants subsume the former's. 4. The `Step` trait is no longer `unsafe`, as the invariants must not be relied upon by unsafe code (unless the type implements `TrustedStep`). 5. `TrustedStep` is implemented for all types that implement `Step` in the standard library and compiler. 6. The `step_trait_ext` feature is merged into the `step_trait` feature. I was unable to find any reasoning for the features being split; the `_unchecked` methods need not necessarily be stabilized at the same time, but I think it is useful to have them under the same feature flag. All existing implementations of `Step` will be broken, as it is not possible to `unsafe impl` a safe trait. Given this trait only exists on nightly, I feel this breakage is acceptable. The blanket `impl<T: Step> TrustedLen for T` will likely cause some minor breakage, but this should be covered by the equivalent impl for `TrustedStep`. Hopefully these changes are sufficient to place `Step` in decent position for stabilization, which would allow user-defined types to be used with `a..b` syntax.
2 parents 84b1005 + 741b9a4 commit 9a72afa

File tree

20 files changed

+423
-122
lines changed

20 files changed

+423
-122
lines changed

compiler/rustc_ast/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#![feature(iter_zip)]
1818
#![feature(label_break_value)]
1919
#![feature(nll)]
20+
#![feature(min_specialization)]
21+
#![feature(trusted_step)]
2022
#![recursion_limit = "256"]
2123

2224
#[macro_use]

compiler/rustc_hir/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#![cfg_attr(bootstrap, feature(extended_key_value_attributes))]
88
#![feature(in_band_lifetimes)]
99
#![feature(once_cell)]
10+
#![feature(min_specialization)]
11+
#![feature(trusted_step)]
1012
#![recursion_limit = "256"]
1113

1214
#[macro_use]

compiler/rustc_index/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#![feature(unboxed_closures)]
77
#![feature(test)]
88
#![feature(fn_traits)]
9+
#![feature(trusted_step)]
910

1011
pub mod bit_set;
1112
pub mod vec;

compiler/rustc_index/src/vec.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl Idx for u32 {
6565
/// `u32::MAX`. You can also customize things like the `Debug` impl,
6666
/// what traits are derived, and so forth via the macro.
6767
#[macro_export]
68-
#[allow_internal_unstable(step_trait, step_trait_ext, rustc_attrs)]
68+
#[allow_internal_unstable(step_trait, rustc_attrs)]
6969
macro_rules! newtype_index {
7070
// ---- public rules ----
7171

@@ -184,7 +184,7 @@ macro_rules! newtype_index {
184184
}
185185
}
186186

187-
unsafe impl ::std::iter::Step for $type {
187+
impl ::std::iter::Step for $type {
188188
#[inline]
189189
fn steps_between(start: &Self, end: &Self) -> Option<usize> {
190190
<usize as ::std::iter::Step>::steps_between(
@@ -204,6 +204,9 @@ macro_rules! newtype_index {
204204
}
205205
}
206206

207+
// Safety: The implementation of `Step` upholds all invariants.
208+
unsafe impl ::std::iter::TrustedStep for $type {}
209+
207210
impl From<$type> for u32 {
208211
#[inline]
209212
fn from(v: $type) -> u32 {

compiler/rustc_infer/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#![feature(never_type)]
2323
#![feature(in_band_lifetimes)]
2424
#![feature(control_flow_enum)]
25+
#![feature(min_specialization)]
26+
#![feature(trusted_step)]
2527
#![recursion_limit = "512"] // For rustdoc
2628

2729
#[macro_use]

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#![feature(associated_type_defaults)]
5151
#![feature(iter_zip)]
5252
#![feature(thread_local_const_init)]
53+
#![feature(trusted_step)]
5354
#![recursion_limit = "512"]
5455

5556
#[macro_use]

compiler/rustc_mir/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Rust MIR: a lowered representation of Rust.
3131
#![feature(option_get_or_insert_default)]
3232
#![feature(once_cell)]
3333
#![feature(control_flow_enum)]
34+
#![feature(trusted_step)]
3435
#![recursion_limit = "256"]
3536

3637
#[macro_use]

compiler/rustc_mir_build/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#![feature(bool_to_option)]
1111
#![feature(iter_zip)]
1212
#![feature(once_cell)]
13+
#![feature(min_specialization)]
14+
#![feature(trusted_step)]
1315
#![recursion_limit = "256"]
1416

1517
#[macro_use]

compiler/rustc_passes/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#![feature(in_band_lifetimes)]
1111
#![feature(iter_zip)]
1212
#![feature(nll)]
13+
#![feature(min_specialization)]
14+
#![feature(trusted_step)]
1315
#![recursion_limit = "256"]
1416

1517
#[macro_use]

compiler/rustc_query_system/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#![feature(iter_zip)]
77
#![feature(min_specialization)]
88
#![feature(stmt_expr_attributes)]
9+
#![feature(trusted_step)]
910

1011
#[macro_use]
1112
extern crate tracing;

compiler/rustc_span/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#![feature(nll)]
2222
#![feature(min_specialization)]
2323
#![feature(thread_local_const_init)]
24+
#![feature(trusted_step)]
2425

2526
#[macro_use]
2627
extern crate rustc_macros;

compiler/rustc_target/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#![feature(never_type)]
1515
#![feature(associated_type_bounds)]
1616
#![feature(exhaustive_patterns)]
17+
#![feature(min_specialization)]
18+
#![feature(trusted_step)]
1719

1820
use std::path::{Path, PathBuf};
1921

compiler/rustc_type_ir/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#![feature(min_specialization)]
2+
#![feature(trusted_step)]
3+
14
#[macro_use]
25
extern crate bitflags;
36
#[macro_use]

library/core/src/iter/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@ pub use self::traits::FusedIterator;
384384
pub use self::traits::InPlaceIterable;
385385
#[unstable(feature = "trusted_len", issue = "37572")]
386386
pub use self::traits::TrustedLen;
387+
#[unstable(feature = "trusted_step", issue = "85731")]
388+
pub use self::traits::TrustedStep;
387389
#[stable(feature = "rust1", since = "1.0.0")]
388390
pub use self::traits::{
389391
DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum,

0 commit comments

Comments
 (0)