Skip to content

Commit

Permalink
Auto merge of #83772 - jhpratt:revamp-step-trait, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed May 30, 2021
2 parents 84b1005 + 741b9a4 commit 9a72afa
Show file tree
Hide file tree
Showing 20 changed files with 423 additions and 122 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#![feature(iter_zip)]
#![feature(label_break_value)]
#![feature(nll)]
#![feature(min_specialization)]
#![feature(trusted_step)]
#![recursion_limit = "256"]

#[macro_use]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#![cfg_attr(bootstrap, feature(extended_key_value_attributes))]
#![feature(in_band_lifetimes)]
#![feature(once_cell)]
#![feature(min_specialization)]
#![feature(trusted_step)]
#![recursion_limit = "256"]

#[macro_use]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_index/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![feature(unboxed_closures)]
#![feature(test)]
#![feature(fn_traits)]
#![feature(trusted_step)]

pub mod bit_set;
pub mod vec;
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_index/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl Idx for u32 {
/// `u32::MAX`. You can also customize things like the `Debug` impl,
/// what traits are derived, and so forth via the macro.
#[macro_export]
#[allow_internal_unstable(step_trait, step_trait_ext, rustc_attrs)]
#[allow_internal_unstable(step_trait, rustc_attrs)]
macro_rules! newtype_index {
// ---- public rules ----

Expand Down Expand Up @@ -184,7 +184,7 @@ macro_rules! newtype_index {
}
}

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

// Safety: The implementation of `Step` upholds all invariants.
unsafe impl ::std::iter::TrustedStep for $type {}

impl From<$type> for u32 {
#[inline]
fn from(v: $type) -> u32 {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#![feature(never_type)]
#![feature(in_band_lifetimes)]
#![feature(control_flow_enum)]
#![feature(min_specialization)]
#![feature(trusted_step)]
#![recursion_limit = "512"] // For rustdoc

#[macro_use]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#![feature(associated_type_defaults)]
#![feature(iter_zip)]
#![feature(thread_local_const_init)]
#![feature(trusted_step)]
#![recursion_limit = "512"]

#[macro_use]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Rust MIR: a lowered representation of Rust.
#![feature(option_get_or_insert_default)]
#![feature(once_cell)]
#![feature(control_flow_enum)]
#![feature(trusted_step)]
#![recursion_limit = "256"]

#[macro_use]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir_build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#![feature(bool_to_option)]
#![feature(iter_zip)]
#![feature(once_cell)]
#![feature(min_specialization)]
#![feature(trusted_step)]
#![recursion_limit = "256"]

#[macro_use]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_passes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#![feature(in_band_lifetimes)]
#![feature(iter_zip)]
#![feature(nll)]
#![feature(min_specialization)]
#![feature(trusted_step)]
#![recursion_limit = "256"]

#[macro_use]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_query_system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![feature(iter_zip)]
#![feature(min_specialization)]
#![feature(stmt_expr_attributes)]
#![feature(trusted_step)]

#[macro_use]
extern crate tracing;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#![feature(nll)]
#![feature(min_specialization)]
#![feature(thread_local_const_init)]
#![feature(trusted_step)]

#[macro_use]
extern crate rustc_macros;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#![feature(never_type)]
#![feature(associated_type_bounds)]
#![feature(exhaustive_patterns)]
#![feature(min_specialization)]
#![feature(trusted_step)]

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

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_type_ir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#![feature(min_specialization)]
#![feature(trusted_step)]

#[macro_use]
extern crate bitflags;
#[macro_use]
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,8 @@ pub use self::traits::FusedIterator;
pub use self::traits::InPlaceIterable;
#[unstable(feature = "trusted_len", issue = "37572")]
pub use self::traits::TrustedLen;
#[unstable(feature = "trusted_step", issue = "85731")]
pub use self::traits::TrustedStep;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::{
DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum,
Expand Down
Loading

0 comments on commit 9a72afa

Please sign in to comment.