precompile and cache Carbon prelude (#7432)

Refactors the link driver to automatically compile and cache the carbon
prelude for use in linking.

Implements a `carbon_library` rule for compiling the Core library
dependencies in the examples.
This commit is contained in:
Lucile Rose Nihlen
2026-07-16 18:02:14 +00:00
committed by GitHub
parent 90f6654b48
commit 625f2ca629
63 changed files with 1454 additions and 634 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
// ARGS: -v compile --phase=check %s
// ARGS: -v compile --phase=check --no-include-carbon-core %s
//
// Only checks a couple statements in order to minimize manual update churn.
// To test this file alone, run:
+18 -17
View File
@@ -2,6 +2,7 @@
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// EXTRA-ARGS: --include-carbon-core
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/full.carbon
//
// AUTOUPDATE
@@ -29,7 +30,7 @@ fn Main() {
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %PrintChar.type.7a7: type = fn_type @PrintChar.loc15 [concrete]
// CHECK:STDOUT: %PrintChar.type.7a7: type = fn_type @PrintChar.loc16 [concrete]
// CHECK:STDOUT: %PrintChar.772: %PrintChar.type.7a7 = struct_value () [concrete]
// CHECK:STDOUT: %.75c: Core.CharLiteral = char_value U+0031 [concrete]
// CHECK:STDOUT: %ImplicitAs.type.0ff: type = generic_interface_type @ImplicitAs [concrete]
@@ -70,23 +71,23 @@ fn Main() {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Main() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %PrintChar.ref.loc19: %PrintChar.type.7a7 = name_ref PrintChar, file.%PrintChar.decl [concrete = constants.%PrintChar.772]
// CHECK:STDOUT: %.loc19_13.1: Core.CharLiteral = char_value U+0031 [concrete = constants.%.75c]
// CHECK:STDOUT: %impl.elem0.loc19: %.1e6 = impl_witness_access constants.%ImplicitAs.impl_witness.780, element0 [concrete = constants.%Core.CharLiteral.as.ImplicitAs.impl.Convert]
// CHECK:STDOUT: %bound_method.loc19: <bound method> = bound_method %.loc19_13.1, %impl.elem0.loc19 [concrete = constants.%Core.CharLiteral.as.ImplicitAs.impl.Convert.bound.17b]
// CHECK:STDOUT: %Core.CharLiteral.as.ImplicitAs.impl.Convert.call.loc19: init %char = call %bound_method.loc19(%.loc19_13.1) [concrete = constants.%int_49]
// CHECK:STDOUT: %.loc19_13.2: %char = value_of_initializer %Core.CharLiteral.as.ImplicitAs.impl.Convert.call.loc19 [concrete = constants.%int_49]
// CHECK:STDOUT: %.loc19_13.3: %char = converted %.loc19_13.1, %.loc19_13.2 [concrete = constants.%int_49]
// CHECK:STDOUT: %PrintChar.call.loc19: init %i32 = call %PrintChar.ref.loc19(%.loc19_13.3)
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
// CHECK:STDOUT: %PrintChar.ref.loc20: %PrintChar.type.b3c = name_ref PrintChar, imports.%Core.PrintChar [concrete = constants.%PrintChar.063]
// CHECK:STDOUT: %.loc20_18.1: Core.CharLiteral = char_value U+0032 [concrete = constants.%.f8d]
// CHECK:STDOUT: %PrintChar.ref.loc20: %PrintChar.type.7a7 = name_ref PrintChar, file.%PrintChar.decl [concrete = constants.%PrintChar.772]
// CHECK:STDOUT: %.loc20_13.1: Core.CharLiteral = char_value U+0031 [concrete = constants.%.75c]
// CHECK:STDOUT: %impl.elem0.loc20: %.1e6 = impl_witness_access constants.%ImplicitAs.impl_witness.780, element0 [concrete = constants.%Core.CharLiteral.as.ImplicitAs.impl.Convert]
// CHECK:STDOUT: %bound_method.loc20: <bound method> = bound_method %.loc20_18.1, %impl.elem0.loc20 [concrete = constants.%Core.CharLiteral.as.ImplicitAs.impl.Convert.bound.e67]
// CHECK:STDOUT: %Core.CharLiteral.as.ImplicitAs.impl.Convert.call.loc20: init %char = call %bound_method.loc20(%.loc20_18.1) [concrete = constants.%int_50]
// CHECK:STDOUT: %.loc20_18.2: %char = value_of_initializer %Core.CharLiteral.as.ImplicitAs.impl.Convert.call.loc20 [concrete = constants.%int_50]
// CHECK:STDOUT: %.loc20_18.3: %char = converted %.loc20_18.1, %.loc20_18.2 [concrete = constants.%int_50]
// CHECK:STDOUT: %PrintChar.call.loc20: init %i32 = call %PrintChar.ref.loc20(%.loc20_18.3)
// CHECK:STDOUT: %bound_method.loc20: <bound method> = bound_method %.loc20_13.1, %impl.elem0.loc20 [concrete = constants.%Core.CharLiteral.as.ImplicitAs.impl.Convert.bound.17b]
// CHECK:STDOUT: %Core.CharLiteral.as.ImplicitAs.impl.Convert.call.loc20: init %char = call %bound_method.loc20(%.loc20_13.1) [concrete = constants.%int_49]
// CHECK:STDOUT: %.loc20_13.2: %char = value_of_initializer %Core.CharLiteral.as.ImplicitAs.impl.Convert.call.loc20 [concrete = constants.%int_49]
// CHECK:STDOUT: %.loc20_13.3: %char = converted %.loc20_13.1, %.loc20_13.2 [concrete = constants.%int_49]
// CHECK:STDOUT: %PrintChar.call.loc20: init %i32 = call %PrintChar.ref.loc20(%.loc20_13.3)
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
// CHECK:STDOUT: %PrintChar.ref.loc21: %PrintChar.type.b3c = name_ref PrintChar, imports.%Core.PrintChar [concrete = constants.%PrintChar.063]
// CHECK:STDOUT: %.loc21_18.1: Core.CharLiteral = char_value U+0032 [concrete = constants.%.f8d]
// CHECK:STDOUT: %impl.elem0.loc21: %.1e6 = impl_witness_access constants.%ImplicitAs.impl_witness.780, element0 [concrete = constants.%Core.CharLiteral.as.ImplicitAs.impl.Convert]
// CHECK:STDOUT: %bound_method.loc21: <bound method> = bound_method %.loc21_18.1, %impl.elem0.loc21 [concrete = constants.%Core.CharLiteral.as.ImplicitAs.impl.Convert.bound.e67]
// CHECK:STDOUT: %Core.CharLiteral.as.ImplicitAs.impl.Convert.call.loc21: init %char = call %bound_method.loc21(%.loc21_18.1) [concrete = constants.%int_50]
// CHECK:STDOUT: %.loc21_18.2: %char = value_of_initializer %Core.CharLiteral.as.ImplicitAs.impl.Convert.call.loc21 [concrete = constants.%int_50]
// CHECK:STDOUT: %.loc21_18.3: %char = converted %.loc21_18.1, %.loc21_18.2 [concrete = constants.%int_50]
// CHECK:STDOUT: %PrintChar.call.loc21: init %i32 = call %PrintChar.ref.loc21(%.loc21_18.3)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
+20 -19
View File
@@ -2,6 +2,7 @@
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// EXTRA-ARGS: --include-carbon-core
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/full.carbon
//
// AUTOUPDATE
@@ -29,7 +30,7 @@ fn Main() {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %Print.type.009: type = fn_type @Print.loc15 [concrete]
// CHECK:STDOUT: %Print.type.009: type = fn_type @Print.loc16 [concrete]
// CHECK:STDOUT: %Print.9c5: %Print.type.009 = struct_value () [concrete]
// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete]
// CHECK:STDOUT: %ImplicitAs.type.0ff: type = generic_interface_type @ImplicitAs [concrete]
@@ -74,27 +75,27 @@ fn Main() {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Main() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Print.ref.loc19: %Print.type.009 = name_ref Print, file.%Print.decl [concrete = constants.%Print.9c5]
// CHECK:STDOUT: %Print.ref.loc20: %Print.type.009 = name_ref Print, file.%Print.decl [concrete = constants.%Print.9c5]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %impl.elem0.loc19: %.1c5 = impl_witness_access constants.%ImplicitAs.impl_witness.a23, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
// CHECK:STDOUT: %bound_method.loc19_9.1: <bound method> = bound_method %int_1, %impl.elem0.loc19 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.094]
// CHECK:STDOUT: %specific_fn.loc19: <specific function> = specific_function %impl.elem0.loc19, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc19_9.2: <bound method> = bound_method %int_1, %specific_fn.loc19 [concrete = constants.%bound_method.953]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc19: init %i32 = call %bound_method.loc19_9.2(%int_1) [concrete = constants.%int_1.0c6]
// CHECK:STDOUT: %.loc19_9.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc19 [concrete = constants.%int_1.0c6]
// CHECK:STDOUT: %.loc19_9.2: %i32 = converted %int_1, %.loc19_9.1 [concrete = constants.%int_1.0c6]
// CHECK:STDOUT: %Print.call.loc19: init %empty_tuple.type = call %Print.ref.loc19(%.loc19_9.2)
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
// CHECK:STDOUT: %Print.ref.loc20: %Print.type.4a7 = name_ref Print, imports.%Core.Print [concrete = constants.%Print.d24]
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
// CHECK:STDOUT: %impl.elem0.loc20: %.1c5 = impl_witness_access constants.%ImplicitAs.impl_witness.a23, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
// CHECK:STDOUT: %bound_method.loc20_14.1: <bound method> = bound_method %int_2, %impl.elem0.loc20 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.9f3]
// CHECK:STDOUT: %bound_method.loc20_9.1: <bound method> = bound_method %int_1, %impl.elem0.loc20 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.094]
// CHECK:STDOUT: %specific_fn.loc20: <specific function> = specific_function %impl.elem0.loc20, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc20_14.2: <bound method> = bound_method %int_2, %specific_fn.loc20 [concrete = constants.%bound_method.3cb]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc20: init %i32 = call %bound_method.loc20_14.2(%int_2) [concrete = constants.%int_2.295]
// CHECK:STDOUT: %.loc20_14.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc20 [concrete = constants.%int_2.295]
// CHECK:STDOUT: %.loc20_14.2: %i32 = converted %int_2, %.loc20_14.1 [concrete = constants.%int_2.295]
// CHECK:STDOUT: %Print.call.loc20: init %empty_tuple.type = call %Print.ref.loc20(%.loc20_14.2)
// CHECK:STDOUT: %bound_method.loc20_9.2: <bound method> = bound_method %int_1, %specific_fn.loc20 [concrete = constants.%bound_method.953]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc20: init %i32 = call %bound_method.loc20_9.2(%int_1) [concrete = constants.%int_1.0c6]
// CHECK:STDOUT: %.loc20_9.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc20 [concrete = constants.%int_1.0c6]
// CHECK:STDOUT: %.loc20_9.2: %i32 = converted %int_1, %.loc20_9.1 [concrete = constants.%int_1.0c6]
// CHECK:STDOUT: %Print.call.loc20: init %empty_tuple.type = call %Print.ref.loc20(%.loc20_9.2)
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [concrete = imports.%Core]
// CHECK:STDOUT: %Print.ref.loc21: %Print.type.4a7 = name_ref Print, imports.%Core.Print [concrete = constants.%Print.d24]
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
// CHECK:STDOUT: %impl.elem0.loc21: %.1c5 = impl_witness_access constants.%ImplicitAs.impl_witness.a23, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
// CHECK:STDOUT: %bound_method.loc21_14.1: <bound method> = bound_method %int_2, %impl.elem0.loc21 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.9f3]
// CHECK:STDOUT: %specific_fn.loc21: <specific function> = specific_function %impl.elem0.loc21, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc21_14.2: <bound method> = bound_method %int_2, %specific_fn.loc21 [concrete = constants.%bound_method.3cb]
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc21: init %i32 = call %bound_method.loc21_14.2(%int_2) [concrete = constants.%int_2.295]
// CHECK:STDOUT: %.loc21_14.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc21 [concrete = constants.%int_2.295]
// CHECK:STDOUT: %.loc21_14.2: %i32 = converted %int_2, %.loc21_14.1 [concrete = constants.%int_2.295]
// CHECK:STDOUT: %Print.call.loc21: init %empty_tuple.type = call %Print.ref.loc21(%.loc21_14.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
+1
View File
@@ -2,6 +2,7 @@
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// EXTRA-ARGS: --include-carbon-core
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/full.carbon
//
// AUTOUPDATE
+6
View File
@@ -134,10 +134,16 @@ fn InstanceC(a: A) -> C {
// CHECK:STDOUT: %assoc0: %ImplicitAs.assoc_type = assoc_entity element0, @ImplicitAs.WithSelf.%ImplicitAs.WithSelf.Convert.decl [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.Destroy = import_ref Core//prelude/parts/destroy, Destroy, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .Destroy = imports.%Core.Destroy
// CHECK:STDOUT: .ImplicitAs = %ImplicitAs.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %default.import = import <none>
// CHECK:STDOUT: %ImplicitAs.decl: %ImplicitAs.type.0ff = interface_decl @ImplicitAs [concrete = constants.%ImplicitAs.generic] {
// CHECK:STDOUT: %Dest.patt.loc3_26.1: %pattern_type.98f = symbolic_binding_pattern Dest, 0 [symbolic = %Dest.patt.loc3_26.2 (constants.%Dest.patt)]
// CHECK:STDOUT: } {
@@ -84,10 +84,32 @@ fn F() {
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.UnsafeAs = import_ref Core//prelude/parts/as, UnsafeAs, unloaded
// CHECK:STDOUT: %Core.As = import_ref Core//prelude/parts/as, As, unloaded
// CHECK:STDOUT: %Core.ImplicitAs = import_ref Core//prelude/parts/as, ImplicitAs, unloaded
// CHECK:STDOUT: %Core.BitAndWith = import_ref Core//prelude/parts/as, BitAndWith, unloaded
// CHECK:STDOUT: %Core.Copy = import_ref Core//prelude/parts/copy, Copy, unloaded
// CHECK:STDOUT: %Core.DefaultOrUnformed = import_ref Core//prelude/parts/default, DefaultOrUnformed, unloaded
// CHECK:STDOUT: %Core.Default = import_ref Core//prelude/parts/default, Default, unloaded
// CHECK:STDOUT: %Core.Destroy = import_ref Core//prelude/parts/destroy, Destroy, unloaded
// CHECK:STDOUT: %Core.Form = import_ref Core//prelude/parts/form, Form, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .UnsafeAs = imports.%Core.UnsafeAs
// CHECK:STDOUT: .As = imports.%Core.As
// CHECK:STDOUT: .ImplicitAs = imports.%Core.ImplicitAs
// CHECK:STDOUT: .BitAndWith = imports.%Core.BitAndWith
// CHECK:STDOUT: .Copy = imports.%Core.Copy
// CHECK:STDOUT: .DefaultOrUnformed = imports.%Core.DefaultOrUnformed
// CHECK:STDOUT: .Default = imports.%Core.Default
// CHECK:STDOUT: .Destroy = imports.%Core.Destroy
// CHECK:STDOUT: .Form = imports.%Core.Form
// CHECK:STDOUT: .IndexWith = %IndexWith.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %default.import = import <none>
// CHECK:STDOUT: %IndexWith.decl: type = class_decl @IndexWith [concrete = constants.%IndexWith] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -210,10 +232,32 @@ fn F() {
// CHECK:STDOUT: %assoc0: %IndexWith.assoc_type = assoc_entity element0, @IndexWith.WithSelf.%IndexWith.WithSelf.At.decl [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.UnsafeAs = import_ref Core//prelude/parts/as, UnsafeAs, unloaded
// CHECK:STDOUT: %Core.As = import_ref Core//prelude/parts/as, As, unloaded
// CHECK:STDOUT: %Core.ImplicitAs = import_ref Core//prelude/parts/as, ImplicitAs, unloaded
// CHECK:STDOUT: %Core.BitAndWith = import_ref Core//prelude/parts/as, BitAndWith, unloaded
// CHECK:STDOUT: %Core.Copy = import_ref Core//prelude/parts/copy, Copy, unloaded
// CHECK:STDOUT: %Core.DefaultOrUnformed = import_ref Core//prelude/parts/default, DefaultOrUnformed, unloaded
// CHECK:STDOUT: %Core.Default = import_ref Core//prelude/parts/default, Default, unloaded
// CHECK:STDOUT: %Core.Destroy = import_ref Core//prelude/parts/destroy, Destroy, unloaded
// CHECK:STDOUT: %Core.Form = import_ref Core//prelude/parts/form, Form, unloaded
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .UnsafeAs = imports.%Core.UnsafeAs
// CHECK:STDOUT: .As = imports.%Core.As
// CHECK:STDOUT: .ImplicitAs = imports.%Core.ImplicitAs
// CHECK:STDOUT: .BitAndWith = imports.%Core.BitAndWith
// CHECK:STDOUT: .Copy = imports.%Core.Copy
// CHECK:STDOUT: .DefaultOrUnformed = imports.%Core.DefaultOrUnformed
// CHECK:STDOUT: .Default = imports.%Core.Default
// CHECK:STDOUT: .Destroy = imports.%Core.Destroy
// CHECK:STDOUT: .Form = imports.%Core.Form
// CHECK:STDOUT: .IndexWith = %IndexWith.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %default.import = import <none>
// CHECK:STDOUT: %IndexWith.decl: %IndexWith.type.df6 = interface_decl @IndexWith [concrete = constants.%IndexWith.generic] {
// CHECK:STDOUT: %SubscriptType.patt.loc4_34.1: %pattern_type.98f = symbolic_binding_pattern SubscriptType, 0 [symbolic = %SubscriptType.patt.loc4_34.2 (constants.%SubscriptType.patt)]
// CHECK:STDOUT: %ElementType.patt.loc4_53.1: %pattern_type.98f = symbolic_binding_pattern ElementType, 1 [symbolic = %ElementType.patt.loc4_53.2 (constants.%ElementType.patt)]