Add pattern matching for `typeof` into field type tparam (#50422)
* Add pattern matching for `typeof` into field type tparam
This PR allows full elimination of the following, even in
ill-typed code.
```
struct TParamTypeofTest{T}
x::T
@eval TParamTypeofTest(x) = $(Expr(:new, :(TParamTypeofTest{typeof(x)}), :x))
end
function tparam_typeof_test_elim(x)
TParamTypeofTest(x).x
end
```
Before this PR, we would get:
```
julia> code_typed(tparam_typeof_test_elim, Tuple{Any})
1-element Vector{Any}:
CodeInfo(
1 ─ %1 = Main.typeof(x)::DataType
│ %2 = Core.apply_type(Main.TParamTypeofTest, %1)::Type{TParamTypeofTest{_A}} where _A
│ %new(%2, x)::TParamTypeofTest
└── return x
```
Where the `new` is non-eliminable, because the compiler did not know that
`x::_A`. Fix this by pattern matching this particular pattern (where the
condition is guaranteed, because we computed `_A` by `typeof`).
This is not particularly general, but this pattern comes up a lot,
so it's surprisingly effective.
* add test case for optimizing multiple abstract fields
* improve robustness
---------
Co-authored-by: Shuhei Kadowaki <aviatesk@gmail.com>