diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bfdf12f3..bf3423007 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - The fish manual, tutorial and FAQ are now available in `man` format as `fish-doc`, `fish-tutorial` and `fish-faq` respectively (#5521). - Local values for `fish_complete_path` and `fish_function_path` are now ignored; only their global values are respected. - Empty universal variables may now be exported (#5992). +- A bug where local variables would not be exported to functions has been fixed (#6153). - A bug where `string split` would be drop empty strings if the output was only empty strings has been fixed (#5987). - `switch` now allows arguments that expand to nothing, like empty variables (#5677). - The null command (`:`) now always exits successfully, rather than passing through the previous exit status (#6022). diff --git a/src/env.cpp b/src/env.cpp index 8998c4790..8f6b21b06 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -855,7 +855,7 @@ class env_stack_impl_t final : public env_scoped_impl_t { virtual ~env_stack_impl_t() = default; private: - // The scopes of caller functions, which are currently shadowed. + /// The scopes of caller functions, which are currently shadowed. std::vector shadowed_locals_; /// A restricted set of variable flags. @@ -936,12 +936,13 @@ void env_stack_impl_t::push_nonshadowing() { void env_stack_impl_t::push_shadowing() { // Propagate local exported variables. - // TODO: this should take all local exported variables, not just those in the top scope. auto node = std::make_shared(true, nullptr); - for (const auto &var : locals_->env) { - if (var.second.exports()) { - node->env.insert(var); - node->changed_exported(); + for (auto cursor = locals_; cursor; cursor = cursor->next) { + for (const auto &var : cursor->env) { + if (var.second.exports()) { + node->env.insert(var); + node->changed_exported(); + } } } this->shadowed_locals_.push_back(std::move(locals_)); diff --git a/tests/checks/set.fish b/tests/checks/set.fish index 4865ec916..cd692bf17 100644 --- a/tests/checks/set.fish +++ b/tests/checks/set.fish @@ -448,4 +448,18 @@ set -e -U __fish_test_global_vs_universal echo "global-vs-universal 5: $__fish_test_global_vs_universal" # CHECK: global-vs-universal 5: +# Export local variables from all parent scopes (issue #6153). +function func; echo $local; end +set -lx local outer +func +# CHECK: outer +begin + func + # CHECK: outer + + set -lx local inner + begin; func; end + # CHECK: inner +end + true