better type inference for several functions taking `NTuple` args (#55124)
Improves the abstract return type inference for these functions, for
homogeneous tuple arguments:
* `tail`
* `front`
* `reverse`
* `circshift`
Example:
```julia
f(g, t::Type{<:Tuple}) = println(Core.Compiler.return_type(g, t))
f(Base.tail, Tuple{NTuple})
f(Base.front, Tuple{NTuple})
f(reverse, Tuple{NTuple})
f(circshift, Tuple{NTuple,Int})
```
Results before:
```julia
Tuple
Tuple
Tuple
Tuple
```
Results after:
```julia
NTuple{N, T} where {N, T}
NTuple{N, T} where {N, T}
NTuple{N, T} where {N, T}
NTuple{N, T} where {N, T}
```
Updates #54495