Add tests for generic terse function declarations. (#8051)

We have test coverage for both features in isolation, but it seems
worthwhile having coverage for the combination of the two.
This commit is contained in:
Richard Smith authored and GitHub committed 2026-10-28 15:33:40 +00:00
1 parent 0421bf3b43
commit 6d51427790
4 files changed
+227 -153

No files matched your search

+42 -9
View File
@@ -48,13 +48,33 @@ fn TestMethods(c: WithMethods) {
let unused b: i32 = WithMethods.Static();
}
// --- generic_non_dependent.carbon
// --- generic.carbon
library "[[@TEST_NAME]]";
fn GenericNonDependent[T: type](unused x: T) => 42 as i32;
fn GenericId[T: Core.Copy](x: T) => x;
fn GenericPair[T: Core.Copy, U: Core.Copy](x: T, y: U) => (x, y);
fn GenericCaller[T: Core.Copy](x: T) => GenericId(x);
fn TemplateDeref[template T: type](p: T*) => *p;
eval fn EvalGenericId[T: Core.Copy](x: T) => x;
fn TestGenericNonDependent() {
let unused a: i32 = GenericNonDependent(true);
class GenericBox(T: Core.Copy) {
fn Get(self: Self) => self.x;
fn Make(x: T) => {.x = x} as Self;
var x: T;
}
fn TestGeneric() {
let a: i32 = GenericNonDependent(true);
let b: i32 = GenericId(a);
let c: bool = GenericCaller(true);
let p: (i32, bool) = GenericPair(b, c);
var v: i32 = p.0;
let unused d: i32 = TemplateDeref(&v);
var arr: array(i32, EvalGenericId(3));
let _: array(i32, 3) = arr;
let box: GenericBox(i32) = GenericBox(i32).Make(7);
let unused e: i32 = box.Get();
}
// --- main_run_i32.carbon
@@ -111,11 +131,29 @@ library "[[@TEST_NAME]]";
class Incomplete;
// TODO: This test produces too many error messages for the same problem.
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE+3]]:39-40: error: function returns incomplete type `Incomplete` [IncompleteTypeInFunctionReturnType]
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-3]]:1-17: note: class was forward declared here [ClassForwardDeclaredHere]
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-5]]:1-17: note: class was forward declared here [ClassForwardDeclaredHere]
// CHECK:STDERR:
fn DerefIncomplete(p: Incomplete*) => *p;
fn GenericDerefIncomplete[template T: type](p: T*) => *p;
fn CallGenericDerefIncomplete(p: Incomplete*) {
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE+11]]:3-27: error: unable to monomorphize specific `GenericDerefIncomplete(Incomplete)` [ResolvingSpecificHere]
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-3]]:55-56: note: `T` evaluates to incomplete type `Incomplete` [IncompleteTypeInMonomorphization]
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-13]]:1-17: note: class was forward declared here [ClassForwardDeclaredHere]
// CHECK:STDERR:
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE+7]]:3-27: error: unable to monomorphize specific `GenericDerefIncomplete(Incomplete)` [ResolvingSpecificHere]
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-7]]:55-56: note: cannot access member of interface `Core.Copy` in type `Incomplete` that does not implement that interface [MissingImplInMemberAccess]
// CHECK:STDERR:
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE+4]]:3-27: error: function returns incomplete type `Incomplete` [IncompleteTypeInFunctionReturnType]
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-19]]:1-17: note: class was forward declared here [ClassForwardDeclaredHere]
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-11]]:55-56: note: return type declared here [IncompleteReturnTypeHere]
// CHECK:STDERR:
GenericDerefIncomplete(p);
}
// --- fail_unused.carbon
library "[[@TEST_NAME]]";
@@ -126,11 +164,6 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR:
fn UnusedTest(x: i32, unused y: i32) => y;
// --- dependent_return.carbon
library "[[@TEST_NAME]]";
fn GenericId[T: Core.Copy](x: T) => x;
// --- fail_call_before_deduced.carbon
library "[[@TEST_NAME]]";
+7 -7
View File
@@ -155,6 +155,13 @@ alias terse_id_fn = fn (x: i32) => x;
fn TestAsGenericArgument() {
PassToGeneric(id_fn);
PassToGeneric(terse_id_fn);
alias generic_terse_id = fn [T: Core.Copy](x: T) => x;
let g1: i32 = generic_terse_id(42 as i32);
let g2: bool = generic_terse_id(true);
alias generic_terse_pair = fn [T: Core.Copy, U: Core.Copy](x: T, y: U) => (x, y);
let unused gp: (i32, bool) = generic_terse_pair(g1, g2);
let unused g3: i32 = (fn [T: Core.Copy](x: T) => x)(10 as i32);
}
// --- as_template_argument.carbon
@@ -338,13 +345,6 @@ fn F() {
(fn => 0);
}
// --- dependent_terse_return.carbon
library "[[@TEST_NAME]]";
fn F() {
(fn [T: Core.Copy](x: T) => x);
}
// CHECK:STDOUT: --- empty.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
+124 -97
View File
@@ -14,6 +14,7 @@
library "[[@TEST_NAME]]";
fn ImportedId(x: i32) => x;
fn ImportedGenericId[T: Core.Copy](x: T) => x;
// --- main.carbon
library "[[@TEST_NAME]]";
@@ -21,10 +22,11 @@ library "[[@TEST_NAME]]";
import library "lib";
fn LocalId(x: i32) => x;
fn LocalGenericId[T: Core.Copy](x: T) => x;
fn Unit() => ();
fn MakePair(x: i32, y: i32) => {.a = x, .b = y};
fn MakePair[T: Core.Copy, U: Core.Copy](x: T, y: U) => {.a = x, .b = y};
class C {
fn Get(self: Self) => self.x;
@@ -33,7 +35,8 @@ class C {
fn Test(c: C) -> i32 {
Unit();
let p: {.a: i32, .b: i32} = MakePair(ImportedId(c.Get()), LocalId(2));
let p: {.a: i32, .b: i32} =
MakePair(ImportedGenericId(ImportedId(c.Get())), LocalGenericId(LocalId(2)));
return p.a;
}
@@ -69,85 +72,98 @@ fn Test(c: C) -> i32 {
// CHECK:STDOUT: source_filename = "main.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @_CLocalId.Main(i32 %x) #0 !dbg !39 {
// CHECK:STDOUT: define i32 @_CLocalId.Main(i32 %x) #0 !dbg !37 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret i32 %x, !dbg !42
// CHECK:STDOUT: ret i32 %x, !dbg !40
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CUnit.Main() #0 !dbg !44 {
// CHECK:STDOUT: define void @_CUnit.Main() #0 !dbg !42 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret void, !dbg !45
// CHECK:STDOUT: ret void, !dbg !43
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define void @_CMakePair.Main(ptr sret({ i32, i32 }) %return, i32 %x, i32 %y) #0 !dbg !46 {
// CHECK:STDOUT: define i32 @_CGet.C.Main(ptr %self) #0 !dbg !44 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc9_47.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 0, !dbg !51
// CHECK:STDOUT: store i32 %x, ptr %.loc9_47.3.a, align 4, !dbg !51
// CHECK:STDOUT: %.loc9_47.5.b = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 1, !dbg !51
// CHECK:STDOUT: store i32 %y, ptr %.loc9_47.5.b, align 4, !dbg !51
// CHECK:STDOUT: ret void, !dbg !51
// CHECK:STDOUT: %.loc13_29.1.x = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !47
// CHECK:STDOUT: %.loc13_29.2 = load i32, ptr %.loc13_29.1.x, align 4, !dbg !47
// CHECK:STDOUT: ret i32 %.loc13_29.2, !dbg !47
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @_CGet.C.Main(ptr %self) #0 !dbg !55 {
// CHECK:STDOUT: define i32 @_CTest.Main(ptr %c) #0 !dbg !49 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc12_29.1.x = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !58
// CHECK:STDOUT: %.loc12_29.2 = load i32, ptr %.loc12_29.1.x, align 4, !dbg !58
// CHECK:STDOUT: ret i32 %.loc12_29.2, !dbg !58
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @_CTest.Main(ptr %c) #0 !dbg !60 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc18_71.1.temp = alloca { i32, i32 }, align 4, !dbg !69
// CHECK:STDOUT: %struct = alloca { i32, i32 }, align 4, !dbg !69
// CHECK:STDOUT: call void @_CUnit.Main(), !dbg !65
// CHECK:STDOUT: %C.Get.call = call i32 @_CGet.C.Main(ptr %c), !dbg !66
// CHECK:STDOUT: %ImportedId.call = call i32 @_CImportedId.Main(i32 %C.Get.call), !dbg !67
// CHECK:STDOUT: %LocalId.call = call i32 @_CLocalId.Main(i32 2), !dbg !68
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_71.1.temp), !dbg !69
// CHECK:STDOUT: call void @_CMakePair.Main(ptr %.loc18_71.1.temp, i32 %ImportedId.call, i32 %LocalId.call), !dbg !69
// CHECK:STDOUT: %.loc18_71.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %.loc18_71.1.temp, i32 0, i32 0, !dbg !69
// CHECK:STDOUT: %.loc18_71.4 = load i32, ptr %.loc18_71.3.a, align 4, !dbg !69
// CHECK:STDOUT: %.loc18_71.5.b = getelementptr inbounds nuw { i32, i32 }, ptr %.loc18_71.1.temp, i32 0, i32 1, !dbg !69
// CHECK:STDOUT: %.loc18_71.6 = load i32, ptr %.loc18_71.5.b, align 4, !dbg !69
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %struct), !dbg !69
// CHECK:STDOUT: %struct1 = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 0, !dbg !69
// CHECK:STDOUT: store i32 %.loc18_71.4, ptr %struct1, align 4, !dbg !69
// CHECK:STDOUT: %struct2 = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 1, !dbg !69
// CHECK:STDOUT: store i32 %.loc18_71.6, ptr %struct2, align 4, !dbg !69
// CHECK:STDOUT: %.loc19.a = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 0, !dbg !72
// CHECK:STDOUT: %.loc19.a.load = load i32, ptr %.loc19.a, align 4, !dbg !72
// CHECK:STDOUT: call void @_CSelfDestruct.Core.ad01ed096e1f14e2(ptr %.loc18_71.1.temp), !dbg !69
// CHECK:STDOUT: ret i32 %.loc19.a.load, !dbg !73
// CHECK:STDOUT: %.loc20_82.5.temp = alloca { i32, i32 }, align 4, !dbg !60
// CHECK:STDOUT: %struct = alloca { i32, i32 }, align 4, !dbg !60
// CHECK:STDOUT: call void @_CUnit.Main(), !dbg !54
// CHECK:STDOUT: %C.Get.call = call i32 @_CGet.C.Main(ptr %c), !dbg !55
// CHECK:STDOUT: %ImportedId.call = call i32 @_CImportedId.Main(i32 %C.Get.call), !dbg !56
// CHECK:STDOUT: %ImportedGenericId.call = call i32 @_CImportedGenericId.Main.2fad9574e050607e(i32 %ImportedId.call), !dbg !57
// CHECK:STDOUT: %LocalId.call = call i32 @_CLocalId.Main(i32 2), !dbg !58
// CHECK:STDOUT: %LocalGenericId.call = call i32 @_CLocalGenericId.Main.2fad9574e050607e(i32 %LocalId.call), !dbg !59
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_82.5.temp), !dbg !60
// CHECK:STDOUT: call void @_CMakePair.Main.3eda18978e8f48e1(ptr %.loc20_82.5.temp, i32 %ImportedGenericId.call, i32 %LocalGenericId.call), !dbg !60
// CHECK:STDOUT: %.loc20_82.7.a = getelementptr inbounds nuw { i32, i32 }, ptr %.loc20_82.5.temp, i32 0, i32 0, !dbg !60
// CHECK:STDOUT: %.loc20_82.8 = load i32, ptr %.loc20_82.7.a, align 4, !dbg !60
// CHECK:STDOUT: %.loc20_82.9.b = getelementptr inbounds nuw { i32, i32 }, ptr %.loc20_82.5.temp, i32 0, i32 1, !dbg !60
// CHECK:STDOUT: %.loc20_82.10 = load i32, ptr %.loc20_82.9.b, align 4, !dbg !60
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %struct), !dbg !60
// CHECK:STDOUT: %struct1 = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 0, !dbg !60
// CHECK:STDOUT: store i32 %.loc20_82.8, ptr %struct1, align 4, !dbg !60
// CHECK:STDOUT: %struct2 = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 1, !dbg !60
// CHECK:STDOUT: store i32 %.loc20_82.10, ptr %struct2, align 4, !dbg !60
// CHECK:STDOUT: %.loc21.a = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 0, !dbg !65
// CHECK:STDOUT: %.loc21.a.load = load i32, ptr %.loc21.a, align 4, !dbg !65
// CHECK:STDOUT: call void @_CSelfDestruct.Core.ad01ed096e1f14e2(ptr %.loc20_82.5.temp), !dbg !60
// CHECK:STDOUT: ret i32 %.loc21.a.load, !dbg !66
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare i32 @_CImportedId.Main(i32)
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define weak_odr void @"_COp.2508ed710019eba8:core.SubobjectDestroy.Core"(ptr %self) #0 !dbg !75 {
// CHECK:STDOUT: define weak_odr void @"_COp.2508ed710019eba8:core.SubobjectDestroy.Core"(ptr %self) #0 !dbg !68 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc18_71.1.b = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 1, !dbg !77
// CHECK:STDOUT: call void @_CSelfDestruct.Core.f127f30143696d51(ptr %.loc18_71.1.b), !dbg !77
// CHECK:STDOUT: %.loc18_71.4.a = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 0, !dbg !77
// CHECK:STDOUT: call void @_CSelfDestruct.Core.f127f30143696d51(ptr %.loc18_71.4.a), !dbg !77
// CHECK:STDOUT: ret void, !dbg !77
// CHECK:STDOUT: %.loc20_82.1.b = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 1, !dbg !70
// CHECK:STDOUT: call void @_CSelfDestruct.Core.f127f30143696d51(ptr %.loc20_82.1.b), !dbg !70
// CHECK:STDOUT: %.loc20_82.4.a = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 0, !dbg !70
// CHECK:STDOUT: call void @_CSelfDestruct.Core.f127f30143696d51(ptr %.loc20_82.4.a), !dbg !70
// CHECK:STDOUT: ret void, !dbg !70
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @_CImportedGenericId.Main.2fad9574e050607e(i32 %x) #0 !dbg !74 {
// CHECK:STDOUT: ret i32 %x, !dbg !77
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @_CLocalGenericId.Main.2fad9574e050607e(i32 %x) #0 !dbg !79 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret i32 %x, !dbg !82
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.ad01ed096e1f14e2(ptr %t) #0 !dbg !81 {
// CHECK:STDOUT: call void @"_COp.2508ed710019eba8:core.SubobjectDestroy.Core"(ptr %t), !dbg !85
// CHECK:STDOUT: ret void, !dbg !86
// CHECK:STDOUT: define linkonce_odr void @_CMakePair.Main.3eda18978e8f48e1(ptr sret({ i32, i32 }) %return, i32 %x, i32 %y) #0 !dbg !84 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %.loc10_71.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 0, !dbg !89
// CHECK:STDOUT: store i32 %x, ptr %.loc10_71.3.a, align 4, !dbg !89
// CHECK:STDOUT: %.loc10_71.5.b = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 1, !dbg !89
// CHECK:STDOUT: store i32 %y, ptr %.loc10_71.5.b, align 4, !dbg !89
// CHECK:STDOUT: ret void, !dbg !89
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.f127f30143696d51(ptr %t) #0 !dbg !88 {
// CHECK:STDOUT: ret void, !dbg !93
// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.ad01ed096e1f14e2(ptr %t) #0 !dbg !93 {
// CHECK:STDOUT: call void @"_COp.2508ed710019eba8:core.SubobjectDestroy.Core"(ptr %t), !dbg !97
// CHECK:STDOUT: ret void, !dbg !98
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr void @_CSelfDestruct.Core.f127f30143696d51(ptr %t) #0 !dbg !100 {
// CHECK:STDOUT: ret void, !dbg !105
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
@@ -163,6 +179,7 @@ fn Test(c: C) -> i32 {
// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5}
// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !10 = !DIFile(filename: "min_prelude/parts/destroy.carbon", directory: "")
// CHECK:STDOUT: !18 = !DIFile(filename: "lib.carbon", directory: "")
// CHECK:STDOUT: !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK:STDOUT: !21 = !{!20, !20}
// CHECK:STDOUT: !22 = !DISubroutineType(types: !21)
@@ -171,50 +188,60 @@ fn Test(c: C) -> i32 {
// CHECK:STDOUT: !30 = !{null}
// CHECK:STDOUT: !31 = !DISubroutineType(types: !30)
// CHECK:STDOUT: !32 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
// CHECK:STDOUT: !33 = !{!32, !20, !20}
// CHECK:STDOUT: !33 = !{!20, !32}
// CHECK:STDOUT: !34 = !DISubroutineType(types: !33)
// CHECK:STDOUT: !35 = !{!20, !32}
// CHECK:STDOUT: !35 = !{null, !32}
// CHECK:STDOUT: !36 = !DISubroutineType(types: !35)
// CHECK:STDOUT: !37 = !{null, !32}
// CHECK:STDOUT: !38 = !DISubroutineType(types: !37)
// CHECK:STDOUT: !39 = distinct !DISubprogram(name: "LocalId", linkageName: "_CLocalId.Main", scope: null, file: !28, line: 5, type: !22, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !43)
// CHECK:STDOUT: !40 = !DILocalVariable(arg: 1, scope: !39, type: !20)
// CHECK:STDOUT: !42 = !DILocation(line: 5, column: 23, scope: !39)
// CHECK:STDOUT: !43 = !{!40}
// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Unit", linkageName: "_CUnit.Main", scope: null, file: !28, line: 7, type: !31, spFlags: DISPFlagDefinition, unit: !29)
// CHECK:STDOUT: !45 = !DILocation(line: 7, column: 14, scope: !44)
// CHECK:STDOUT: !46 = distinct !DISubprogram(name: "MakePair", linkageName: "_CMakePair.Main", scope: null, file: !28, line: 9, type: !34, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !54)
// CHECK:STDOUT: !47 = !DILocalVariable(arg: 1, scope: !46, type: !20)
// CHECK:STDOUT: !48 = !DILocalVariable(arg: 2, scope: !46, type: !20)
// CHECK:STDOUT: !51 = !DILocation(line: 9, column: 32, scope: !46)
// CHECK:STDOUT: !54 = !{!47, !48}
// CHECK:STDOUT: !55 = distinct !DISubprogram(name: "Get", linkageName: "_CGet.C.Main", scope: null, file: !28, line: 12, type: !36, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !59)
// CHECK:STDOUT: !56 = !DILocalVariable(arg: 1, scope: !55, type: !32)
// CHECK:STDOUT: !58 = !DILocation(line: 12, column: 25, scope: !55)
// CHECK:STDOUT: !59 = !{!56}
// CHECK:STDOUT: !60 = distinct !DISubprogram(name: "Test", linkageName: "_CTest.Main", scope: null, file: !28, line: 16, type: !36, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !74)
// CHECK:STDOUT: !61 = !DILocalVariable(arg: 1, scope: !60, type: !32)
// CHECK:STDOUT: !65 = !DILocation(line: 17, column: 3, scope: !60)
// CHECK:STDOUT: !66 = !DILocation(line: 18, column: 51, scope: !60)
// CHECK:STDOUT: !67 = !DILocation(line: 18, column: 40, scope: !60)
// CHECK:STDOUT: !68 = !DILocation(line: 18, column: 61, scope: !60)
// CHECK:STDOUT: !69 = !DILocation(line: 18, column: 31, scope: !60)
// CHECK:STDOUT: !72 = !DILocation(line: 19, column: 10, scope: !60)
// CHECK:STDOUT: !73 = !DILocation(line: 19, column: 3, scope: !60)
// CHECK:STDOUT: !74 = !{!61}
// CHECK:STDOUT: !75 = distinct !DISubprogram(name: "Op", linkageName: "_COp.2508ed710019eba8:core.SubobjectDestroy.Core", scope: null, file: !28, line: 18, type: !38, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !80)
// CHECK:STDOUT: !76 = !DILocalVariable(arg: 1, scope: !75, type: !32)
// CHECK:STDOUT: !77 = !DILocation(line: 18, column: 31, scope: !75)
// CHECK:STDOUT: !78 = !{null, !20}
// CHECK:STDOUT: !79 = !DISubroutineType(types: !78)
// CHECK:STDOUT: !80 = !{!76}
// CHECK:STDOUT: !81 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.Core.ad01ed096e1f14e2", scope: null, file: !10, line: 32, type: !38, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !87)
// CHECK:STDOUT: !82 = !DILocalVariable(arg: 1, scope: !81, type: !32)
// CHECK:STDOUT: !85 = !DILocation(line: 34, column: 5, scope: !81)
// CHECK:STDOUT: !86 = !DILocation(line: 32, column: 1, scope: !81)
// CHECK:STDOUT: !87 = !{!82}
// CHECK:STDOUT: !88 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.Core.f127f30143696d51", scope: null, file: !10, line: 32, type: !79, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !94)
// CHECK:STDOUT: !89 = !DILocalVariable(arg: 1, scope: !88, type: !20)
// CHECK:STDOUT: !93 = !DILocation(line: 32, column: 1, scope: !88)
// CHECK:STDOUT: !94 = !{!89}
// CHECK:STDOUT: !37 = distinct !DISubprogram(name: "LocalId", linkageName: "_CLocalId.Main", scope: null, file: !28, line: 5, type: !22, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !41)
// CHECK:STDOUT: !38 = !DILocalVariable(arg: 1, scope: !37, type: !20)
// CHECK:STDOUT: !40 = !DILocation(line: 5, column: 23, scope: !37)
// CHECK:STDOUT: !41 = !{!38}
// CHECK:STDOUT: !42 = distinct !DISubprogram(name: "Unit", linkageName: "_CUnit.Main", scope: null, file: !28, line: 8, type: !31, spFlags: DISPFlagDefinition, unit: !29)
// CHECK:STDOUT: !43 = !DILocation(line: 8, column: 14, scope: !42)
// CHECK:STDOUT: !44 = distinct !DISubprogram(name: "Get", linkageName: "_CGet.C.Main", scope: null, file: !28, line: 13, type: !34, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !48)
// CHECK:STDOUT: !45 = !DILocalVariable(arg: 1, scope: !44, type: !32)
// CHECK:STDOUT: !47 = !DILocation(line: 13, column: 25, scope: !44)
// CHECK:STDOUT: !48 = !{!45}
// CHECK:STDOUT: !49 = distinct !DISubprogram(name: "Test", linkageName: "_CTest.Main", scope: null, file: !28, line: 17, type: !34, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !67)
// CHECK:STDOUT: !50 = !DILocalVariable(arg: 1, scope: !49, type: !32)
// CHECK:STDOUT: !54 = !DILocation(line: 18, column: 3, scope: !49)
// CHECK:STDOUT: !55 = !DILocation(line: 20, column: 45, scope: !49)
// CHECK:STDOUT: !56 = !DILocation(line: 20, column: 34, scope: !49)
// CHECK:STDOUT: !57 = !DILocation(line: 20, column: 16, scope: !49)
// CHECK:STDOUT: !58 = !DILocation(line: 20, column: 71, scope: !49)
// CHECK:STDOUT: !59 = !DILocation(line: 20, column: 56, scope: !49)
// CHECK:STDOUT: !60 = !DILocation(line: 20, column: 7, scope: !49)
// CHECK:STDOUT: !61 = !{!32, !20, !20}
// CHECK:STDOUT: !62 = !DISubroutineType(types: !61)
// CHECK:STDOUT: !65 = !DILocation(line: 21, column: 10, scope: !49)
// CHECK:STDOUT: !66 = !DILocation(line: 21, column: 3, scope: !49)
// CHECK:STDOUT: !67 = !{!50}
// CHECK:STDOUT: !68 = distinct !DISubprogram(name: "Op", linkageName: "_COp.2508ed710019eba8:core.SubobjectDestroy.Core", scope: null, file: !28, line: 20, type: !36, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !73)
// CHECK:STDOUT: !69 = !DILocalVariable(arg: 1, scope: !68, type: !32)
// CHECK:STDOUT: !70 = !DILocation(line: 20, column: 7, scope: !68)
// CHECK:STDOUT: !71 = !{null, !20}
// CHECK:STDOUT: !72 = !DISubroutineType(types: !71)
// CHECK:STDOUT: !73 = !{!69}
// CHECK:STDOUT: !74 = distinct !DISubprogram(name: "ImportedGenericId", linkageName: "_CImportedGenericId.Main.2fad9574e050607e", scope: null, file: !18, line: 4, type: !22, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !78)
// CHECK:STDOUT: !75 = !DILocalVariable(arg: 1, scope: !74, type: !20)
// CHECK:STDOUT: !77 = !DILocation(line: 4, column: 45, scope: !74)
// CHECK:STDOUT: !78 = !{!75}
// CHECK:STDOUT: !79 = distinct !DISubprogram(name: "LocalGenericId", linkageName: "_CLocalGenericId.Main.2fad9574e050607e", scope: null, file: !28, line: 6, type: !22, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !83)
// CHECK:STDOUT: !80 = !DILocalVariable(arg: 1, scope: !79, type: !20)
// CHECK:STDOUT: !82 = !DILocation(line: 6, column: 42, scope: !79)
// CHECK:STDOUT: !83 = !{!80}
// CHECK:STDOUT: !84 = distinct !DISubprogram(name: "MakePair", linkageName: "_CMakePair.Main.3eda18978e8f48e1", scope: null, file: !28, line: 10, type: !62, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !92)
// CHECK:STDOUT: !85 = !DILocalVariable(arg: 1, scope: !84, type: !20)
// CHECK:STDOUT: !86 = !DILocalVariable(arg: 2, scope: !84, type: !20)
// CHECK:STDOUT: !89 = !DILocation(line: 10, column: 56, scope: !84)
// CHECK:STDOUT: !92 = !{!85, !86}
// CHECK:STDOUT: !93 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.Core.ad01ed096e1f14e2", scope: null, file: !10, line: 32, type: !36, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !99)
// CHECK:STDOUT: !94 = !DILocalVariable(arg: 1, scope: !93, type: !32)
// CHECK:STDOUT: !97 = !DILocation(line: 34, column: 5, scope: !93)
// CHECK:STDOUT: !98 = !DILocation(line: 32, column: 1, scope: !93)
// CHECK:STDOUT: !99 = !{!94}
// CHECK:STDOUT: !100 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.Core.f127f30143696d51", scope: null, file: !10, line: 32, type: !72, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !106)
// CHECK:STDOUT: !101 = !DILocalVariable(arg: 1, scope: !100, type: !20)
// CHECK:STDOUT: !105 = !DILocation(line: 32, column: 1, scope: !100)
// CHECK:STDOUT: !106 = !{!101}
// CHECK:STDOUT:
+54 -40
View File
@@ -15,6 +15,7 @@ library "[[@TEST_NAME]]";
alias Imported = fn (x: i32) -> i32 { return x; };
alias ImportedTerse = fn (x: i32) => x;
alias ImportedGenericTerse = fn [T: Core.Copy](x: T) => x;
// --- main.carbon
library "[[@TEST_NAME]]";
@@ -25,8 +26,9 @@ fn Test() -> i32 {
alias f = fn (x: i32) -> i32 {
return x;
};
alias g = fn (x: i32) => x;
return (fn (y: i32) => y)(g(f(ImportedTerse(Imported(1)))));
alias g = fn [T: Core.Copy](x: T) => x;
return (fn [T: Core.Copy](y: T) => y)(
g(f(ImportedGenericTerse(ImportedTerse(Imported(1))))));
}
// CHECK:STDOUT: ; ---
@@ -73,36 +75,42 @@ fn Test() -> i32 {
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @_CTest.Main() #0 !dbg !40 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %fn.call.loc10_57 = call i32 @"_Cfn:enclosed.3c14c8ca6559e7d0"(i32 1), !dbg !43
// CHECK:STDOUT: %fn.call.loc10_58 = call i32 @"_Cfn:enclosed.c7952b8f54fe2475"(i32 %fn.call.loc10_57), !dbg !44
// CHECK:STDOUT: %fn.call.loc10_59 = call i32 @"_Cfn:enclosed.78e97d08196088b9"(i32 %fn.call.loc10_58), !dbg !45
// CHECK:STDOUT: %fn.call.loc10_60 = call i32 @"_Cfn:enclosed.0e7270695e932392"(i32 %fn.call.loc10_59), !dbg !46
// CHECK:STDOUT: %fn.call.loc10_61 = call i32 @"_Cfn:enclosed.1fd415d9d5ad7882"(i32 %fn.call.loc10_60), !dbg !47
// CHECK:STDOUT: ret i32 %fn.call.loc10_61, !dbg !48
// CHECK:STDOUT: %fn.call.loc11_56 = call i32 @"_Cfn:enclosed.3c14c8ca6559e7d0"(i32 1), !dbg !43
// CHECK:STDOUT: %fn.call.loc11_57 = call i32 @"_Cfn:enclosed.c7952b8f54fe2475"(i32 %fn.call.loc11_56), !dbg !44
// CHECK:STDOUT: %fn.call.loc11_58 = call i32 @"_Cfn:enclosed.8a40e95b23d3f272.2fad9574e050607e"(i32 %fn.call.loc11_57), !dbg !45
// CHECK:STDOUT: %fn.call.loc11_59 = call i32 @"_Cfn:enclosed.1a725d33c50a7457"(i32 %fn.call.loc11_58), !dbg !46
// CHECK:STDOUT: %fn.call.loc11_60 = call i32 @"_Cfn:enclosed.e581b0d03d82ce06.2fad9574e050607e"(i32 %fn.call.loc11_59), !dbg !47
// CHECK:STDOUT: %fn.call.loc11_61 = call i32 @"_Cfn:enclosed.c27343342d9f58cb.2fad9574e050607e"(i32 %fn.call.loc11_60), !dbg !48
// CHECK:STDOUT: ret i32 %fn.call.loc11_61, !dbg !49
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.78e97d08196088b9"(i32 %x) #0 !dbg !49 {
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.1a725d33c50a7457"(i32 %x) #0 !dbg !50 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret i32 %x, !dbg !55
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.0e7270695e932392"(i32 %x) #0 !dbg !57 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret i32 %x, !dbg !60
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.1fd415d9d5ad7882"(i32 %y) #0 !dbg !62 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret i32 %y, !dbg !65
// CHECK:STDOUT: ret i32 %x, !dbg !56
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: declare i32 @"_Cfn:enclosed.c7952b8f54fe2475"(i32)
// CHECK:STDOUT:
// CHECK:STDOUT: declare i32 @"_Cfn:enclosed.3c14c8ca6559e7d0"(i32)
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @"_Cfn:enclosed.8a40e95b23d3f272.2fad9574e050607e"(i32 %x) #0 !dbg !58 {
// CHECK:STDOUT: ret i32 %x, !dbg !61
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @"_Cfn:enclosed.e581b0d03d82ce06.2fad9574e050607e"(i32 %x) #0 !dbg !63 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret i32 %x, !dbg !66
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define linkonce_odr i32 @"_Cfn:enclosed.c27343342d9f58cb.2fad9574e050607e"(i32 %y) #0 !dbg !68 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: ret i32 %y, !dbg !71
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT:
// CHECK:STDOUT: !llvm.dbg.cu = !{!37}
@@ -110,6 +118,7 @@ fn Test() -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5}
// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !18 = !DIFile(filename: "lib.carbon", directory: "")
// CHECK:STDOUT: !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
// CHECK:STDOUT: !21 = !{!20, !20}
// CHECK:STDOUT: !22 = !DISubroutineType(types: !21)
@@ -118,22 +127,27 @@ fn Test() -> i32 {
// CHECK:STDOUT: !38 = !{!20}
// CHECK:STDOUT: !39 = !DISubroutineType(types: !38)
// CHECK:STDOUT: !40 = distinct !DISubprogram(name: "Test", linkageName: "_CTest.Main", scope: null, file: !36, line: 5, type: !39, spFlags: DISPFlagDefinition, unit: !37)
// CHECK:STDOUT: !43 = !DILocation(line: 10, column: 47, scope: !40)
// CHECK:STDOUT: !44 = !DILocation(line: 10, column: 33, scope: !40)
// CHECK:STDOUT: !45 = !DILocation(line: 10, column: 31, scope: !40)
// CHECK:STDOUT: !46 = !DILocation(line: 10, column: 29, scope: !40)
// CHECK:STDOUT: !47 = !DILocation(line: 10, column: 10, scope: !40)
// CHECK:STDOUT: !48 = !DILocation(line: 10, column: 3, scope: !40)
// CHECK:STDOUT: !49 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.78e97d08196088b9", scope: null, file: !36, line: 6, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !56)
// CHECK:STDOUT: !50 = !DILocalVariable(arg: 1, scope: !49, type: !20)
// CHECK:STDOUT: !55 = !DILocation(line: 7, column: 5, scope: !49)
// CHECK:STDOUT: !56 = !{!50}
// CHECK:STDOUT: !57 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.0e7270695e932392", scope: null, file: !36, line: 9, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !61)
// CHECK:STDOUT: !58 = !DILocalVariable(arg: 1, scope: !57, type: !20)
// CHECK:STDOUT: !60 = !DILocation(line: 9, column: 28, scope: !57)
// CHECK:STDOUT: !61 = !{!58}
// CHECK:STDOUT: !62 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.1fd415d9d5ad7882", scope: null, file: !36, line: 10, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !66)
// CHECK:STDOUT: !63 = !DILocalVariable(arg: 1, scope: !62, type: !20)
// CHECK:STDOUT: !65 = !DILocation(line: 10, column: 26, scope: !62)
// CHECK:STDOUT: !66 = !{!63}
// CHECK:STDOUT: !43 = !DILocation(line: 11, column: 46, scope: !40)
// CHECK:STDOUT: !44 = !DILocation(line: 11, column: 32, scope: !40)
// CHECK:STDOUT: !45 = !DILocation(line: 11, column: 11, scope: !40)
// CHECK:STDOUT: !46 = !DILocation(line: 11, column: 9, scope: !40)
// CHECK:STDOUT: !47 = !DILocation(line: 11, column: 7, scope: !40)
// CHECK:STDOUT: !48 = !DILocation(line: 10, column: 10, scope: !40)
// CHECK:STDOUT: !49 = !DILocation(line: 10, column: 3, scope: !40)
// CHECK:STDOUT: !50 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.1a725d33c50a7457", scope: null, file: !36, line: 6, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !57)
// CHECK:STDOUT: !51 = !DILocalVariable(arg: 1, scope: !50, type: !20)
// CHECK:STDOUT: !56 = !DILocation(line: 7, column: 5, scope: !50)
// CHECK:STDOUT: !57 = !{!51}
// CHECK:STDOUT: !58 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.8a40e95b23d3f272.2fad9574e050607e", scope: null, file: !18, line: 5, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !62)
// CHECK:STDOUT: !59 = !DILocalVariable(arg: 1, scope: !58, type: !20)
// CHECK:STDOUT: !61 = !DILocation(line: 5, column: 57, scope: !58)
// CHECK:STDOUT: !62 = !{!59}
// CHECK:STDOUT: !63 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.e581b0d03d82ce06.2fad9574e050607e", scope: null, file: !36, line: 9, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !67)
// CHECK:STDOUT: !64 = !DILocalVariable(arg: 1, scope: !63, type: !20)
// CHECK:STDOUT: !66 = !DILocation(line: 9, column: 40, scope: !63)
// CHECK:STDOUT: !67 = !{!64}
// CHECK:STDOUT: !68 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.c27343342d9f58cb.2fad9574e050607e", scope: null, file: !36, line: 10, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !72)
// CHECK:STDOUT: !69 = !DILocalVariable(arg: 1, scope: !68, type: !20)
// CHECK:STDOUT: !71 = !DILocation(line: 10, column: 38, scope: !68)
// CHECK:STDOUT: !72 = !{!69}
// CHECK:STDOUT: