Skip to content

Document the explicit FunctionWrappersWrapper{FW, P, CS}(fw, cs) constructor - #79

Merged
ChrisRackauckas merged 3 commits into
SciML:mainfrom
ChrisRackauckas-Claude:agent/document-typed-constructor
Jul 29, 2026
Merged

Document the explicit FunctionWrappersWrapper{FW, P, CS}(fw, cs) constructor#79
ChrisRackauckas merged 3 commits into
SciML:mainfrom
ChrisRackauckas-Claude:agent/document-typed-constructor

Conversation

@ChrisRackauckas-Claude

@ChrisRackauckas-Claude ChrisRackauckas-Claude commented Jul 28, 2026

Copy link
Copy Markdown
Member

Ignore this PR until it has been reviewed by @ChrisRackauckas.

Summary

FunctionWrappersWrapper is exported, so its two-argument inner constructor was already reachable as public API — but it was the only constructor of the type carrying no docstring. The other three all have one.

That matters because it is the constructor downstream solver stacks actually call. NonlinearSolveBase's AutoDePSpecialize / norecompile path builds its wrapper tuple itself and then constructs with all three type parameters supplied directly:

cs = FunctionWrappersWrappers.SingleCacheStorage()
FunctionWrappersWrappers.FunctionWrappersWrapper{
    typeof(fwt), FunctionWrappersWrappers.AllowNonIsBits, typeof(cs),
}(fwt, cs)

It uses this form rather than FunctionWrappersWrapper(fwt; cache, policy) because giving FW, P and CS as type parameters makes the wrapper type inferrable without depending on constant propagation through a keyword-argument frame — and the wrapper type, plus every cache built from the wrapped problem, has to stay concrete. The docstring now records that, and records the caller's obligation to keep cs consistent with the cache mode P's fallback path expects.

Note on mechanics: a docstring written inside the struct body does not attach to the type's binding — I verified it does not show up in the binding's MultiDoc, so Documenter would never render it. It has to be attached with @doc on the method signature after the struct.

Docs-only; no behavior change. Patch bump to 1.11.1 — the name was already public and exported, this only documents an existing method.

Validation

Docstring is attached to the right method, alongside the four pre-existing ones:

$ julia --project -e '...Base.Docs.meta(FunctionWrappersWrappers)[b].docs...'
docstring count: 5
  sig=…Tuple{FW, CS}} where {FW, P, CS}  -> FunctionWrappersWrapper{FW, P, CS}(fw, cs) -> FunctionWrappersWrapper{FW, P, CS}
  sig=…Tuple{F, NTuple{K, Any}, NTuple{K, Type}}} where {F, K}  -> FunctionWrappersWrapper(f, argtypes, rettypes; …
  sig=…Tuple{Any}…  -> FunctionWrappersWrapper{FW, P, CS}(f) -> …
  sig=Union{}  -> FunctionWrappersWrapper{FW, P, CS}
  sig=Tuple{Tuple{Vararg{FunctionWrappers.FunctionWrapper}}}  -> FunctionWrappersWrapper(fw::…; cache=…, policy=…)

The new jldoctest was run directly and returns 3.0 as written.

Full test suite passes:

$ julia --project -e 'using Pkg; Pkg.test()'
     Testing FunctionWrappersWrappers tests passed

Runic 1.7.0 --check exits 0.

CI

The QA group was failing here for a reason unrelated to this change: #76 dropped the ExplicitImports ignore list, and main has been red since. This PR is stacked on #80, which fixes that. Merge #80 first.

$ GROUP=QA julia --project=. -e 'using Pkg; Pkg.test()'   # this branch, on top of #80
QA            |   20     20  29.3s
     Testing FunctionWrappersWrappers tests passed

Correction to the validation note above: my earlier Pkg.test() run exercised only the curated default group, which does not include QA, so it did not catch that failure.

Rebased after #80 grew a second commit removing the dead TruncatedStacktraces dependency — the @doc block now sits directly after the struct rather than after the TruncatedStacktraces.@truncate_stacktrace line, which no longer exists. Re-verified the docstring still attaches to the right method: the binding carries 5 docstrings, the new one keyed on Tuple{FW, CS}.

Links

SciML#76 replaced the whole `run_qa(...)` call with a bare
`run_qa(FunctionWrappersWrappers)`, which silently discarded the
`all_qualified_accesses_are_public` ignore list it carried. The QA group has
errored on `main` ever since with `NonPublicQualifiedAccessException` for
`FunctionWrappers.FunctionWrapper` and
`TruncatedStacktraces.@truncate_stacktrace`.

This is invisible to `Pkg.test()`, which runs the curated default group; QA is
not part of it.

`:tail` is not restored: `Base.tail` is no longer reached, and ExplicitImports
does not flag it.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
`@truncate_stacktrace` cannot fire in this package. TruncatedStacktraces sets
`DISABLE = @load_preference("disable", true) || VERSION >= v"1.10"`, and the
macro body is wrapped in `@static if !DISABLE`, so on Julia 1.10 and later it
expands to nothing — and 1.10 is this package's floor. The `Base.show` method it
is supposed to define has never existed on any Julia version we support, and the
preference cannot override the version clause.

Verified: `FunctionWrappersWrapper` contributes zero `Base.show` methods, and
its type prints in full with no truncation.

That makes the dependency dead weight, and it was the only reason the QA suite
needed a `@truncate_stacktrace` ignore. Removing it is better than either
ignoring the access or promoting the name upstream — the latter is impossible
in any case, since SciML/TruncatedStacktraces.jl is archived and read-only.

Only the `FunctionWrapper` ignore remains, and that one has a path out now:
JuliaLang/FunctionWrappers.jl#35.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
…tructor

`FunctionWrappersWrapper` is exported, so its inner constructor was already
reachable as public API, but it carried no docstring — the only constructor of
the type that did not. Downstream solver stacks construct through exactly this
method, because supplying `FW`, `P` and `CS` directly keeps the wrapper type
inferrable without relying on constant propagation through a keyword-argument
frame, which the `argtypes`/`rettypes` and tuple constructors do.

The docstring is attached with `@doc` on the method signature after the struct;
a docstring written inside the struct body does not attach to the type's
binding, so Documenter would never render it.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude
ChrisRackauckas-Claude force-pushed the agent/document-typed-constructor branch from d354a67 to 22e07c2 Compare July 29, 2026 01:34
@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review July 29, 2026 02:31
@ChrisRackauckas
ChrisRackauckas merged commit d896d40 into SciML:main Jul 29, 2026
16 checks passed
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