Repository navigation
Name a declaration from a path-mapped assembly from its root once - #20518
xperiandri wants to merge 16 commits into
Conversation
✅ Release notes checked
|
This comment has been minimized.
This comment has been minimized.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7cf1ff0 to
a4ae807
Compare
T-Gro
left a comment
There was a problem hiding this comment.
🤖🕵️ Please make the description more concise using this guidance. Keep the problem and why the change is needed prominent, using short sentences in simplified technical English. Retain necessary caveats.
This comment has been minimized.
This comment has been minimized.
T-Gro
left a comment
There was a problem hiding this comment.
So shouldn't' this just plain remove .pathMap from tcGlobals and move it over to tcConfig ?
This comment has been minimized.
This comment has been minimized.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4b662de to
78f4c4d
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
A moderate relative-path regression and a duplicate release-note entry remain unresolved.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
Fixes F# declaration paths for path-mapped assemblies and preserves project-specific path maps in cached compiler state.
Changes:
- Corrects mapped source-path resolution.
- Preserves path maps across cached and transparent compilation.
- Adds regression tests and release-note documentation.
| File | Summary |
|---|---|
tests/FSharp.Compiler.ComponentTests/FSharpChecker/PathMap.fs |
Adds path-map regression tests. |
tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj |
Includes the new tests. |
src/Compiler/Symbols/SymbolHelpers.fs |
Adjusts declaration source-path resolution. |
src/Compiler/Service/TransparentCompiler.fs |
Preserves path maps in transparent compilation. |
src/Compiler/Service/IncrementalBuild.fs |
Preserves path maps in cached builds. |
docs/release-notes/.FSharp.Compiler.Service/11.0.100.md |
Documents the fixes; contains a duplicate entry. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
|
🔍 Tooling Safety Check — Affects-Design-Time
|
|
#20518 and #20519 need consistent expectations for the coordinate system of imported filenames: a relative compilation directory does not prove the filename is already root-relative, and a matching suffix does not establish source identity. An older DLL with Could we pin these distinctions with emitted-DLL tests asserting both the compiler’s returned location and the editor’s destination, rather than relying on in-memory references whose IDE options remove the path map? |
|
An older DLL built with Perhaps retain compilation-directory qualification unless the filename is established to be mapped-root-relative, rather than using the directory’s rootedness as proof that qualification is unnecessary. An emitted older-producer DLL regression alongside the ordinary mapped-filename case would ensure that removing duplicated directory segments does not also remove a necessary directory component. |
|
@abonie Both points are addressed in 1e21fcf. Rule. A relative file name is now joined with the compile directory unless it already starts with that directory followed by a separator. A path map writes the files compiled from under the directory with the mapped directory at their start, so only such a name is used as is. Everything else keeps the directory, as on Tests. I replaced the in-memory declaration test with one that compiles the library with Editor. The editor's destination is decided in #20519, which this PR does not touch. For |
1e21fcf to
5586d58
Compare
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Retaining the compilation directory fixes the bare |
5586d58 to
5d40d47
Compare
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…imports are cached FrameworkImportsCache keys the framework imports, and the TcGlobals built with them, by the framework set alone. A project reusing the entry got a fresh TcGlobals only when langVersion or realsig differed, and even then took pathMap from the cached instance. Since TypedTreePickle applies that map to every range it writes, the in-memory reference data of each project carried the --pathmap of whichever project filled the cache first, and a project without a map handed its consumers file names nothing on disk matches. pathMap now takes part in the decision like langVersion and realsig, and the new TcGlobals takes it from the project's own TcConfig, in the incremental builder and the transparent compiler alike. Fixes dotnet#20474 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ing project Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`main` opened 11.0.200 for SDK 11.0.200; 11.0.100 has shipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…imports are cached FrameworkImportsCache keys the framework imports, and the TcGlobals built with them, by the framework set alone. A project reusing the entry got a fresh TcGlobals only when langVersion or realsig differed, and even then took pathMap from the cached instance. Since TypedTreePickle applies that map to every range it writes, the in-memory reference data of each project carried the --pathmap of whichever project filled the cache first, and a project without a map handed its consumers file names nothing on disk matches. pathMap now takes part in the decision like langVersion and realsig, and the new TcGlobals takes it from the project's own TcConfig, in the incremental builder and the transparent compiler alike. Fixes dotnet#20474 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ing project Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A build that maps its source paths - as DeterministicSourcePaths does - maps the directory it compiled in along with the file names of its ranges, so the two reach the same root and neither records what that root is. `fileNameOfItem` joined them anyway, on the assumption that the directory is absolute and the file name relative to it, and the declaration of a symbol imported from such an assembly came back naming the directory twice. Nothing matches a path like that, so Go To Definition reported the symbol as external and opened generated metadata instead of its source. Join only when the directory is rooted. When it is not, the file name already reaches the root on its own and is as complete as the metadata can make it. The IDE drops the path map from the options it builds, so this is reached through an assembly on disk - which is where a path map is normally applied, and which no change to those options can rewrite. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
On Linux and macOS a backslash is part of a file name, so a map to .\ left the declaration's name unresolvable against the root there. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Linking the note added a copy of it instead of editing the first, and `main` has since opened 11.0.200 for SDK 11.0.200, leaving 11.0.100 shipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A relative name in metadata is relative to the directory the assembly was compiled in, as the #line names that compilers before F# 10 wrote are. A path map writes the files compiled from under that directory with the mapped directory at their start, so only such a name is used as is; the directory being relative did not prove a name was mapped. The in-memory test gives way to one that compiles the library out of process from its own directory and references the emitted assembly, with no map, a relative one and the rooted /_/ one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5d40d47 to
2b147da
Compare
…lled the cache Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Takes the test that a project keeps its path map after a sibling without one filled the cache. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test's arguments are joined into one command line. On .NET Framework the default references come from the targeting pack under "Program Files (x86)", so each was split at its spaces and fsc stopped with FS2020. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Compilers before F# 10 recorded what follows a #line directive under the name the directive gives, relative to the compile directory. Under a relative path map such a name can start with the mapped directory exactly as the name of a compiled file does, and was then taken for one. A name is now used as written only if the item also lies in the file its outermost module or type is declared in; a #line directive leaves the two in different files. A module read from a signature file gives no such evidence, since only values record where their implementation is. PathMapFSharp9.dll is real F# 9 output (FSharp.Compiler.Service 43.9.300). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@abonie Fixed in 75bb45b: a name that starts with the mapped compile directory is used as written only when the item lies in the same file as the outermost module or type around it, and a |
T-Gro
left a comment
There was a problem hiding this comment.
The diff is still way too big - apply the NoBloat instructions and CodeCompaction skill.
Especially the massive code comments would benefit not just with drastic reduction, but ideally with well named functions/arguments/bindings/types making the intention clear.
If a well named piece of code just tells what the comment says - delete the comment.
- This diff adds 47 new code comment lines and 3501 new code comment chars.
- Comments bypass the type system and become stale maintenance state. Keep only durable public contracts; express implementation intent through names, functions, active patterns, discriminated unions, and types.

With a path map in
Directory.Build.props, Go To Definition into a sibling project opened generated metadata because the declaration's file name repeated the directory, e.g..\src\Domain\.\src\Domain\Types.fs. The file name and working directory are now joined only when the directory is rooted. Builds without a path map are unaffected.Related: #20470 (IDE options) and #20519 (editor resolution). Stacked on #20476.
🤖 Generated with Claude Code