Skip to content

Spurious duplicate modules error #7525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Bodigrim opened this issue Aug 10, 2021 · 12 comments
Closed

Spurious duplicate modules error #7525

Bodigrim opened this issue Aug 10, 2021 · 12 comments

Comments

@Bodigrim
Copy link
Collaborator

Bodigrim commented Aug 10, 2021

name:          duplicate-modules
version:       0.0
cabal-version: 2.0
build-type:    Simple
category:      NA
maintainer:    NA
synopsis:      NA
description:   NA NA
license:       BSD3
license-file:  LICENSE

flag expose

library
  default-language: Haskell2010
  if flag(expose)
    exposed-modules: Foo
  else
    other-modules: Foo

cabal check is unhappy with this:

Warning: The package will not build sanely due to these errors:
Warning: Duplicate modules in library: Foo
Warning: Hackage would reject this package.

I understand that it's a tricky situation for cabal and that potentially there could be exponentially many flag combinations, but practically, when number of flags is < 5, I'd expect cabal to evaluate all possible combinations and validate respective configurations independently.

@Mikolaj
Copy link
Member

Mikolaj commented Aug 10, 2021

I think it's worth designing a check that warns of such use of flags (even when the two module differ and so there's no error). I've just heard today experienced devs stating that cabal flags should not change a package API, as is the case in your example. Otherwise, flipping flags potentially causes breakage and cabal can't guess if it should rebuild half of package database or not to prevent it. Not to mention the horror of ensuring my package can handle various API-changing flags combinations of packages it depends on.

Also, each if-then-else can double the time solving takes, because it can change what a package depends on. That gets nasty long before 5 flags.

@Mikolaj
Copy link
Member

Mikolaj commented Aug 10, 2021

Having said that, if your goal is to conditionally expose internal modules, perhaps it can be done by putting them in an internal library, using in a library with exposed modules, and placing visibility:True of the internal library inside a conditional? I haven't tried that, so I'd be interested if it works or in any other workaround you may find.

@emilypi
Copy link
Member

emilypi commented Aug 11, 2021

It sounds like we're just parsing through the relevant flags other-modules and exposed-modules without considering conditionals, which tells me check needs to be smarter about the context in which these entries occur. Let's see if we can hunt this one down, but that's my working suspicion 😄

@Mikolaj
Copy link
Member

Mikolaj commented Aug 11, 2021

@emilypi: however, which flag values should check consider?

@emilypi
Copy link
Member

emilypi commented Aug 12, 2021

@Mikolaj let's think about it - i dont know check that well, but i did run into this comment which is probably the root of our problem:

   -- flatten the generic package description into a regular package
    -- description
    -- TODO: this may give more warnings than it should give;
    --       consider two branches of a condition, one saying
    --          ghc-options: -Wall
    --       and the other
    --          ghc-options: -Werror
    --      joined into
    --          ghc-options: -Wall -Werror
    --      checkPackages will yield a warning on the last line, but it
    --      would not on each individual branch.
    --      Hovever, this is the same way hackage does it, so we will yield
    --      the exact same errors as it will.

-- TODO: this may give more warnings than it should give;

"Flattening" branches seems to be happening here, and its wrong in this case.

@emilypi
Copy link
Member

emilypi commented Aug 12, 2021

AHA!

-- | Flatten a generic package description by ignoring all conditions and just
-- join the field descriptors into on package description.  Note, however,
-- that this may lead to inconsistent field values, since all values are
-- joined into one field, which may not be possible in the original package
-- description, due to the use of exclusive choices (if ... else ...).
--
-- TODO: One particularly tricky case is defaulting.  In the original package
-- description, e.g., the source directory might either be the default or a
-- certain, explicitly set path.  Since defaults are filled in only after the
-- package has been resolved and when no explicit value has been set, the
-- default path will be missing from the package description returned by this
-- function.

From

-- | Flatten a generic package description by ignoring all conditions and just
is the culprit.

@emilypi
Copy link
Member

emilypi commented Aug 16, 2021

Related: #4629

@ptkato
Copy link
Collaborator

ptkato commented Aug 20, 2021

Curiouser and curiouser! Apart from performance, is there any other reason as to why this flattening behaviour, without considering the conditionals, would be desired?

@emilypi
Copy link
Member

emilypi commented Aug 20, 2021

Laziness (in the pejorative sense) :)

@jneira
Copy link
Member

jneira commented Aug 22, 2021

I would say this is duplicate of #4629 so I would close it

@Mikolaj
Copy link
Member

Mikolaj commented Aug 23, 2021

Unless @Bodigrim objects, I think it makes sense to close.

@gbaz
Copy link
Collaborator

gbaz commented Sep 3, 2021

definitely a dup, closing.

@gbaz gbaz closed this as completed Sep 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants