@@ -108,23 +108,38 @@ Goal::Co DerivationBuildingGoal::gaveUpOnSubstitution(bool storeDerivation)
108108
109109 Note that some inputs might not be in the eval store because they
110110 are (resolved) derivation outputs in a resolved derivation. */
111+
112+ std::set<const SingleDerivedPath::Built *> builtInputs;
113+
114+ StorePathSet inputSrcs;
115+
116+ for (auto & input : drv->inputs )
117+ std::visit (overloaded{
118+ [&](const SingleDerivedPath::Opaque & op) {
119+ inputSrcs.insert (op.path );
120+ },
121+ [&](const SingleDerivedPath::Built & built) {
122+ builtInputs.insert (&built);
123+ },
124+ }, input.raw ());
125+
111126 if (&worker.evalStore != &worker.store ) {
112- RealisedPath::Set inputSrcs ;
113- for (auto & i : drv-> inputs . srcs )
114- if (worker.evalStore .isValidPath (i ))
115- inputSrcs .insert (i );
116- copyClosure (worker.evalStore , worker.store , inputSrcs );
127+ StorePathSet evalStorePaths ;
128+ for (auto & path : inputSrcs )
129+ if (worker.evalStore .isValidPath (path ))
130+ evalStorePaths .insert (path );
131+ copyClosure (worker.evalStore , worker.store , evalStorePaths );
117132 }
118133
119- for (auto & i : drv-> inputs . srcs ) {
120- if (worker.store .isValidPath (i ))
134+ for (auto & path : inputSrcs ) {
135+ if (worker.store .isValidPath (path ))
121136 continue ;
122137 if (!settings.useSubstitutes )
123138 throw Error (
124139 " dependency '%s' of '%s' does not exist, and substitution is disabled" ,
125- worker.store .printStorePath (i ),
140+ worker.store .printStorePath (path ),
126141 worker.store .printStorePath (drvPath));
127- waitees.insert (upcast_goal (worker.makePathSubstitutionGoal (i )));
142+ waitees.insert (upcast_goal (worker.makePathSubstitutionGoal (path )));
128143 }
129144
130145 co_await await (std::move (waitees));
@@ -148,45 +163,47 @@ Goal::Co DerivationBuildingGoal::gaveUpOnSubstitution(bool storeDerivation)
148163 /* Determine the full set of input paths. */
149164
150165 if (storeDerivation) {
151- assert (drv->inputs .drvs .map .empty ());
166+ /* For resolved derivations, there should be no Built inputs */
167+ assert (std::ranges::none_of (drv->inputs , [](const auto & input) {
168+ return std::holds_alternative<SingleDerivedPath::Built>(input.raw ());
169+ }));
152170 /* Store the resolved derivation, as part of the record of
153171 what we're actually building */
154172 writeDerivation (worker.store , *drv);
155173 }
156174
157- {
158- /* If we get this far, we know no dynamic drvs inputs */
159-
160- for (auto & [depDrvPath, depNode] : drv->inputs .drvs .map ) {
161- for (auto & outputName : depNode.value ) {
162- /* Don't need to worry about `inputGoals`, because
163- impure derivations are always resolved above. Can
164- just use DB. This case only happens in the (older)
165- input addressed and fixed output derivation cases. */
166- auto outMap = [&] {
167- for (auto * drvStore : {&worker.evalStore , &worker.store })
168- if (drvStore->isValidPath (depDrvPath))
169- return worker.store .queryDerivationOutputMap (depDrvPath, drvStore);
170- assert (false );
171- }();
172-
173- auto outMapPath = outMap.find (outputName);
174- if (outMapPath == outMap.end ()) {
175- throw Error (
176- " derivation '%s' requires non-existent output '%s' from input derivation '%s'" ,
177- worker.store .printStorePath (drvPath),
178- outputName,
179- worker.store .printStorePath (depDrvPath));
180- }
175+ /* Process source inputs */
176+ worker.store .computeFSClosure (inputSrcs, inputPaths);
177+
178+ /* Process derivation inputs */
179+ for (auto * built : builtInputs) {
180+ /* Only handle simple (non-dynamic) derivation inputs */
181+ if (auto * opaque = std::get_if<SingleDerivedPath::Opaque>(&built->drvPath ->raw ())) {
182+ auto & depDrvPath = opaque->path ;
183+ /* Don't need to worry about `inputGoals`, because
184+ impure derivations are always resolved above. Can
185+ just use DB. This case only happens in the (older)
186+ input addressed and fixed output derivation cases. */
187+ auto outMap = [&] {
188+ for (auto * drvStore : {&worker.evalStore , &worker.store })
189+ if (drvStore->isValidPath (depDrvPath))
190+ return worker.store .queryDerivationOutputMap (depDrvPath, drvStore);
191+ assert (false );
192+ }();
181193
182- worker.store .computeFSClosure (outMapPath->second , inputPaths);
194+ auto outMapPath = outMap.find (built->output );
195+ if (outMapPath == outMap.end ()) {
196+ throw Error (
197+ " derivation '%s' requires non-existent output '%s' from input derivation '%s'" ,
198+ worker.store .printStorePath (drvPath),
199+ built->output ,
200+ worker.store .printStorePath (depDrvPath));
183201 }
202+
203+ worker.store .computeFSClosure (outMapPath->second , inputPaths);
184204 }
185205 }
186206
187- /* Second, the input sources. */
188- worker.store .computeFSClosure (drv->inputs .srcs , inputPaths);
189-
190207 debug (" added input paths %s" , worker.store .showPaths (inputPaths));
191208
192209 /* Okay, try to build. Note that here we don't wait for a build
0 commit comments