Skip to content

fix(parser): namespace pollution of constants by use module.nu#15518

Merged
fdncred merged 2 commits intonushell:mainfrom
blindFS:use_const
May 1, 2025
Merged

fix(parser): namespace pollution of constants by use module.nu#15518
fdncred merged 2 commits intonushell:mainfrom
blindFS:use_const

Conversation

@blindFS
Copy link
Copy Markdown
Contributor

@blindFS blindFS commented Apr 7, 2025

A bug introduced by #14920

When use module.nu is called, all exported constants defined in it are added to the scope.

Description

On the branch of empty arguments, the constant var_id vector should be empty, only constant_values (for $module.foo access) are injected.

User-Facing Changes

Tests + Formatting

todo!

adjusted

After Submitting

@blindFS
Copy link
Copy Markdown
Contributor Author

blindFS commented Apr 7, 2025

@NotTheDr01ds Please review this with care.

@sholderbach
Copy link
Copy Markdown
Member

Thanks, can you add a test that the scope is only filled by those marked as export?

@blindFS
Copy link
Copy Markdown
Contributor Author

blindFS commented Apr 7, 2025

Thanks, can you add a test that the scope is only filled by those marked as export?

Sure, just figured out where to make that happen.

Oh, I should be more clear. The bug is that even exported constants shouldn't be available by calling use module.nu, but only accessible by $module.foo according to the nushell book. use module.nu * however behaves as what you'd expect.

@blindFS blindFS marked this pull request as ready for review April 7, 2025 13:24
@NotTheDr01ds NotTheDr01ds requested a review from kubouch April 7, 2025 18:07
@blindFS
Copy link
Copy Markdown
Contributor Author

blindFS commented Apr 8, 2025

Another interesting issue:

  1. create a foo.nu file with the following content
export module "mod name" {
  export const var_name = "const value"
}
  1. use foo.nu 'mod name'
  2. invalid variable name in the scope:
name type
$mod name record<var_name: string>

@kubouch
Copy link
Copy Markdown
Contributor

kubouch commented Apr 9, 2025

Looks good. Does that issue appear also without #14920 applied? I.e., is it related to your changes, or is it just a bug in the const/module implementation?

@blindFS
Copy link
Copy Markdown
Contributor Author

blindFS commented Apr 9, 2025

Looks good. Does that issue appear also without #14920 applied? I.e., is it related to your changes, or is it just a bug in the const/module implementation?

Not related to #14920 , already the case in ver. 101 which is before that PR.

image

@blindFS
Copy link
Copy Markdown
Contributor Author

blindFS commented Apr 9, 2025

Basically space is not allowed in variable identifiers, but allowed in module names. So the problem arises when trying to reference a module as a variable.

TBH, I'm not a fan of such semantics, making lsp tasks more difficult, and the memory management is not well optimized.

@kubouch
Copy link
Copy Markdown
Contributor

kubouch commented Apr 9, 2025

The space comes from space being used as a submodule separator. We were thinking changing it to the more traditional :: which would eliminate the problem.

@sgvictorino
Copy link
Copy Markdown
Contributor

Can we make is_identifier_byte more strict? We could split on :: in normalize_module_name and parse_variable_expr to make $mod::name work.

@blindFS
Copy link
Copy Markdown
Contributor Author

blindFS commented Apr 14, 2025

Can we make is_identifier_byte more strict? We could split on :: in normalize_module_name and parse_variable_expr to make $mod::name work.

By $mod::name, do you mean the variable which is a record representing all the nested constants, or a single constant named name defined in a module named mod?

I thought if we choose to go for the :: syntax. We no longer need module record variables?

@sgvictorino
Copy link
Copy Markdown
Contributor

sgvictorino commented Apr 14, 2025

By $mod::name, do you mean the variable which is a record representing all the nested constants, or a single constant named name defined in a module named mod?

I mean the module record variable.

I thought if we choose to go for the :: syntax. We no longer need module record variables?

Sorry if I'm missing something obvious, but why not?

@blindFS
Copy link
Copy Markdown
Contributor Author

blindFS commented Apr 14, 2025

Sorry if I'm missing something obvious, but why not?

Could be my misunderstanding. I thought foo::bar would be a new type of expression especially designed for referring contents inside modules.

Currently if we execute use module.nu, all its exported commands would be available with a prefix module, while its exported constants stored in the module record, which are quite inconsistent semantics. With :: syntax however, use module.nu does nothing more than adding the module to the scope. And we can access all its contents with something like "mod name"::"command name", $"mod name"::"constant name".

@kubouch
Copy link
Copy Markdown
Contributor

kubouch commented Apr 15, 2025

The :: change is a substantial language change that still needs some design that's better done elsewhere, but yeah, I think it would allow us to move away from the module records.

@fdncred
Copy link
Copy Markdown
Contributor

fdncred commented May 1, 2025

Seems like the discussion has gone a little bit off topic but as it relates to this PR, I think we're ready to land this. Thanks!

@fdncred fdncred merged commit a7547a5 into nushell:main May 1, 2025
15 checks passed
@github-actions github-actions bot added this to the v0.105.0 milestone May 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants