@@ -17,6 +17,7 @@ import GHC
17import Ormolu.Printer.Combinators
17import Ormolu.Printer.Combinators
18import Ormolu.Printer.Meat.Common
18import Ormolu.Printer.Meat.Common
19import Ormolu.Utils
19import Ormolu.Utils
20+import SrcLoc (combineSrcSpans)
20import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration.Value (p_hsSplice)
21import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration.Value (p_hsSplice)
22p_hsType :: HsType GhcPs -> R ()
23p_hsType :: HsType GhcPs -> R ()
@@ -66,13 +67,26 @@ p_hsType = \case
66 HsSumTy NoExt xs ->
67 HsSumTy NoExt xs ->
67 parensHash . sitcc $
68 parensHash . sitcc $
68 sep (txt "| " >> breakpoint') (sitcc . located' p_hsType) xs
69 sep (txt "| " >> breakpoint') (sitcc . located' p_hsType) xs
69− HsOpTy NoExt x op y -> do
70+ HsOpTy NoExt x op y -> sitcc $ do
71+ -- In the AST, type operators are right-associative instead of left-associative
72+ -- like value level operators. This makes similar constructs look inconsistent.
73+ -- Here, we shake the AST to convert right-associative tree to a left-associative
76+ HsOpTy NoExt x' op' y' ->
80+ (L (combineSrcSpans (getLoc x) (getLoc x')) (HsOpTy NoExt x op x'))
70− located x p_hsType
84+ located x p_hsType
71− breakpoint
85+ breakpoint
72− inci $ do
86+ inci $ do
73− p_rdrName op
87+ p_rdrName op
75− located y p_hsType
89+ located y p_hsType
76 HsParTy NoExt (L _ t@HsKindSig {}) ->
90 HsParTy NoExt (L _ t@HsKindSig {}) ->
77 -- NOTE Kind signatures already put parentheses around in all cases, so
91 -- NOTE Kind signatures already put parentheses around in all cases, so
78 -- skip this layer of parentheses. The reason for this behavior is that
92 -- skip this layer of parentheses. The reason for this behavior is that