ICMP is just different protocol from UDP. There's field "Protocol" in IP packet. 0x01 = ICMP, 0x06 = TCP, 0x11 = UDP.
I think that this article gets terminology wrong. It's not UDP socket that gets created here, but Datagram socket. Seems to be bad API naming in Rust library.
To give a more nuanced reply versus the "you're wrong" ones already here, the difference is that UDP adds send and receive ports, enabling most modern users (& uses) of UDP. Hence, it is the "User" datagram protocol.
(it also adds a checksum, which used to be more important than it is nowadays, but still well worth it imho.)
Let me rephrase GP into (I hope) a more useful analogy.
— actually, here’s the whole analogous exchange:
“A rectangle is an equal-sided rectangle (i.e. “square”) though. That’s what the R stands for.”
“No? Why would you think a rectangle is a square?”
Just as not all rectangles are squares (squares are a specific subset of rectangles), not all datagram protocols are UDP (UDP is just one particular datagram protocol).
The obvious answer is "I didn't know datagrams were a superset of UDP". I don't really understand how "how do you not know this" is a reasonable or useful question to ask.
Presumably you're also using systems that don't support Unix Domain Sockets which can be configured as SOCK_STREAM, SOCK_DGRAM, and even gasp SOCK_SEQPACKET (equivalent to SOCK_DGRAM in this case admittedly).
I think that this article gets terminology wrong. It's not UDP socket that gets created here, but Datagram socket. Seems to be bad API naming in Rust library.