[red-knot] Improve ergonomics for the PySlice trait (#13983)

This commit is contained in:
Alex Waygood 2024-10-29 20:40:59 +00:00 committed by GitHub
parent 96b3c400fe
commit 39cf46ecd6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 8 additions and 11 deletions

View file

@ -3228,7 +3228,7 @@ impl<'db> TypeInferenceBuilder<'db> {
let elements = tuple_ty.elements(self.db); let elements = tuple_ty.elements(self.db);
let (start, stop, step) = slice_ty.as_tuple(self.db); let (start, stop, step) = slice_ty.as_tuple(self.db);
if let Ok(new_elements) = elements.as_ref().py_slice(start, stop, step) { if let Ok(new_elements) = elements.py_slice(start, stop, step) {
let new_elements: Vec<_> = new_elements.copied().collect(); let new_elements: Vec<_> = new_elements.copied().collect();
Type::Tuple(TupleType::new(self.db, new_elements.into_boxed_slice())) Type::Tuple(TupleType::new(self.db, new_elements.into_boxed_slice()))
} else { } else {
@ -3267,7 +3267,7 @@ impl<'db> TypeInferenceBuilder<'db> {
let (start, stop, step) = slice_ty.as_tuple(self.db); let (start, stop, step) = slice_ty.as_tuple(self.db);
let chars: Vec<_> = literal_value.chars().collect(); let chars: Vec<_> = literal_value.chars().collect();
let result = if let Ok(new_chars) = chars.as_slice().py_slice(start, stop, step) { let result = if let Ok(new_chars) = chars.py_slice(start, stop, step) {
let literal: String = new_chars.collect(); let literal: String = new_chars.collect();
Type::StringLiteral(StringLiteralType::new(self.db, literal.into_boxed_str())) Type::StringLiteral(StringLiteralType::new(self.db, literal.into_boxed_str()))
} else { } else {
@ -3303,7 +3303,7 @@ impl<'db> TypeInferenceBuilder<'db> {
let literal_value = literal_ty.value(self.db); let literal_value = literal_ty.value(self.db);
let (start, stop, step) = slice_ty.as_tuple(self.db); let (start, stop, step) = slice_ty.as_tuple(self.db);
if let Ok(new_bytes) = literal_value.as_ref().py_slice(start, stop, step) { if let Ok(new_bytes) = literal_value.py_slice(start, stop, step) {
let new_bytes: Vec<u8> = new_bytes.copied().collect(); let new_bytes: Vec<u8> = new_bytes.copied().collect();
Type::BytesLiteral(BytesLiteralType::new(self.db, new_bytes.into_boxed_slice())) Type::BytesLiteral(BytesLiteralType::new(self.db, new_bytes.into_boxed_slice()))
} else { } else {

View file

@ -106,7 +106,7 @@ pub(crate) trait PySlice {
>; >;
} }
impl<T> PySlice for &[T] { impl<T> PySlice for [T] {
type Item = T; type Item = T;
fn py_slice( fn py_slice(
@ -257,10 +257,7 @@ mod tests {
step: Option<i32>, step: Option<i32>,
expected: &[char; M], expected: &[char; M],
) { ) {
assert_equal( assert_equal(input.py_slice(start, stop, step).unwrap(), expected.iter());
input.as_slice().py_slice(start, stop, step).unwrap(),
expected.iter(),
);
} }
#[test] #[test]
@ -431,15 +428,15 @@ mod tests {
// Step size zero is invalid: // Step size zero is invalid:
assert!(matches!( assert!(matches!(
input.as_slice().py_slice(None, None, Some(0)), input.py_slice(None, None, Some(0)),
Err(StepSizeZeroError) Err(StepSizeZeroError)
)); ));
assert!(matches!( assert!(matches!(
input.as_slice().py_slice(Some(0), Some(5), Some(0)), input.py_slice(Some(0), Some(5), Some(0)),
Err(StepSizeZeroError) Err(StepSizeZeroError)
)); ));
assert!(matches!( assert!(matches!(
input.as_slice().py_slice(Some(0), Some(0), Some(0)), input.py_slice(Some(0), Some(0), Some(0)),
Err(StepSizeZeroError) Err(StepSizeZeroError)
)); ));