Skip to content

Commit 57e2e86

Browse files
authored
[ty] Simplify lifetime requirements for PySlice trait (#19687)
1 parent 18aae21 commit 57e2e86

File tree

3 files changed

+22
-21
lines changed

3 files changed

+22
-21
lines changed

crates/ty_python_semantic/src/types/infer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8520,7 +8520,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
85208520
};
85218521

85228522
if let Ok(new_elements) = tuple.py_slice(db, start, stop, step) {
8523-
TupleType::from_elements(db, new_elements.copied())
8523+
TupleType::from_elements(db, new_elements)
85248524
} else {
85258525
report_slice_step_size_zero(context, value_node.into());
85268526
Type::unknown()
@@ -8599,7 +8599,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
85998599
let literal_value = literal_ty.value(db);
86008600

86018601
if let Ok(new_bytes) = literal_value.py_slice(db, start, stop, step) {
8602-
let new_bytes: Vec<u8> = new_bytes.copied().collect();
8602+
let new_bytes: Vec<u8> = new_bytes.collect();
86038603
Type::bytes_literal(db, &new_bytes)
86048604
} else {
86058605
report_slice_step_size_zero(context, value_node.into());

crates/ty_python_semantic/src/types/tuple.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,12 +500,12 @@ impl<'db> PySlice<'db> for FixedLengthTuple<Type<'db>> {
500500
type Item = Type<'db>;
501501

502502
fn py_slice(
503-
&'db self,
503+
&self,
504504
db: &'db dyn Db,
505505
start: Option<i32>,
506506
stop: Option<i32>,
507507
step: Option<i32>,
508-
) -> Result<impl Iterator<Item = &'db Self::Item>, StepSizeZeroError> {
508+
) -> Result<impl Iterator<Item = Self::Item>, StepSizeZeroError> {
509509
self.0.py_slice(db, start, stop, step)
510510
}
511511
}

crates/ty_python_semantic/src/util/subscript.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,27 @@ pub(crate) trait PySlice<'db> {
111111
type Item: 'db;
112112

113113
fn py_slice(
114-
&'db self,
114+
&self,
115115
db: &'db dyn Db,
116116
start: Option<i32>,
117117
stop: Option<i32>,
118118
step: Option<i32>,
119-
) -> Result<impl Iterator<Item = &'db Self::Item>, StepSizeZeroError>;
119+
) -> Result<impl Iterator<Item = Self::Item>, StepSizeZeroError>;
120120
}
121121

122-
impl<'db, T: 'db> PySlice<'db> for [T] {
122+
impl<'db, T> PySlice<'db> for [T]
123+
where
124+
T: Copy + 'db,
125+
{
123126
type Item = T;
124127

125128
fn py_slice(
126-
&'db self,
129+
&self,
127130
_db: &'db dyn Db,
128131
start: Option<i32>,
129132
stop: Option<i32>,
130133
step_int: Option<i32>,
131-
) -> Result<impl Iterator<Item = &'db Self::Item>, StepSizeZeroError> {
134+
) -> Result<impl Iterator<Item = Self::Item>, StepSizeZeroError> {
132135
let step_int = step_int.unwrap_or(1);
133136
if step_int == 0 {
134137
return Err(StepSizeZeroError);
@@ -139,12 +142,12 @@ impl<'db, T: 'db> PySlice<'db> for [T] {
139142
// The iterator needs to have the same type as the step>0 case below,
140143
// so we need to use `.skip(0)`.
141144
#[expect(clippy::iter_skip_zero)]
142-
return Ok(Either::Left(self.iter().skip(0).take(0).step_by(1)));
145+
return Ok(Either::Left(self.iter().skip(0).take(0).step_by(1)).copied());
143146
}
144147

145148
let to_position = |index| Nth::from_index(index).to_position(len);
146149

147-
if step_int.is_positive() {
150+
let iter = if step_int.is_positive() {
148151
let step = from_nonnegative_i32(step_int);
149152

150153
let start = start.map(to_position).unwrap_or(Position::BeforeStart);
@@ -168,9 +171,7 @@ impl<'db, T: 'db> PySlice<'db> for [T] {
168171
(0, 0, step)
169172
};
170173

171-
Ok(Either::Left(
172-
self.iter().skip(skip).take(take).step_by(step),
173-
))
174+
Either::Left(self.iter().skip(skip).take(take).step_by(step))
174175
} else {
175176
let step = from_negative_i32(step_int);
176177

@@ -195,10 +196,10 @@ impl<'db, T: 'db> PySlice<'db> for [T] {
195196
(skip, take, step)
196197
};
197198

198-
Ok(Either::Right(
199-
self.iter().rev().skip(skip).take(take).step_by(step),
200-
))
201-
}
199+
Either::Right(self.iter().rev().skip(skip).take(take).step_by(step))
200+
};
201+
202+
Ok(iter.copied())
202203
}
203204
}
204205

@@ -210,7 +211,7 @@ mod tests {
210211
use crate::util::subscript::{OutOfBoundsError, StepSizeZeroError};
211212

212213
use super::{PyIndex, PySlice};
213-
use itertools::assert_equal;
214+
use itertools::{Itertools, assert_equal};
214215

215216
#[test]
216217
fn py_index_empty() {
@@ -276,8 +277,8 @@ mod tests {
276277
expected: &[char; M],
277278
) {
278279
assert_equal(
279-
input.py_slice(db, start, stop, step).unwrap(),
280-
expected.iter(),
280+
input.py_slice(db, start, stop, step).unwrap().collect_vec(),
281+
expected.iter().copied().collect_vec(),
281282
);
282283
}
283284

0 commit comments

Comments
 (0)