Repository: spack/spack

Issue:
Environment concretization NOP with no error
### Steps to reproduce

```console
$ spack env create gcc
$ spack -e gcc add gcc@12.2.0%gcc@4.8.5 +binutils +bootstrap +graphite +profiled +strip ~nvptx build_type=Release languages=c,c++,fortran,lto ^binutils+gas+gold+ld+lto+plugins@2.39:2
$ spack -e gcc concretize
$ spack -e gcc find --no-groups --show-full-compiler -cfvNd
```

### Error message

```console
$ spack env create gcc
==> Created environment 'gcc' in /home/greenc/work/cet-is/sources/Spack/spack/var/spack/environments/gcc
==> You can activate this environment with:
==>   spack env activate gcc
$ spack -e gcc add gcc@12.2.0%gcc@4.8.5 +binutils +bootstrap +graphite +profiled +strip ~nvptx build_type=Release languages=c,c++,fortran,lto ^binutils+gas+gold+ld+lto+plugins@2.39:2
==> Adding gcc@12.2.0%gcc@4.8.5+binutils+bootstrap+graphite~nvptx+profiled+strip build_type=Release languages=c,c++,fortran,lto ^binutils@2.39:2+gas+gold+ld+lto+plugins to environment gcc
$ spack -e gcc concretize
==> Fetching https://mirror.spack.io/bootstrap/github-actions/v0.4/build_cache/linux-centos7-x86_64-gcc-10.2.1-patchelf-0.16.1-p72zyan5wrzuabtmzq7isa5mzyh6ahdp.spec.json
==> Fetching https://mirror.spack.io/bootstrap/github-actions/v0.4/build_cache/linux-centos7-x86_64/gcc-10.2.1/patchelf-0.16.1/linux-centos7-x86_64-gcc-10.2.1-patchelf-0.16.1-p72zyan5wrzuabtmzq7isa5mzyh6ahdp.spack
==> Installing "patchelf@0.16.1%gcc@10.2.1 ldflags="-static-libstdc++ -static-libgcc"  build_system=autotools arch=linux-centos7-x86_64" from a buildcache
==> Fetching https://mirror.spack.io/bootstrap/github-actions/v0.4/build_cache/linux-centos7-x86_64-gcc-10.2.1-clingo-bootstrap-spack-prqkzynv2nwko5mktitebgkeumuxkveu.spec.json
==> Fetching https://mirror.spack.io/bootstrap/github-actions/v0.4/build_cache/linux-centos7-x86_64/gcc-10.2.1/clingo-bootstrap-spack/linux-centos7-x86_64-gcc-10.2.1-clingo-bootstrap-spack-prqkzynv2nwko5mktitebgkeumuxkveu.spack
==> Installing "clingo-bootstrap@spack%gcc@10.2.1~docs~ipo+python+static_libstdcpp build_type=Release arch=linux-centos7-x86_64" from a buildcache
$ spack -e gcc find --no-groups --show-full-compiler -cfvNd
==> In environment gcc
==> Root specs
gcc@12.2.0%gcc@4.8.5 +binutils+bootstrap+graphite~nvptx+profiled+strip build_type=Release languages=c,c++,fortran,lto
    binutils@2.39:2 +gas+gold+ld+lto+plugins


==> Concretized roots
==> Error: max() arg is an empty sequence
```

### Information on your system

* **Spack:** 0.20.0.dev0
* **Python:** 3.6.8
* **Platform:** linux-scientific7-skylake_avx512
* **Concretizer:** clingo

```console
$ git lg -1
* 8195f27 - (HEAD, upstream/develop, upstream-develop) Windows: properly handle symlink failures (#36003) (56 minutes ago) <John W. Parent>
```

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have searched the issues of this repo and believe this is not a duplicate
- [X] I have run the failing commands in debug mode and reported the output


Discussion:
Could reproduce. Bisecting points to this PR https://github.com/spack/spack/pull/35681 of mine
Here's the bugfix:
```diff
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index ea839e15e1..42ce486233 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -501,7 +501,7 @@ def _compute_specs_from_answer_set(self):
                 key = providers[0]
             candidate = answer.get(key)
 
-            if candidate and candidate.intersects(input_spec):
+            if candidate and candidate.satisfies(input_spec):
                 self._concrete_specs.append(answer[key])
                 self._concrete_specs_by_input[input_spec] = answer[key]
             else:
```
Now the most difficult part to find a reproducer that can fit a unit test.
Theoretically, `candidate` is a concrete spec and the result of `intersects` and `satisfies` should be the same with an abstract spec. I think we are hitting a bug in the implementation of `intersects` with versions, but need to confirm this.
To answer why does it show up in environments and not in `spack spec`. In `environments` we go over this line:

https://github.com/spack/spack/blob/8195f27a661846311eae8412f8b8b3f0f0c2d368/lib/spack/spack/concretize.py#L748

that triggers the line with the fix above. In `spack spec` instead we access directly another attribute of the result:

https://github.com/spack/spack/blob/8195f27a661846311eae8412f8b8b3f0f0c2d368/lib/spack/spack/spec.py#L2800

which doesn't follow the buggy code path.
I'll apply the patch locally and let you know, thank you.

Looks like the patch has me operating again, thank you.
The reproducer with `gcc` is failing here:

https://github.com/spack/spack/blob/8195f27a661846311eae8412f8b8b3f0f0c2d368/lib/spack/spack/spec.py#L3588-L3598

which is a piece of code that gave us trouble also before (with `cp2k` iirc). It's kind of hard to find something similar that can be triggered with mock packages.[^1]

[^1]: I can setup a test with `gcc` as a case, but it takes 24 secs. on my platform, so I'd rather avoid it. 

Resolving patch:
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -501,7 +501,7 @@ def _compute_specs_from_answer_set(self):
                 key = providers[0]
             candidate = answer.get(key)
 
-            if candidate and candidate.intersects(input_spec):
+            if candidate and candidate.satisfies(input_spec):
                 self._concrete_specs.append(answer[key])
                 self._concrete_specs_by_input[input_spec] = answer[key]
             else:
diff --git a/var/spack/repos/builtin.mock/packages/v1-consumer/package.py b/var/spack/repos/builtin.mock/packages/v1-consumer/package.py
--- a/var/spack/repos/builtin.mock/packages/v1-consumer/package.py
+++ b/var/spack/repos/builtin.mock/packages/v1-consumer/package.py
@@ -16,3 +16,5 @@ class V1Consumer(Package):
 
     depends_on("v2")
     depends_on("v1")
+
+    provides("somelang")


Test patch:
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -2076,3 +2076,24 @@ def test_external_python_extension_find_unified_python(self):
         abstract_specs = [spack.spec.Spec(s) for s in ["py-extension1", "python"]]
         specs = spack.concretize.concretize_specs_together(*abstract_specs)
         assert specs[0]["python"] == specs[1]["python"]
+
+    @pytest.mark.regression("36190")
+    @pytest.mark.parametrize(
+        "specs",
+        [
+            ["mpileaks^ callpath ^dyninst@8.1.1:8 ^mpich2@1.3:1"],
+            ["multivalue-variant ^a@2:2"],
+            ["v1-consumer ^conditional-provider@1:1 +disable-v1"],
+        ],
+    )
+    def test_result_specs_is_not_empty(self, specs):
+        """Check that the implementation of "result.specs" is correct in cases where we
+        know a concretization exists.
+        """
+        specs = [spack.spec.Spec(s) for s in specs]
+        solver = spack.solver.asp.Solver()
+        setup = spack.solver.asp.SpackSolverSetup()
+        result, _, _ = solver.driver.solve(setup, specs, reuse=[])
+
+        assert result.specs
+        assert not result.unsolved_specs