As a side note, aside from whether I understand the following explanation correctly or not, I’ve never been confused by the adjacent sibling combinator.
matches the second element only if it immediately follows the first element, and both are children of the same parent element.
For example, I am not surprised by the result of ul + li.
First, it’s important to understand that p:first-child means “a <p> that is the first child of an arbitrary parent” and not "the first child of a <p>". Normally every element has a parent.
The quote you mentioned refers to an edge case: Think about this selector html:first-child. This code selects the <html> element. We know that <html> is the root element and therefore has no parent. In newer browsers the <html> still gets selected although it has no parent.
I looked at the compatibility table of the :first-child article and saw that Internet Explorer doesn’t support this selector for elements with no parent. To test my theory I put the following code into a .html file and opened it in Firefox and Internet Explorer 11:
Firefox displays the teal background color, because modern browsers don’t need a parent for this selector to work. Internet Explorers background stayed white, because it only excepts this selector if the element has a parent but <html> doesn’t have a parent.
You see, this is really a very special case and will probably never be a concern when developing.