@@ -303,6 +303,7 @@ EvalState::EvalState(
303303 , srcToStore(make_ref<decltype (srcToStore)::element_type>())
304304 , importResolutionCache(make_ref<decltype (importResolutionCache)::element_type>())
305305 , fileEvalCache(make_ref<decltype (fileEvalCache)::element_type>())
306+ , positionToDocComment(make_ref<decltype (positionToDocComment)::element_type>())
306307 , regexCache(makeRegexCache())
307308#if NIX_USE_BOEHMGC
308309 , baseEnvP(std::allocate_shared<Env *>(traceable_allocator<Env *>(), &mem.allocEnv(BASE_ENV_SIZE)))
@@ -3345,19 +3346,21 @@ Expr * EvalState::parse(
33453346 const SourcePath & basePath,
33463347 const std::shared_ptr<StaticEnv> & staticEnv)
33473348{
3348- DocCommentMap tmpDocComments; // Only used when not origin is not a SourcePath
3349- DocCommentMap * docComments = &tmpDocComments;
3349+ auto tmpDocComments = make_ref<DocCommentMap>();
33503350
3351- if (auto sourcePath = std::get_if<SourcePath>(&origin)) {
3352- auto [it, _] = positionToDocComment.try_emplace (*sourcePath);
3353- docComments = &it->second ;
3354- }
3355-
3356- auto result =
3357- parseExprFromBuf (text, length, origin, basePath, mem.exprs , symbols, settings, positions, *docComments, rootFS);
3351+ auto result = parseExprFromBuf (
3352+ text, length, origin, basePath, mem.exprs , symbols, settings, positions, *tmpDocComments, rootFS);
33583353
33593354 result->bindVars (*this , staticEnv);
33603355
3356+ if (auto sourcePath = std::get_if<SourcePath>(&origin))
3357+ /* A single file might appear multiple times in PosTable if it's
3358+ parsed by scopedImport. If we are the first then emplace into the map, otherwise
3359+ copy our positions into the existing map. */
3360+ positionToDocComment->emplace_or_visit (*sourcePath, tmpDocComments, [&tmpDocComments](auto & kv) {
3361+ kv.second ->insert (tmpDocComments->begin (), tmpDocComments->end ());
3362+ });
3363+
33613364 return result;
33623365}
33633366
@@ -3368,20 +3371,22 @@ ExprAttrs * EvalState::parseReplBindings(
33683371 const SourcePath & basePath,
33693372 const std::shared_ptr<StaticEnv> & staticEnv)
33703373{
3371- DocCommentMap tmpDocComments;
3372- DocCommentMap * docComments = &tmpDocComments;
3373-
3374- if (auto sourcePath = std::get_if<SourcePath>(&origin)) {
3375- auto [it, _] = positionToDocComment.try_emplace (*sourcePath);
3376- docComments = &it->second ;
3377- }
3374+ auto tmpDocComments = make_ref<DocCommentMap>();
33783375
33793376 auto bindings = parseReplBindingsFromBuf (
3380- text, length, origin, basePath, mem.exprs , symbols, settings, positions, *docComments , rootFS);
3377+ text, length, origin, basePath, mem.exprs , symbols, settings, positions, *tmpDocComments , rootFS);
33813378 assert (bindings);
33823379
33833380 bindings->bindVars (*this , staticEnv);
33843381
3382+ if (auto sourcePath = std::get_if<SourcePath>(&origin))
3383+ /* A single file might appear multiple times in PosTable if it's
3384+ parsed by scopedImport. If we are the first then emplace into the map, otherwise
3385+ copy our positions into the existing map. */
3386+ positionToDocComment->emplace_or_visit (*sourcePath, tmpDocComments, [&tmpDocComments](auto & kv) {
3387+ kv.second ->insert (tmpDocComments->begin (), tmpDocComments->end ());
3388+ });
3389+
33853390 return bindings;
33863391}
33873392
@@ -3392,14 +3397,12 @@ DocComment EvalState::getDocCommentForPos(PosIdx pos)
33923397 if (!path)
33933398 return {};
33943399
3395- auto table = positionToDocComment.find (*path);
3396- if (table == positionToDocComment.end ())
3397- return {};
3398-
3399- auto it = table->second .find (pos);
3400- if (it == table->second .end ())
3401- return {};
3402- return it->second ;
3400+ DocComment result;
3401+ positionToDocComment->visit (*path, [&](const auto & kv) {
3402+ if (auto it = kv.second ->find (pos); it != kv.second ->end ())
3403+ result = it->second ;
3404+ });
3405+ return result;
34033406}
34043407
34053408std::string ExternalValueBase::coerceToString (
0 commit comments