mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
[ty] Simplify lifetime requirements for PySlice
trait (#19687)
This commit is contained in:
parent
18aae21b9a
commit
57e2e8664f
3 changed files with 22 additions and 21 deletions
|
@ -8520,7 +8520,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(new_elements) = tuple.py_slice(db, start, stop, step) {
|
if let Ok(new_elements) = tuple.py_slice(db, start, stop, step) {
|
||||||
TupleType::from_elements(db, new_elements.copied())
|
TupleType::from_elements(db, new_elements)
|
||||||
} else {
|
} else {
|
||||||
report_slice_step_size_zero(context, value_node.into());
|
report_slice_step_size_zero(context, value_node.into());
|
||||||
Type::unknown()
|
Type::unknown()
|
||||||
|
@ -8599,7 +8599,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
let literal_value = literal_ty.value(db);
|
let literal_value = literal_ty.value(db);
|
||||||
|
|
||||||
if let Ok(new_bytes) = literal_value.py_slice(db, start, stop, step) {
|
if let Ok(new_bytes) = literal_value.py_slice(db, start, stop, step) {
|
||||||
let new_bytes: Vec<u8> = new_bytes.copied().collect();
|
let new_bytes: Vec<u8> = new_bytes.collect();
|
||||||
Type::bytes_literal(db, &new_bytes)
|
Type::bytes_literal(db, &new_bytes)
|
||||||
} else {
|
} else {
|
||||||
report_slice_step_size_zero(context, value_node.into());
|
report_slice_step_size_zero(context, value_node.into());
|
||||||
|
|
|
@ -500,12 +500,12 @@ impl<'db> PySlice<'db> for FixedLengthTuple<Type<'db>> {
|
||||||
type Item = Type<'db>;
|
type Item = Type<'db>;
|
||||||
|
|
||||||
fn py_slice(
|
fn py_slice(
|
||||||
&'db self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
start: Option<i32>,
|
start: Option<i32>,
|
||||||
stop: Option<i32>,
|
stop: Option<i32>,
|
||||||
step: Option<i32>,
|
step: Option<i32>,
|
||||||
) -> Result<impl Iterator<Item = &'db Self::Item>, StepSizeZeroError> {
|
) -> Result<impl Iterator<Item = Self::Item>, StepSizeZeroError> {
|
||||||
self.0.py_slice(db, start, stop, step)
|
self.0.py_slice(db, start, stop, step)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,24 +111,27 @@ pub(crate) trait PySlice<'db> {
|
||||||
type Item: 'db;
|
type Item: 'db;
|
||||||
|
|
||||||
fn py_slice(
|
fn py_slice(
|
||||||
&'db self,
|
&self,
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
start: Option<i32>,
|
start: Option<i32>,
|
||||||
stop: Option<i32>,
|
stop: Option<i32>,
|
||||||
step: Option<i32>,
|
step: Option<i32>,
|
||||||
) -> Result<impl Iterator<Item = &'db Self::Item>, StepSizeZeroError>;
|
) -> Result<impl Iterator<Item = Self::Item>, StepSizeZeroError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'db, T: 'db> PySlice<'db> for [T] {
|
impl<'db, T> PySlice<'db> for [T]
|
||||||
|
where
|
||||||
|
T: Copy + 'db,
|
||||||
|
{
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn py_slice(
|
fn py_slice(
|
||||||
&'db self,
|
&self,
|
||||||
_db: &'db dyn Db,
|
_db: &'db dyn Db,
|
||||||
start: Option<i32>,
|
start: Option<i32>,
|
||||||
stop: Option<i32>,
|
stop: Option<i32>,
|
||||||
step_int: Option<i32>,
|
step_int: Option<i32>,
|
||||||
) -> Result<impl Iterator<Item = &'db Self::Item>, StepSizeZeroError> {
|
) -> Result<impl Iterator<Item = Self::Item>, StepSizeZeroError> {
|
||||||
let step_int = step_int.unwrap_or(1);
|
let step_int = step_int.unwrap_or(1);
|
||||||
if step_int == 0 {
|
if step_int == 0 {
|
||||||
return Err(StepSizeZeroError);
|
return Err(StepSizeZeroError);
|
||||||
|
@ -139,12 +142,12 @@ impl<'db, T: 'db> PySlice<'db> for [T] {
|
||||||
// The iterator needs to have the same type as the step>0 case below,
|
// The iterator needs to have the same type as the step>0 case below,
|
||||||
// so we need to use `.skip(0)`.
|
// so we need to use `.skip(0)`.
|
||||||
#[expect(clippy::iter_skip_zero)]
|
#[expect(clippy::iter_skip_zero)]
|
||||||
return Ok(Either::Left(self.iter().skip(0).take(0).step_by(1)));
|
return Ok(Either::Left(self.iter().skip(0).take(0).step_by(1)).copied());
|
||||||
}
|
}
|
||||||
|
|
||||||
let to_position = |index| Nth::from_index(index).to_position(len);
|
let to_position = |index| Nth::from_index(index).to_position(len);
|
||||||
|
|
||||||
if step_int.is_positive() {
|
let iter = if step_int.is_positive() {
|
||||||
let step = from_nonnegative_i32(step_int);
|
let step = from_nonnegative_i32(step_int);
|
||||||
|
|
||||||
let start = start.map(to_position).unwrap_or(Position::BeforeStart);
|
let start = start.map(to_position).unwrap_or(Position::BeforeStart);
|
||||||
|
@ -168,9 +171,7 @@ impl<'db, T: 'db> PySlice<'db> for [T] {
|
||||||
(0, 0, step)
|
(0, 0, step)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Either::Left(
|
Either::Left(self.iter().skip(skip).take(take).step_by(step))
|
||||||
self.iter().skip(skip).take(take).step_by(step),
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
let step = from_negative_i32(step_int);
|
let step = from_negative_i32(step_int);
|
||||||
|
|
||||||
|
@ -195,10 +196,10 @@ impl<'db, T: 'db> PySlice<'db> for [T] {
|
||||||
(skip, take, step)
|
(skip, take, step)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Either::Right(
|
Either::Right(self.iter().rev().skip(skip).take(take).step_by(step))
|
||||||
self.iter().rev().skip(skip).take(take).step_by(step),
|
};
|
||||||
))
|
|
||||||
}
|
Ok(iter.copied())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +211,7 @@ mod tests {
|
||||||
use crate::util::subscript::{OutOfBoundsError, StepSizeZeroError};
|
use crate::util::subscript::{OutOfBoundsError, StepSizeZeroError};
|
||||||
|
|
||||||
use super::{PyIndex, PySlice};
|
use super::{PyIndex, PySlice};
|
||||||
use itertools::assert_equal;
|
use itertools::{Itertools, assert_equal};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn py_index_empty() {
|
fn py_index_empty() {
|
||||||
|
@ -276,8 +277,8 @@ mod tests {
|
||||||
expected: &[char; M],
|
expected: &[char; M],
|
||||||
) {
|
) {
|
||||||
assert_equal(
|
assert_equal(
|
||||||
input.py_slice(db, start, stop, step).unwrap(),
|
input.py_slice(db, start, stop, step).unwrap().collect_vec(),
|
||||||
expected.iter(),
|
expected.iter().copied().collect_vec(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue