The printer for lists is indeed quite sensitive to the exact path of the type being printed.

Any manipulation that muddles this path makes the printer revert to the generic sum type printer.

Moreover, in the case of `List`, the list type is re-exported as

type 'a t = 'a list = 
| []
| (::) of 'a * 'a list

Thus after opening the List module, the toplevel printer sees

1 :: (2 :: ...)

as

( 1 :: (2 :: ... : 'a list) : 'a t)

And since t is different that list, it prints the value as

(::)(1, ...)

then starting from the second element, we are back to 'a list and the pretty list printer.

This means that we can make the situation worse by re-exporting the type list as

type 'a t = 'a list = 
| []
| (::) of 'a * 'a t

With this definition, we completely confuse the pretty printer for lists and are rewarded with:

# [1;2];;
- : int t = (::) (1, (::) (2, []))

If you are interested, I have a small patch that makes the toplevel printer identify the list type more reliably: https://github.com/ocaml/ocaml/pull/9336 .

— octachron.