Skip to content

Bug: Module/functor arguments with "module type of" malformatted #2776

Description

@JanBeh

Bug description:

Given a functor with three arguments of which the second has a module type denoted with a module type of statement referring to the previous functor argument, the resulting line-breaking and indentation seems to be wrong, at least in some cases.

Reproduction:

The bug should be reproducible as follows. Use ocamlformat version 0.28.1:

$ ocamlformat --version
0.28.1

Create a .ocamlformat file with:

ocaml-version=5.4

Create a file formatbug.ml with:

module M
    (Ord : Set.OrderedType)
    (SomeSet : module type of Set.Make (Ord))
    (SomeOtherFunctorArgument : Set.OrderedType) =
struct
  let f = SomeSet.singleton
end

Runing ocamlformat formatbug.ml gives:

module M
    (Ord : Set.OrderedType)
    (SomeSet :
      module type of Set.Make (Ord))
        (SomeOtherFunctorArgument : Set.OrderedType) =
struct
  let f = SomeSet.singleton
end

What I expect instead:

I would expect all functor arguments to be idented with the same level (as in the input). Also, I would not expect a line break after "SomeSet :".

Cases that work correctly:

Note that the following files result in identical output (i.e. the indentation remains correct):

module M
    (Ord : Set.OrderedType)
    (SomeSet : module type of Set.Make (Ord)) =
struct
  let f = SomeSet.singleton
end
module M
    (Ord : Set.OrderedType)
    (SomeSet : Set.S with type elt = Ord.t)
    (SomeOtherFunctorArgument : Set.OrderedType) =
struct
  let f = SomeSet.singleton
end
module M =
functor
  (Ord : Set.OrderedType)
  (SomeSet : module type of Set.Make (Ord))
  (SomeOtherFunctorArgument : Set.OrderedType)
  ->
  struct
    let f = SomeSet.singleton
  end

Used configuration:

Querying the configuration gives the following result:

$ ocamlformat --print-config
comment-check=true
debug=false
disable=false
margin-check=false
max-iters=10
ocaml-version=5.4 (file .ocamlformat:1)
quiet=false
disable-conf-attrs=false
version-check=true
assignment-operator=end-line
break-before-in=fit-or-vertical
break-cases=fit
break-collection-expressions=fit-or-vertical
break-colon=after
break-fun-decl=wrap
break-fun-sig=wrap
break-infix=wrap
break-infix-before-func=false
break-separators=after
break-sequences=true
break-string-literals=auto
break-struct=force
cases-exp-indent=4
cases-matching-exp-indent=normal
disambiguate-non-breaking-match=false
doc-comments=after-when-possible
doc-comments-padding=2
doc-comments-tag-only=default
dock-collection-brackets=true
exp-grouping=preserve
extension-indent=2
field-space=loose
function-indent=2
function-indent-nested=never
if-then-else=compact
indent-after-in=0
indicate-multiline-delimiters=no
indicate-nested-or-patterns=unsafe-no
infix-precedence=indent
leading-nested-match-parens=false
let-and=compact
let-binding-indent=2
let-binding-deindent-fun=true
let-binding-spacing=compact
let-module=compact
line-endings=lf
margin=80
match-indent=0
match-indent-nested=never
max-indent=68
module-indent=2
module-item-spacing=compact
nested-match=wrap
ocp-indent-compat=false
parens-ite=false
parens-tuple=always
parens-tuple-patterns=multi-line-only
parse-docstrings=true
parse-toplevel-phrases=false
sequence-blank-line=preserve-one
sequence-style=terminator
single-case=compact
space-around-arrays=true
space-around-lists=true
space-around-records=true
space-around-variants=true
stritem-extension-indent=0
type-decl=compact
type-decl-indent=2
wrap-comments=false
wrap-fun-args=true
profile=default

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions