Skip to content
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

"cabal: Internal error in target matching" (was: Internal error/infinite loop in D.Client.TargetSelector) #5081

Open
grayjay opened this issue Jan 31, 2018 · 7 comments · Fixed by #5263
Labels
attention: pr-welcome cabal-install: nix-local-build re: internal-error Internal error or crash via Haskell's "error" method re: target Concerning build targets like pkg:lib type: bug

Comments

@grayjay
Copy link
Collaborator

grayjay commented Jan 31, 2018

I reproduced the issue on master (3781531) by running the following command in the cabal repository:

$ cabal new-build test:unknown-test-suite
cabal: Internal error in target matching. It should always be possible to find
a syntax that's sufficiently qualified to give an unambiguous match. However
when matching 'test:unknown-test-suite' we found test:unknown-test-suite
(unknown-component) which does not have an unambiguous syntax. The possible
syntax and the targets they match are as follows:
cabal: <<loop>>

It also occurs when I run the same command on a simple project with one directory containing a simple .cabal file:

name: example
version: 1.0
build-type: Simple
cabal-version: >= 1.2

library

The error message is from D.Client.TargetSelector:

die' verbosity $ "Internal error in target matching. It should always "

@23Skidoo
Copy link
Member

23Skidoo commented Feb 1, 2018

/cc @dcoutts, may be caused by your recent patches.

@gelisam gelisam self-assigned this Apr 15, 2018
@gelisam
Copy link
Collaborator

gelisam commented Apr 16, 2018

I found it, I'll send a PR

gelisam added a commit that referenced this issue Apr 16, 2018
The pattern guard was clearly meant as a list-comprehension filter,
but on a let-bound pattern, it instead caused a circular loop in which
whether the LHS variables are bound the the RHS values depends on the
values of the LHS variables.

fixes #5081
@grayjay
Copy link
Collaborator Author

grayjay commented May 2, 2018

Reopening, since there is still an internal error. After #5263, cabal prints the full error message:

$ cabal new-build test:unknown-test-suite
cabal: Internal error in target matching. It should always be possible to find
a syntax that's sufficiently qualified to give an unambiguous match. However
when matching 'test:unknown-test-suite' we found test:unknown-test-suite
(unknown-component) which does not have an unambiguous syntax. The possible
syntax and the targets they match are as follows:
'test:unknown-test-suite' which matches test:unknown-test-suite
(unknown-component), :pkg:test:lib:test:file:unknown-test-suite (unknown-file)

@grayjay grayjay reopened this May 2, 2018
@gelisam
Copy link
Collaborator

gelisam commented May 3, 2018

Ah, I thought this bug was only about the loop, but now that I am taking a closer look at the error message, it does say "Internal error", so I guess this error message isn't supposed to be displayed in the first place. Hmm, what's the desired behaviour instead?

Let's see, if there is a package foo with a test-suite which is also named foo, and we ask for foo, we get the following error message:

cabal: Ambiguous target 'foo'. It could be:
test:foo (component)
lib:foo (component)

So I think what is going on is that test:unknown-test-suite is ambiguous, just like foo, and so cabal is trying to list a few alternatives which aren't ambiguous. Unfortunately, one of those alternatives is test:unknown-test-suite itself, which isn't any less ambiguous than test:unknown-test-suite. Fortunately, cabal has an internal sanity check which catches the problem and reports this as an internal error.

But wait, why is test:unknown-test-suite ambiguous? Now that the message no longer loops, we can see that the other possibility is :pkg:test:lib:test:file:unknown-test-suite, a format I have never seen before. Let's double-check the documentation.

Okay, so apparently there are many more ways of specifying a target than I though. Only looking at packages, libraries (which have the same name as the package) and test suites, we have all of those possibilities:

  • <package-name>
  • test
  • test:<test-suite>
  • <test-suite>
  • <package-name>:<test-suite>
  • <package-name>:test:<test-suite>
  • lib
  • lib:<package-name>
  • <package-name>:<package-name>
  • <package-name>:lib:<package-name>

So if the package and the test-suite are both named test, then asking for test or test:test are both ambiguous, as they can both either mean to build the library or the test-suite. Since we don't have a weirdly named package or test-suite, this still doesn't explain why test:unknown-test-suite is ambiguous. My guess is that there is a separate ambiguity-check for unknown targets:

  1. If there are multiple matching known targets, show some disambiguations. Otherwise,
  2. If there is only one matching known target, pick it. Otherwise,
  3. If there are no matching known targets, check for unknown targets.
  4. If there are multiple matching unknown targets, show some disambiguations. Otherwise,
  5. If there is only one matching unknown target, complain that the specified component doesn't exist.
  6. If there are no matching unknown target, complain that the target syntax is not recognized.

Our bug seems to be in phase 4: test:unknown-test-suite is obviously meant to refer to a test-suite named unknown-test-suite, but technically it could also refer to a package named test and a component (not necessarily a test suite) named unknown-test-suite. So the two ways of disambiguating are:

  • <package-name>:test:unknown-test-suite
  • test:<component-name>:unknown-test-suite

but since we're talking about a non-existing component, who knows which non-existing package name and component-name we should pick?

I now think the expected behaviour should be to offer the following disambiguations:

  • :test:unknown-test-suite
  • test:lib:unknown-test-suite
  • test:exe:unknown-test-suite
  • test:test:unknown-test-suite
  • test:bench:unknown-test-suite

Where the first disambiguation uses an empty package name, meaning the current package. That syntax doesn't refer to any package if the current folder uses a cabal.project file to specify multiple projects, but that should hopefully be enough to guide the user in the right direction. One alternative would be to list <package-name>:test:unknown-test-suite for every package in the cabal.project file.

@hvr hvr added the meta: hvr label Oct 24, 2018
@hvr hvr changed the title Internal error/infinite loop in D.Client.TargetSelector "cabal: Internal error in target matching" (was: Internal error/infinite loop in D.Client.TargetSelector) Oct 24, 2018
@emilypi emilypi removed the meta: hvr label Aug 11, 2021
@andreasabel
Copy link
Member

andreasabel commented Aug 31, 2021

A simple reproducer for this internal error is:

cabal-testsuite/PackageTests/Regression/T4025$ cabal run T4025:exe

cabal: Internal error in target matching. It should always be possible to find
a syntax that's sufficiently qualified to give an unambiguous match. However
when matching 'T4025:exe' we found T4025:exe (unknown-component) which does
not have an unambiguous syntax. The possible syntax and the targets they match
are as follows:
'T4025:exe' which matches T4025:exe (unknown-component),
:pkg:T4025:lib:T4025:file:exe (unknown-file)

$ cabal run T4025:exe:exe
cabal: Internal error in target matching ... the targets they
match are as follows:
'T4025:exe:exe' which matches T4025:exe:exe (unknown-component), T4025:exe:exe
(unknown-file)
':pkg:T4025:exe:exe' which matches T4025:exe:exe (unknown-component)

name: T4025
version: 1.0
build-type: Simple
cabal-version: >= 1.10
library
default-language: Haskell2010
build-depends: base
exposed-modules: A
executable exe
default-language: Haskell2010
build-depends: T4025, base
hs-source-dirs: exe
main-is: Main.hs

The error is likely caused by a cabal.project file in a parent directory (here: repo root).

The internal error goes away if I create a cabal.project file with entry:

packages: .

[Meta: removing stalled assignment.]

@andreasabel andreasabel added re: internal-error Internal error or crash via Haskell's "error" method re: target Concerning build targets like pkg:lib labels Aug 31, 2021
@ysangkok
Copy link
Member

The error is likely caused by a cabal.project file in a parent directory (here: repo root).

When using list-bin on https://gitlab.com/awjchen/hs-bittorrent , I get this error even without any cabal.project:

~/hs-bittorrent % cabal list-bin exe:hs-bittorrent
Error: cabal: Internal error in target matching. It should always be possible
to find a syntax that's sufficiently qualified to give an unambiguous match.
However when matching 'exe:hs-bittorrent' we found exe:hs-bittorrent
(unknown-component) which does not have an unambiguous syntax. The possible
syntax and the targets they match are as follows:
'exe:hs-bittorrent' which matches exe:hs-bittorrent (unknown-component),
:pkg:exe:lib:exe:file:hs-bittorrent (unknown-file)

And even if I add one, I still get it. Should I open another issue?

@gbaz
Copy link
Collaborator

gbaz commented Apr 18, 2022

This is a bad error, but in this case it is because there is only one stanza, and that stanza is not named hs-bittorrent, but rather hs-bittorrent-exe. So the target selector needs to pick that.

cabal list-bin hs-bittorrent-exe works correctly, as does cabal list-bin exe:cabal list-bin hs-bittorrent-exe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
attention: pr-welcome cabal-install: nix-local-build re: internal-error Internal error or crash via Haskell's "error" method re: target Concerning build targets like pkg:lib type: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants