Here it's applying the cast function to main1. What cast does is take an object of type a and a coercion between a and b and using it coerces the object from a to b. Its type signature could be written as:

cast :: a -> (a ~# b) -> b

Where (~#) is the type of unboxed coercions. Think of it as the compiler-internal version of (~). Read a paper by SPJ if you really want to know the difference. As you can see, the type of the second argument of cast, the coercion, is declared in the core explicitly:

:: (State# RealWorld -> (# State# RealWorld, () #)) ~# IO ()

In other words:

a = State# RealWorld -> (# State# RealWorld, () #)
b = IO ()

So it's casting from that first type to the second type, just as Tekmo wrote. (And (# #) is the type of unboxed tuples, just for the record.)

The only part left is that it's not enough to give a type for the coercion: there also has to be a coercion object, which is generated by the compiler during type inference and type checking as evidence that the cast is legal. Here it looks like this:

Sym (NTCo:IO <()>)

Sym stands for Symmetry - a coercion is valid in either direction, and this just flips it around. NTCo presumably stands for Newtype Coercion. And it specifies which newtype coercion we're talking about: the one for IO, with the argument type (). Presumably the newtype coercion by default points in the other direction, so it has to be flipped around with Sym. I don't know this for sure, but it looks like NTCo and Sym are constructors for the (~#) type. Which would make a bunch of sense.

I think it is a shame that most of the "Core overview"-articles don't deal with type applications (the at-sign stuff). I find that it's hard to understand what's going on when you ignore that. In general, I would just recommend that people read this paper, which explains System Fc, which is pretty much just GHC Core in a language theory setting.