Canonicalize generated functions for Core witnesses (#7729)

Use a single `SemIR::Function` per `Core` interface method, whether it's
generated locally or imported. This prevents generating duplicate
functions, which lead to different types when the witness appears in a
`FacetValue` as part of a specific for a class.

We use a `CanonicalValueStore` of `GeneratedFunction` objects that allow
finding an existing FunctionId for a `Generated` special function before
(re-)generating it. Mangling for `Generated` functions is also moved to
use the values from the `GeneratedFunction`'s canonicalization key, so
that we have a consistent source of truth for the unique ID of a
`Generated` function across all files.

New tests are in
`toolchain/check/testdata/impl/custom_witness/destroy.carbon`.
This commit is contained in:
Dana Jansens
2026-09-15 16:02:13 +00:00
committed by GitHub
parent db2e26ba86
commit 4416f3525b
278 changed files with 5941 additions and 5506 deletions
@@ -184,12 +184,12 @@ fn Run() {
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
// CHECK:STDOUT: define weak_odr void @"_C__destroy_thunk:thunk.A.Main"(ptr %self) #5 !dbg !28 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: call void @"_COp.e649d414b9e7644a:core.Destroy.Core"(ptr %self), !dbg !30
// CHECK:STDOUT: call void @"_COp.5a23cc09585c55d2:core.Destroy.Core"(ptr %self), !dbg !30
// CHECK:STDOUT: ret void, !dbg !30
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define weak_odr void @"_COp.e649d414b9e7644a:core.Destroy.Core"(ptr %self) #4 !dbg !32 {
// CHECK:STDOUT: define weak_odr void @"_COp.5a23cc09585c55d2:core.Destroy.Core"(ptr %self) #4 !dbg !32 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret void, !dbg !34
// CHECK:STDOUT: }
@@ -197,12 +197,12 @@ fn Run() {
// CHECK:STDOUT: ; Function Attrs: alwaysinline nounwind
// CHECK:STDOUT: define weak_odr void @"_C__destroy_thunk:thunk.B.Main"(ptr %self) #5 !dbg !36 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: call void @"_COp.535580a8a7a96b3b:core.Destroy.Core"(ptr %self), !dbg !38
// CHECK:STDOUT: call void @"_COp.8c4b83ecd900f1ea:core.Destroy.Core"(ptr %self), !dbg !38
// CHECK:STDOUT: ret void, !dbg !38
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define weak_odr void @"_COp.535580a8a7a96b3b:core.Destroy.Core"(ptr %self) #4 !dbg !40 {
// CHECK:STDOUT: define weak_odr void @"_COp.8c4b83ecd900f1ea:core.Destroy.Core"(ptr %self) #4 !dbg !40 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret void, !dbg !42
// CHECK:STDOUT: }
@@ -281,7 +281,7 @@ fn Run() {
// CHECK:STDOUT: !29 = !DILocalVariable(arg: 1, scope: !28, type: !10)
// CHECK:STDOUT: !30 = !DILocation(line: 8, column: 1, scope: !28)
// CHECK:STDOUT: !31 = !{!29}
// CHECK:STDOUT: !32 = distinct !DISubprogram(name: "Op", linkageName: "_COp.e649d414b9e7644a:core.Destroy.Core", scope: null, file: !8, line: 8, type: !12, spFlags: DISPFlagDefinition, unit: !9, retainedNodes: !35)
// CHECK:STDOUT: !32 = distinct !DISubprogram(name: "Op", linkageName: "_COp.5a23cc09585c55d2:core.Destroy.Core", scope: null, file: !8, line: 8, type: !12, spFlags: DISPFlagDefinition, unit: !9, retainedNodes: !35)
// CHECK:STDOUT: !33 = !DILocalVariable(arg: 1, scope: !32, type: !10)
// CHECK:STDOUT: !34 = !DILocation(line: 8, column: 1, scope: !32)
// CHECK:STDOUT: !35 = !{!33}
@@ -289,7 +289,7 @@ fn Run() {
// CHECK:STDOUT: !37 = !DILocalVariable(arg: 1, scope: !36, type: !10)
// CHECK:STDOUT: !38 = !DILocation(line: 13, column: 1, scope: !36)
// CHECK:STDOUT: !39 = !{!37}
// CHECK:STDOUT: !40 = distinct !DISubprogram(name: "Op", linkageName: "_COp.535580a8a7a96b3b:core.Destroy.Core", scope: null, file: !8, line: 13, type: !12, spFlags: DISPFlagDefinition, unit: !9, retainedNodes: !43)
// CHECK:STDOUT: !40 = distinct !DISubprogram(name: "Op", linkageName: "_COp.8c4b83ecd900f1ea:core.Destroy.Core", scope: null, file: !8, line: 13, type: !12, spFlags: DISPFlagDefinition, unit: !9, retainedNodes: !43)
// CHECK:STDOUT: !41 = !DILocalVariable(arg: 1, scope: !40, type: !10)
// CHECK:STDOUT: !42 = !DILocation(line: 13, column: 1, scope: !40)
// CHECK:STDOUT: !43 = !{!41}