Skip to content

[JuliaLowering] Fix @nospecialize multi-arg and add 0-arg#61021

Merged
topolarity merged 4 commits intomasterfrom
avi/JuliaLowering-nospecialize
Feb 18, 2026
Merged

[JuliaLowering] Fix @nospecialize multi-arg and add 0-arg#61021
topolarity merged 4 commits intomasterfrom
avi/JuliaLowering-nospecialize

Conversation

@aviatesk
Copy link
Copy Markdown
Member

Split the single @nospecialize(ctx, ex, exs...) method into properly typed variants:

  • 0-arg: emits [K"meta" "nospecialize"] for blanket usage
  • 1-arg: applies _apply_nospecialize to the argument
  • 2+-arg: applies _apply_nospecialize to all arguments

The previous implementation only processed the first argument when multiple were given (the rest were silently ignored).

@aviatesk aviatesk requested a review from c42f February 13, 2026 15:25
Comment thread JuliaLowering/src/syntax_macros.jl Outdated
@topolarity
Copy link
Copy Markdown
Member

This should also include tests for the added support, but otherwise LGTM

@topolarity topolarity added the needs tests Unit tests are required for this change label Feb 13, 2026
@aviatesk aviatesk force-pushed the avi/JuliaLowering-nospecialize branch from cdcec6b to 6562322 Compare February 14, 2026 13:46
Comment thread JuliaLowering/src/scope_analysis.jl
@aviatesk aviatesk removed the needs tests Unit tests are required for this change label Feb 15, 2026
# @nospecialize with default value in signature
@test JuliaLowering.include_string(test_mod, """
begin
function f_nospecialize_default(x, @nospecialize(y=1))
Copy link
Copy Markdown
Member

@topolarity topolarity Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to add a broken test for the body form (which doesn't work, as noted in

# TODO: Ensure we preserve @nospecialize metadata in args
).

A kwargs example would also be good (and is similarly broken for the body form). Sorry to make you add so many tests, but it seems prudent when we run into loose ends like this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added. Regarding keyword argument methods, it hasn't been decided yet how @nospecialize should be propagated, so it might be better to decide that before writing tests.
Even if we add @nospecialize to the keyword methods themselves, we might not get the desired effect unless we also @nospecialize the NamedTuple argument that kwcall receives.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, the bug applies to the positional arguments as well, which don't propagate through the helper method either.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I added a new broken test case for that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean this case:

function f_body_nospecialize_default(x; y=1)
    @nospecialize x
    (x, y)
end
(f_body_nospecialize_default(10; y = 20), f_body_nospecialize_default(30))

flisp labels x as nospecialize in both the "body" and "wrapper" functions.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, added that case too. Let me elaborate my thinking on this part a bit

Regarding keyword argument methods, it hasn't been decided yet how @nospecialize should be propagated, so it might be better to decide that before writing tests.

So in order to correctly nospecialize the keyword arguments, I believe we need to add nospecialize for the NamedTuple argument of the keyword sorter method as well as their corresponding arguments of the keyword body method, but we currently don't implement this. The keyword body method nospecialization would just be fine, but adding @nospecialize for the NamedTuple means we won't specialize the entire keyword arguments set of the keyword sorter method, so some caution might be needed.

Copy link
Copy Markdown
Member

@topolarity topolarity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll probably have to re-work the fix for body @nospecialize soon, given the need to propagate it to derived positional / kwargs methods. @mlechu can you add this to your list of proper fixes needed?

Otherwise changes LGTM w/ a couple additional tests - definitely an improvement. Thanks @aviatesk

@aviatesk aviatesk force-pushed the avi/JuliaLowering-nospecialize branch 2 times, most recently from 42290e1 to 51cb4e2 Compare February 17, 2026 12:10
aviatesk and others added 3 commits February 18, 2026 08:41
Split the single `@nospecialize(ctx, ex, exs...)` method into
properly typed variants:
- 0-arg: emits `[K"meta" "nospecialize"]` for blanket usage
- 1-arg: applies `_apply_nospecialize` to the argument
- 2+-arg: applies `_apply_nospecialize` to all arguments

The previous implementation only processed the first argument
when multiple were given (the rest were silently ignored).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Cody Tapscott <84105208+topolarity@users.noreply.github.com>
Fix body-level `@nospecialize x z` not setting the nospecialize bits
on `Method.nospecialize`. The macro sets `:nospecialize` metadata on
identifiers, but this was not propagated to the binding during scope
analysis. Now `_resolve_scopes` checks for this metadata on argument
references and sets `is_nospecialize` on the binding.

Add tests for missing `@nospecialize` forms:
- Body-level multi-arg (`@nospecialize a c d`)
- Body-level single-arg (`@nospecialize b`)
- Body-level zero-arg (blanket `@nospecialize`)
- Signature-level with default value (`@nospecialize(y=1)`)
- IR-level tests for body-level single and multi-arg

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@aviatesk aviatesk force-pushed the avi/JuliaLowering-nospecialize branch from 51cb4e2 to b625cb0 Compare February 18, 2026 00:38
@aviatesk aviatesk added the merge me PR is reviewed. Merge when all tests are passing label Feb 18, 2026
Comment thread JuliaLowering/test/functions.jl Outdated
Co-authored-by: Cody Tapscott <84105208+topolarity@users.noreply.github.com>
@topolarity topolarity merged commit 4d8e18a into master Feb 18, 2026
6 of 8 checks passed
@topolarity topolarity deleted the avi/JuliaLowering-nospecialize branch February 18, 2026 21:21
@topolarity topolarity removed the merge me PR is reviewed. Merge when all tests are passing label Feb 18, 2026
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.

2 participants