I wonder if there is one trait that is implemented by all the primitive integer types and can be used here?
The num crate provides such a trait, but I'm not sure it would be terribly useful to you here. It sounds like at the end of your operation, you need a usize to be able to index an array, so you want to accept "some integer type," do some math with it, then get a usize out the other end.
You might be interested in the TryInto trait, which is like Into but specifies a possibly-fallible conversion. If you make your own function fallible, this would be an appropriate way to accept multiple integer types.
The Div and Rem bounds need to specify the output type, because right now the output is unbounded meaning you could get any type from their invocations; it wouldn't even have to be a numeric type.
However, assuming you need to keep isize as the intermediate type, you could just do something like this and forgo the Div and Rem bounds entirely:
enum FooError {
IntConversion,
OutOfSliceBounds,
}
fn foo<T: TryInto<isize>, V>(n: T, slice: &[V]) -> Result<&V, FooError>
{
let n: isize = n.try_into().map_err(|_| FooError::IntConversion)?;
// Do some math on n, then...
let n: usize = n.try_into().map_err(|_| FooError::IntConversion)?;
slice.get(n).ok_or(FooError::OutOfSliceBounds)
}
If isize is not large enough to be the intermediate type you could use a larger integer type, but to index a slice you have to be able to convert the final result to usize.
If the domain of usize is suitable for the math operations, you could just accept T: TryInto<usize> and then you don't need the second conversion at all.