Files
carbon-lang/toolchain/check/testdata/class/basic.carbon
T
Richard Smith 6fe8e0b5aa Provide generic impls for Core.Int and Core.UInt operations. (#4693)
Instead of providing operations only for `i32`, provide them for all
`iN` and `uN` types.

For now, this excludes the `*Assign`, `Inc` and `Dec` interfaces,
because the implementations for those are defined as Carbon functions
rather than builtins, and we can't yet lower definitions for specific
functions, so converting those to be generic breaks the build for our
examples.
2024-12-19 22:02:18 +00:00

176 lines
9.7 KiB
Plaintext

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/class/basic.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/basic.carbon
class Class {
fn F(n: i32) -> i32 {
return n;
}
fn G(n: i32) -> i32;
var k: i32;
}
fn Class.G(n: i32) -> i32 {
return n;
}
fn Run() -> i32 {
return Class.F(4);
}
// CHECK:STDOUT: --- basic.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Class: type = class_type @Class [template]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [template]
// CHECK:STDOUT: %F.type: type = fn_type @F [template]
// CHECK:STDOUT: %F: %F.type = struct_value () [template]
// CHECK:STDOUT: %G.type: type = fn_type @G [template]
// CHECK:STDOUT: %G: %G.type = struct_value () [template]
// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [template]
// CHECK:STDOUT: %struct_type.k: type = struct_type {.k: %i32} [template]
// CHECK:STDOUT: %complete_type.3: <witness> = complete_type_witness %struct_type.k [template]
// CHECK:STDOUT: %Run.type: type = fn_type @Run [template]
// CHECK:STDOUT: %Run: %Run.type = struct_value () [template]
// CHECK:STDOUT: %int_4.1: Core.IntLiteral = int_value 4 [template]
// CHECK:STDOUT: %Convert.type.2: type = fn_type @Convert.1, @ImplicitAs(%i32) [template]
// CHECK:STDOUT: %Convert.type.10: type = fn_type @Convert.2, @impl.1(%int_32) [template]
// CHECK:STDOUT: %Convert.10: %Convert.type.10 = struct_value () [template]
// CHECK:STDOUT: %interface.19: <witness> = interface_witness (%Convert.10) [template]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_4.1, %Convert.10 [template]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(%int_32) [template]
// CHECK:STDOUT: %int_4.2: %i32 = int_value 4 [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] {
// CHECK:STDOUT: .Int = %import_ref.1
// CHECK:STDOUT: .ImplicitAs = %import_ref.5
// CHECK:STDOUT: import Core//prelude
// CHECK:STDOUT: import Core//prelude/...
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .Core = imports.%Core
// CHECK:STDOUT: .Class = %Class.decl
// CHECK:STDOUT: .Run = %Run.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %Core.import = import Core
// CHECK:STDOUT: %Class.decl: type = class_decl @Class [template = constants.%Class] {} {}
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
// CHECK:STDOUT: %n.patt: %i32 = binding_pattern n
// CHECK:STDOUT: %n.param_patt: %i32 = value_param_pattern %n.patt, runtime_param0
// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern
// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1
// CHECK:STDOUT: } {
// CHECK:STDOUT: %int_32.loc21_23: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc21_23: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %n.param.loc21: %i32 = value_param runtime_param0
// CHECK:STDOUT: %.loc21: type = splice_block %i32.loc21_15 [template = constants.%i32] {
// CHECK:STDOUT: %int_32.loc21_15: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc21_15: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %n.loc21: %i32 = bind_name n, %n.param.loc21
// CHECK:STDOUT: %return.param.loc21: ref %i32 = out_param runtime_param1
// CHECK:STDOUT: %return.loc21: ref %i32 = return_slot %return.param.loc21
// CHECK:STDOUT: }
// CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [template = constants.%Run] {
// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern
// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param0
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @Class {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {
// CHECK:STDOUT: %n.patt: %i32 = binding_pattern n
// CHECK:STDOUT: %n.param_patt: %i32 = value_param_pattern %n.patt, runtime_param0
// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern
// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1
// CHECK:STDOUT: } {
// CHECK:STDOUT: %int_32.loc12_19: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc12_19: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %n.param: %i32 = value_param runtime_param0
// CHECK:STDOUT: %.loc12: type = splice_block %i32.loc12_11 [template = constants.%i32] {
// CHECK:STDOUT: %int_32.loc12_11: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc12_11: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %n: %i32 = bind_name n, %n.param
// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param1
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {
// CHECK:STDOUT: %n.patt: %i32 = binding_pattern n
// CHECK:STDOUT: %n.param_patt: %i32 = value_param_pattern %n.patt, runtime_param0
// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern
// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param1
// CHECK:STDOUT: } {
// CHECK:STDOUT: %int_32.loc16_19: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc16_19: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %n.param.loc16: %i32 = value_param runtime_param0
// CHECK:STDOUT: %.loc16: type = splice_block %i32.loc16_11 [template = constants.%i32] {
// CHECK:STDOUT: %int_32.loc16_11: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc16_11: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %n.loc16: %i32 = bind_name n, %n.param.loc16
// CHECK:STDOUT: %return.param.loc16: ref %i32 = out_param runtime_param1
// CHECK:STDOUT: %return.loc16: ref %i32 = return_slot %return.param.loc16
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc18: %Class.elem = field_decl k, element0 [template]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %struct_type.k [template = constants.%complete_type.3]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%Class
// CHECK:STDOUT: .F = %F.decl
// CHECK:STDOUT: .G = %G.decl
// CHECK:STDOUT: .k = %.loc18
// CHECK:STDOUT: complete_type_witness = %complete_type
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%n.param_patt: %i32) -> %i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %n.ref: %i32 = name_ref n, %n
// CHECK:STDOUT: return %n.ref
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G(%n.param_patt: %i32) -> %i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %n.ref: %i32 = name_ref n, %n.loc21
// CHECK:STDOUT: return %n.ref
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Run() -> %i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [template = constants.%Class]
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, @Class.%F.decl [template = constants.%F]
// CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [template = constants.%int_4.1]
// CHECK:STDOUT: %impl.elem0: %Convert.type.2 = interface_witness_access constants.%interface.19, element0 [template = constants.%Convert.10]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_4, %impl.elem0 [template = constants.%Convert.bound]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn]
// CHECK:STDOUT: %int.convert_checked: init %i32 = call %Convert.specific_fn(%int_4) [template = constants.%int_4.2]
// CHECK:STDOUT: %.loc26_18.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_4.2]
// CHECK:STDOUT: %.loc26_18.2: %i32 = converted %int_4, %.loc26_18.1 [template = constants.%int_4.2]
// CHECK:STDOUT: %F.call: init %i32 = call %F.ref(%.loc26_18.2)
// CHECK:STDOUT: %.loc26_20.1: %i32 = value_of_initializer %F.call
// CHECK:STDOUT: %.loc26_20.2: %i32 = converted %F.call, %.loc26_20.1
// CHECK:STDOUT: return %.loc26_20.2
// CHECK:STDOUT: }
// CHECK:STDOUT: