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>
T-Gro
left a comment
There was a problem hiding this comment.
🤖🕵️ AI review — verify independently.
…t the multi-target tests Brings the fixes pushed to dotnet#20518 and dotnet#20483 onto the integration branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t the multi-target tests Brings the fixes pushed to dotnet#20518 and dotnet#20483 onto the integration branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t the multi-target tests Brings the fixes pushed to dotnet#20518 and dotnet#20483 onto the integration branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t the multi-target tests Brings the fixes pushed to dotnet#20518 and dotnet#20483 onto the integration branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <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>
…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>
…lled 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>
A name recorded under a relative --pathmap already starts with the compile directory, so joining the two repeated it. A relative #line name that a compiler before F# 10 wrote is relative to that directory even when it starts with it. The assembly tells them apart: a name is a compiled file when a module, type or namespace has its range in that file, or a value published through a signature has its implementation there. This replaces the walk from the item to its outermost entity, which missed custom operations, named arguments and members of types declared directly in a namespace. The tests now cover a custom operation, a namespace whose last fragment holds no type, and a value of a signature'd module that sits in a nested module. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Replaying the branch onto main left some files short of the branch's own content; this restores it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2599ec4 to
925ab17
Compare
…t the multi-target tests Brings the fixes pushed to dotnet#20518 and dotnet#20483 onto the integration branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Build Failure AnalysisSummary - All 16 Windows build legs fail while compiling Root cause: .NET Framework-incompatible
|
…, absent on net472 The Desktop legs could not compile FSharp.Compiler.ComponentTests: the .NET Framework BCL has no `String.Contains(string, StringComparison)`, so the arguments were read as a tuple (FS0001 in PathMap.fs). `IndexOf(name, StringComparison.Ordinal) >= 0` exists on every target. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Go To Definition into a project built with a relative
--pathmap(for example.for the repository root) opened generated metadata instead of the source: the declaration's file name repeated the compile directory, as in.\src\Domain\.\src\Domain\Types.fs. A name that is one of the assembly's own compiled files is now used as recorded.Details
#linename that a compiler before F# 10 wrote is relative to the compile directory even when it starts with it, so it is still joined. The assembly tells the two apart: a name is a compiled file when a module, type or namespace has its range in that file, or a value published through a signature has its implementation there.#linedirective that precedes the header of a top-level module, type or namespace, or a#linename that is also the name of a compiled file, is read as a compiled file.🤖 Generated with Claude Code