Export all local exported variables in a new scope

Fixes #6153
This commit is contained in:
Johannes Altmanninger 2019-10-03 12:26:51 +02:00 committed by ridiculousfish
parent afb8f42f39
commit 9b86d5dd16
3 changed files with 22 additions and 6 deletions

View file

@ -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). - 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. - 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). - 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). - 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). - `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). - The null command (`:`) now always exits successfully, rather than passing through the previous exit status (#6022).

View file

@ -855,7 +855,7 @@ class env_stack_impl_t final : public env_scoped_impl_t {
virtual ~env_stack_impl_t() = default; virtual ~env_stack_impl_t() = default;
private: private:
// The scopes of caller functions, which are currently shadowed. /// The scopes of caller functions, which are currently shadowed.
std::vector<env_node_ref_t> shadowed_locals_; std::vector<env_node_ref_t> shadowed_locals_;
/// A restricted set of variable flags. /// A restricted set of variable flags.
@ -936,14 +936,15 @@ void env_stack_impl_t::push_nonshadowing() {
void env_stack_impl_t::push_shadowing() { void env_stack_impl_t::push_shadowing() {
// Propagate local exported variables. // Propagate local exported variables.
// TODO: this should take all local exported variables, not just those in the top scope.
auto node = std::make_shared<env_node_t>(true, nullptr); auto node = std::make_shared<env_node_t>(true, nullptr);
for (const auto &var : locals_->env) { for (auto cursor = locals_; cursor; cursor = cursor->next) {
for (const auto &var : cursor->env) {
if (var.second.exports()) { if (var.second.exports()) {
node->env.insert(var); node->env.insert(var);
node->changed_exported(); node->changed_exported();
} }
} }
}
this->shadowed_locals_.push_back(std::move(locals_)); this->shadowed_locals_.push_back(std::move(locals_));
this->locals_ = std::move(node); this->locals_ = std::move(node);
} }

View file

@ -448,4 +448,18 @@ set -e -U __fish_test_global_vs_universal
echo "global-vs-universal 5: $__fish_test_global_vs_universal" echo "global-vs-universal 5: $__fish_test_global_vs_universal"
# CHECK: global-vs-universal 5: # 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 true