diff --git a/toolchain/check/diagnostic_emitter.cpp b/toolchain/check/diagnostic_emitter.cpp index 0c2070167fa6..49532d45c4cb 100644 --- a/toolchain/check/diagnostic_emitter.cpp +++ b/toolchain/check/diagnostic_emitter.cpp @@ -92,14 +92,7 @@ auto DiagnosticEmitter::ConvertArg(llvm::Any arg) const -> llvm::Any { if (!type_of_expr->inst_id.has_value()) { return ""; } - // TODO: Where possible, produce a better description of the type based on - // the expression. - return "`" + - StringifyConstantInst( - *sem_ir_, - sem_ir_->types().GetTypeInstId( - sem_ir_->insts().Get(type_of_expr->inst_id).type_id())) + - "`"; + return "`" + StringifyTypeOfInst(*sem_ir_, type_of_expr->inst_id) + "`"; } if (auto* expr = llvm::any_cast(&arg)) { return "`" + StringifyConstantInst(*sem_ir_, expr->inst_id) + "`"; diff --git a/toolchain/check/testdata/alias/preserve_in_type_printing.carbon b/toolchain/check/testdata/alias/preserve_in_type_printing.carbon index 1e9b5cc37d82..db6bdd6edb2d 100644 --- a/toolchain/check/testdata/alias/preserve_in_type_printing.carbon +++ b/toolchain/check/testdata/alias/preserve_in_type_printing.carbon @@ -51,3 +51,31 @@ fn H() -> const A* { return; } // CHECK:STDERR: ^~~~~~~~~~~~ // CHECK:STDERR: fn I() -> array(A, 42) { return; } + +// --- fail_alias_in_type_of_expr.carbon + +library "[[@TEST_NAME]]"; + +class C {} +alias A = C; + +fn MakePtr() -> A*; + +// The diagnostics below should describe the types of the expressions using the +// spelling `A` from the declaration of the callee, not the canonical `C`. + +fn F() { + // The type of a call is the declared return type of the callee. + // CHECK:STDERR: fail_alias_in_type_of_expr.carbon:[[@LINE+4]]:3: error: type `A*` does not support qualified expressions [QualifiedExprUnsupported] + // CHECK:STDERR: MakePtr().missing; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + MakePtr().missing; + + // The type of a dereference is the pointee type of the pointer's type. + // CHECK:STDERR: fail_alias_in_type_of_expr.carbon:[[@LINE+4]]:3: error: value of type `A` is not callable [CallToNonCallable] + // CHECK:STDERR: (*MakePtr())(); + // CHECK:STDERR: ^~~~~~~~~~~~~~ + // CHECK:STDERR: + (*MakePtr())(); +} diff --git a/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon b/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon index 93aef73ec5e6..627ee600eca4 100644 --- a/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon +++ b/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon @@ -163,13 +163,14 @@ class FDifferentImplicitParamType { class FDifferentReturnType { impl as J { - // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE+12]]:5: error: cannot implicitly convert expression of type `FDifferentReturnType` to `bool` [ConversionFailure] + // TODO: Include an "aka" in this diagnostic to explain that the type `Self` is `FDifferentReturnType`. + // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE+12]]:5: error: cannot implicitly convert expression of type `Self` to `bool` [ConversionFailure] // CHECK:STDERR: fn F(self: bool, b: bool) -> Self; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE+9]]:5: note: type `FDifferentReturnType` does not implement interface `Core.ImplicitAs(bool)` [MissingImplInMemberAccessInContext] // CHECK:STDERR: fn F(self: bool, b: bool) -> Self; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE-85]]:15: note: while building thunk to match the signature of this function [ThunkSignature] + // CHECK:STDERR: fail_impl_bad_assoc_fn.carbon:[[@LINE-86]]:15: note: while building thunk to match the signature of this function [ThunkSignature] // CHECK:STDERR: interface J { fn F(self: bool, b: bool) -> bool; } // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: @@ -361,12 +362,12 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %pattern_type.b9f: type = pattern_type %FDifferentReturnType [concrete] // CHECK:STDOUT: %return.param_patt.f37: %pattern_type.b9f = out_param_pattern [concrete] // CHECK:STDOUT: %return.patt.e4f: %pattern_type.b9f = return_slot_pattern %return.param_patt.f37, %FDifferentReturnType [concrete] -// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.type.ff55f4.1: type = fn_type @FDifferentReturnType.as.J.impl.F.loc178_38.1 [concrete] +// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.type.ff55f4.1: type = fn_type @FDifferentReturnType.as.J.impl.F.loc179_38.1 [concrete] // CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.9725a5.1: %FDifferentReturnType.as.J.impl.F.type.ff55f4.1 = struct_value () [concrete] // CHECK:STDOUT: %J.facet.6a7: %J.type = facet_value %FDifferentReturnType, (%J.impl_witness.6a4) [concrete] // CHECK:STDOUT: %J.WithSelf.F.type.1a1: type = fn_type @J.WithSelf.F, @J.WithSelf(%J.facet.6a7) [concrete] // CHECK:STDOUT: %J.WithSelf.F.efe: %J.WithSelf.F.type.1a1 = struct_value () [concrete] -// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.type.ff55f4.2: type = fn_type @FDifferentReturnType.as.J.impl.F.loc178_38.2 [concrete] +// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.type.ff55f4.2: type = fn_type @FDifferentReturnType.as.J.impl.F.loc179_38.2 [concrete] // CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.9725a5.2: %FDifferentReturnType.as.J.impl.F.type.ff55f4.2 = struct_value () [concrete] // CHECK:STDOUT: %SelfNested.type: type = facet_type <@SelfNested> [concrete] // CHECK:STDOUT: %Self.e81: %SelfNested.type = symbolic_binding Self, 0 [symbolic] @@ -408,7 +409,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %pattern_type.3a0: type = pattern_type %array_type.291 [concrete] // CHECK:STDOUT: %return.param_patt.489: %pattern_type.3a0 = out_param_pattern [concrete] // CHECK:STDOUT: %return.patt.98a: %pattern_type.3a0 = return_slot_pattern %return.param_patt.489, %array_type.291 [concrete] -// CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.1: type = fn_type @SelfNestedBadParam.as.SelfNested.impl.F.loc195_87.1 [concrete] +// CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.1: type = fn_type @SelfNestedBadParam.as.SelfNested.impl.F.loc196_87.1 [concrete] // CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.5fd896.1: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.1 = struct_value () [concrete] // CHECK:STDOUT: %SelfNested.facet.d0d: %SelfNested.type = facet_value %SelfNestedBadParam, (%SelfNested.impl_witness.09d) [concrete] // CHECK:STDOUT: %SelfNested.WithSelf.F.type.398: type = fn_type @SelfNested.WithSelf.F, @SelfNested.WithSelf(%SelfNested.facet.d0d) [concrete] @@ -419,7 +420,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %pattern_type.94f: type = pattern_type %tuple.type.9ab [concrete] // CHECK:STDOUT: %x.param_patt.7b9: %pattern_type.94f = value_param_pattern [concrete] // CHECK:STDOUT: %x.patt.961: %pattern_type.94f = wrapper_binding_pattern x, %x.param_patt.7b9 [concrete] -// CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.2: type = fn_type @SelfNestedBadParam.as.SelfNested.impl.F.loc195_87.2 [concrete] +// CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.2: type = fn_type @SelfNestedBadParam.as.SelfNested.impl.F.loc196_87.2 [concrete] // CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.5fd896.2: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.2 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.914: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.assoc_type.e23: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%i32) [concrete] @@ -434,7 +435,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %pattern_type.5c2: type = pattern_type %tuple.type.829 [concrete] // CHECK:STDOUT: %x.param_patt.7be: %pattern_type.5c2 = value_param_pattern [concrete] // CHECK:STDOUT: %x.patt.608: %pattern_type.5c2 = wrapper_binding_pattern x, %x.param_patt.7be [concrete] -// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.1: type = fn_type @SelfNestedBadReturnType.as.SelfNested.impl.F.loc211_112.1 [concrete] +// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.1: type = fn_type @SelfNestedBadReturnType.as.SelfNested.impl.F.loc212_112.1 [concrete] // CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.5a7d54.1: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.1 = struct_value () [concrete] // CHECK:STDOUT: %SelfNested.facet.e71: %SelfNested.type = facet_value %SelfNestedBadReturnType, (%SelfNested.impl_witness.849) [concrete] // CHECK:STDOUT: %SelfNested.WithSelf.F.type.20c: type = fn_type @SelfNested.WithSelf.F, @SelfNested.WithSelf(%SelfNested.facet.e71) [concrete] @@ -444,7 +445,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %pattern_type.f0d: type = pattern_type %array_type.a08 [concrete] // CHECK:STDOUT: %return.param_patt.039: %pattern_type.f0d = out_param_pattern [concrete] // CHECK:STDOUT: %return.patt.3c4: %pattern_type.f0d = return_slot_pattern %return.param_patt.039, %array_type.a08 [concrete] -// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.2: type = fn_type @SelfNestedBadReturnType.as.SelfNested.impl.F.loc211_112.2 [concrete] +// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.2: type = fn_type @SelfNestedBadReturnType.as.SelfNested.impl.F.loc212_112.2 [concrete] // CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.5a7d54.2: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.2 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -559,34 +560,34 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: // CHECK:STDOUT: !with Self: // CHECK:STDOUT: %SelfNested.WithSelf.F.decl: @SelfNested.WithSelf.%SelfNested.WithSelf.F.type (%SelfNested.WithSelf.F.type.702) = fn_decl @SelfNested.WithSelf.F [symbolic = @SelfNested.WithSelf.%SelfNested.WithSelf.F (constants.%SelfNested.WithSelf.F.eec)] { -// CHECK:STDOUT: %x.param_patt.loc183_9.1: @SelfNested.WithSelf.F.%pattern_type.loc183_9 (%pattern_type.60a) = value_param_pattern [symbolic = %x.param_patt.loc183_9.2 (constants.%x.param_patt.e85)] -// CHECK:STDOUT: %x.patt.loc183_9.1: @SelfNested.WithSelf.F.%pattern_type.loc183_9 (%pattern_type.60a) = wrapper_binding_pattern x, %x.param_patt.loc183_9.1 [symbolic = %x.patt.loc183_9.2 (constants.%x.patt.6af)] -// CHECK:STDOUT: %return.param_patt.loc183_57.1: @SelfNested.WithSelf.F.%pattern_type.loc183_57 (%pattern_type.2ab) = out_param_pattern [symbolic = %return.param_patt.loc183_57.2 (constants.%return.param_patt.439)] -// CHECK:STDOUT: %return.patt.loc183_41.1: @SelfNested.WithSelf.F.%pattern_type.loc183_57 (%pattern_type.2ab) = return_slot_pattern %return.param_patt.loc183_57.1, %array_type.loc183_57.2 [symbolic = %return.patt.loc183_41.2 (constants.%return.patt.869)] +// CHECK:STDOUT: %x.param_patt.loc184_9.1: @SelfNested.WithSelf.F.%pattern_type.loc184_9 (%pattern_type.60a) = value_param_pattern [symbolic = %x.param_patt.loc184_9.2 (constants.%x.param_patt.e85)] +// CHECK:STDOUT: %x.patt.loc184_9.1: @SelfNested.WithSelf.F.%pattern_type.loc184_9 (%pattern_type.60a) = wrapper_binding_pattern x, %x.param_patt.loc184_9.1 [symbolic = %x.patt.loc184_9.2 (constants.%x.patt.6af)] +// CHECK:STDOUT: %return.param_patt.loc184_57.1: @SelfNested.WithSelf.F.%pattern_type.loc184_57 (%pattern_type.2ab) = out_param_pattern [symbolic = %return.param_patt.loc184_57.2 (constants.%return.param_patt.439)] +// CHECK:STDOUT: %return.patt.loc184_41.1: @SelfNested.WithSelf.F.%pattern_type.loc184_57 (%pattern_type.2ab) = return_slot_pattern %return.param_patt.loc184_57.1, %array_type.loc184_57.2 [symbolic = %return.patt.loc184_41.2 (constants.%return.patt.869)] // CHECK:STDOUT: } { -// CHECK:STDOUT: %Self.ref.loc183_50: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.e81)] +// CHECK:STDOUT: %Self.ref.loc184_50: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.e81)] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4] -// CHECK:STDOUT: %Self.as_type.loc183_50: type = facet_access_type %Self.ref.loc183_50 [symbolic = %Self.as_type.loc183_16.1 (constants.%Self.as_type.8ab)] -// CHECK:STDOUT: %.loc183_50: type = converted %Self.ref.loc183_50, %Self.as_type.loc183_50 [symbolic = %Self.as_type.loc183_16.1 (constants.%Self.as_type.8ab)] -// CHECK:STDOUT: %array_type.loc183_57.2: type = array_type %int_4, %.loc183_50 [symbolic = %array_type.loc183_57.1 (constants.%array_type.4e4)] -// CHECK:STDOUT: %.loc183_57.2: Core.Form = init_form %array_type.loc183_57.2 [symbolic = %.loc183_57.1 (constants.%.f45)] +// CHECK:STDOUT: %Self.as_type.loc184_50: type = facet_access_type %Self.ref.loc184_50 [symbolic = %Self.as_type.loc184_16.1 (constants.%Self.as_type.8ab)] +// CHECK:STDOUT: %.loc184_50: type = converted %Self.ref.loc184_50, %Self.as_type.loc184_50 [symbolic = %Self.as_type.loc184_16.1 (constants.%Self.as_type.8ab)] +// CHECK:STDOUT: %array_type.loc184_57.2: type = array_type %int_4, %.loc184_50 [symbolic = %array_type.loc184_57.1 (constants.%array_type.4e4)] +// CHECK:STDOUT: %.loc184_57.2: Core.Form = init_form %array_type.loc184_57.2 [symbolic = %.loc184_57.1 (constants.%.f45)] // CHECK:STDOUT: %x.param: @SelfNested.WithSelf.F.%tuple.type (%tuple.type.c49) = value_param call_param0 -// CHECK:STDOUT: %.loc183_38.1: type = splice_block %.loc183_38.3 [symbolic = %tuple.type (constants.%tuple.type.c49)] { -// CHECK:STDOUT: %Self.ref.loc183_12: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.e81)] -// CHECK:STDOUT: %Self.as_type.loc183_16.2: type = facet_access_type %Self.ref.loc183_12 [symbolic = %Self.as_type.loc183_16.1 (constants.%Self.as_type.8ab)] -// CHECK:STDOUT: %.loc183_16: type = converted %Self.ref.loc183_12, %Self.as_type.loc183_16.2 [symbolic = %Self.as_type.loc183_16.1 (constants.%Self.as_type.8ab)] -// CHECK:STDOUT: %ptr.loc183_16.2: type = ptr_type %.loc183_16 [symbolic = %ptr.loc183_16.1 (constants.%ptr.a16)] -// CHECK:STDOUT: %Self.ref.loc183_24: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.e81)] -// CHECK:STDOUT: %Self.as_type.loc183_24: type = facet_access_type %Self.ref.loc183_24 [symbolic = %Self.as_type.loc183_16.1 (constants.%Self.as_type.8ab)] -// CHECK:STDOUT: %.loc183_24: type = converted %Self.ref.loc183_24, %Self.as_type.loc183_24 [symbolic = %Self.as_type.loc183_16.1 (constants.%Self.as_type.8ab)] +// CHECK:STDOUT: %.loc184_38.1: type = splice_block %.loc184_38.3 [symbolic = %tuple.type (constants.%tuple.type.c49)] { +// CHECK:STDOUT: %Self.ref.loc184_12: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.e81)] +// CHECK:STDOUT: %Self.as_type.loc184_16.2: type = facet_access_type %Self.ref.loc184_12 [symbolic = %Self.as_type.loc184_16.1 (constants.%Self.as_type.8ab)] +// CHECK:STDOUT: %.loc184_16: type = converted %Self.ref.loc184_12, %Self.as_type.loc184_16.2 [symbolic = %Self.as_type.loc184_16.1 (constants.%Self.as_type.8ab)] +// CHECK:STDOUT: %ptr.loc184_16.2: type = ptr_type %.loc184_16 [symbolic = %ptr.loc184_16.1 (constants.%ptr.a16)] +// CHECK:STDOUT: %Self.ref.loc184_24: %SelfNested.type = name_ref Self, @SelfNested.%Self [symbolic = %Self (constants.%Self.e81)] +// CHECK:STDOUT: %Self.as_type.loc184_24: type = facet_access_type %Self.ref.loc184_24 [symbolic = %Self.as_type.loc184_16.1 (constants.%Self.as_type.8ab)] +// CHECK:STDOUT: %.loc184_24: type = converted %Self.ref.loc184_24, %Self.as_type.loc184_24 [symbolic = %Self.as_type.loc184_16.1 (constants.%Self.as_type.8ab)] // CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %struct_type.x.y.loc183_37.2: type = struct_type {.x: @SelfNested.WithSelf.F.%Self.as_type.loc183_16.1 (%Self.as_type.8ab), .y: %i32} [symbolic = %struct_type.x.y.loc183_37.1 (constants.%struct_type.x.y.4c5)] -// CHECK:STDOUT: %.loc183_38.2: %tuple.type.24b = tuple_literal (%ptr.loc183_16.2, %struct_type.x.y.loc183_37.2) [symbolic = %tuple (constants.%tuple.b6a)] -// CHECK:STDOUT: %.loc183_38.3: type = converted %.loc183_38.2, constants.%tuple.type.c49 [symbolic = %tuple.type (constants.%tuple.type.c49)] +// CHECK:STDOUT: %struct_type.x.y.loc184_37.2: type = struct_type {.x: @SelfNested.WithSelf.F.%Self.as_type.loc184_16.1 (%Self.as_type.8ab), .y: %i32} [symbolic = %struct_type.x.y.loc184_37.1 (constants.%struct_type.x.y.4c5)] +// CHECK:STDOUT: %.loc184_38.2: %tuple.type.24b = tuple_literal (%ptr.loc184_16.2, %struct_type.x.y.loc184_37.2) [symbolic = %tuple (constants.%tuple.b6a)] +// CHECK:STDOUT: %.loc184_38.3: type = converted %.loc184_38.2, constants.%tuple.type.c49 [symbolic = %tuple.type (constants.%tuple.type.c49)] // CHECK:STDOUT: } // CHECK:STDOUT: %x: @SelfNested.WithSelf.F.%tuple.type (%tuple.type.c49) = wrapper_binding x, %x.param -// CHECK:STDOUT: %return.param: ref @SelfNested.WithSelf.F.%array_type.loc183_57.1 (%array_type.4e4) = out_param call_param1 -// CHECK:STDOUT: %return: ref @SelfNested.WithSelf.F.%array_type.loc183_57.1 (%array_type.4e4) = return_slot %return.param +// CHECK:STDOUT: %return.param: ref @SelfNested.WithSelf.F.%array_type.loc184_57.1 (%array_type.4e4) = out_param call_param1 +// CHECK:STDOUT: %return: ref @SelfNested.WithSelf.F.%array_type.loc184_57.1 (%array_type.4e4) = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0: %SelfNested.assoc_type = assoc_entity element0, %SelfNested.WithSelf.F.decl [concrete = constants.%assoc0.219] // CHECK:STDOUT: @@ -888,7 +889,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: impl @FDifferentReturnType.as.J.impl: %Self.ref as %J.ref { -// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.decl.loc178_38.1: %FDifferentReturnType.as.J.impl.F.type.ff55f4.1 = fn_decl @FDifferentReturnType.as.J.impl.F.loc178_38.1 [concrete = constants.%FDifferentReturnType.as.J.impl.F.9725a5.1] { +// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.decl.loc179_38.1: %FDifferentReturnType.as.J.impl.F.type.ff55f4.1 = fn_decl @FDifferentReturnType.as.J.impl.F.loc179_38.1 [concrete = constants.%FDifferentReturnType.as.J.impl.F.9725a5.1] { // CHECK:STDOUT: %self.param_patt: %pattern_type.831 = value_param_pattern [concrete = constants.%self.param_patt.210] // CHECK:STDOUT: %self.patt: %pattern_type.831 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.3a9] // CHECK:STDOUT: %b.param_patt: %pattern_type.831 = value_param_pattern [concrete = constants.%b.param_patt.792] @@ -897,19 +898,19 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %return.patt: %pattern_type.b9f = return_slot_pattern %return.param_patt, %Self.ref [concrete = constants.%return.patt.e4f] // CHECK:STDOUT: } { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FDifferentReturnType [concrete = constants.%FDifferentReturnType] -// CHECK:STDOUT: %.loc178_34: Core.Form = init_form %Self.ref [concrete = constants.%.1f5] +// CHECK:STDOUT: %.loc179_34: Core.Form = init_form %Self.ref [concrete = constants.%.1f5] // CHECK:STDOUT: %self.param: bool = value_param call_param0 -// CHECK:STDOUT: %.loc178_16: type = type_literal bool [concrete = bool] +// CHECK:STDOUT: %.loc179_16: type = type_literal bool [concrete = bool] // CHECK:STDOUT: %self: bool = wrapper_binding self, %self.param // CHECK:STDOUT: %b.param: bool = value_param call_param1 -// CHECK:STDOUT: %.loc178_25: type = type_literal bool [concrete = bool] +// CHECK:STDOUT: %.loc179_25: type = type_literal bool [concrete = bool] // CHECK:STDOUT: %b: bool = wrapper_binding b, %b.param // CHECK:STDOUT: %return.param: ref %FDifferentReturnType = out_param call_param2 // CHECK:STDOUT: %return: ref %FDifferentReturnType = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: %.loc87_44.1: type = specific_constant @J.WithSelf.F.%.loc87_44.1, @J.WithSelf.F(constants.%J.facet.6a7) [concrete = bool] // CHECK:STDOUT: %.loc87_44.2: Core.Form = specific_constant @J.WithSelf.F.%.loc87_44.2, @J.WithSelf.F(constants.%J.facet.6a7) [concrete = constants.%.f34] -// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.decl.loc178_38.2: %FDifferentReturnType.as.J.impl.F.type.ff55f4.2 = fn_decl @FDifferentReturnType.as.J.impl.F.loc178_38.2 [concrete = constants.%FDifferentReturnType.as.J.impl.F.9725a5.2] { +// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.decl.loc179_38.2: %FDifferentReturnType.as.J.impl.F.type.ff55f4.2 = fn_decl @FDifferentReturnType.as.J.impl.F.loc179_38.2 [concrete = constants.%FDifferentReturnType.as.J.impl.F.9725a5.2] { // CHECK:STDOUT: %.1: %pattern_type.831 = specific_constant constants.%self.param_patt.210, @J.WithSelf.F(constants.%J.facet.6a7) [concrete = constants.%self.param_patt.210] // CHECK:STDOUT: %self.patt: %pattern_type.831 = wrapper_binding_pattern self, %.1 [concrete = constants.%self.patt.3a9] // CHECK:STDOUT: %.2: %pattern_type.831 = specific_constant constants.%b.param_patt.792, @J.WithSelf.F(constants.%J.facet.6a7) [concrete = constants.%b.param_patt.792] @@ -923,43 +924,43 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %return.param: ref bool = out_param call_param2 // CHECK:STDOUT: %return: ref bool = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (%FDifferentReturnType.as.J.impl.F.decl.loc178_38.2), @FDifferentReturnType.as.J.impl [concrete] +// CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (%FDifferentReturnType.as.J.impl.F.decl.loc179_38.2), @FDifferentReturnType.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness.6a4] // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .F = %FDifferentReturnType.as.J.impl.F.decl.loc178_38.1 +// CHECK:STDOUT: .F = %FDifferentReturnType.as.J.impl.F.decl.loc179_38.1 // CHECK:STDOUT: extend %J.ref // CHECK:STDOUT: witness = %J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: impl @SelfNestedBadParam.as.SelfNested.impl: %Self.ref as %SelfNested.ref { -// CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.decl.loc195_87.1: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.1 = fn_decl @SelfNestedBadParam.as.SelfNested.impl.F.loc195_87.1 [concrete = constants.%SelfNestedBadParam.as.SelfNested.impl.F.5fd896.1] { +// CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.decl.loc196_87.1: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.1 = fn_decl @SelfNestedBadParam.as.SelfNested.impl.F.loc196_87.1 [concrete = constants.%SelfNestedBadParam.as.SelfNested.impl.F.5fd896.1] { // CHECK:STDOUT: %x.param_patt: %pattern_type.a68 = value_param_pattern [concrete = constants.%x.param_patt.140] // CHECK:STDOUT: %x.patt: %pattern_type.a68 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt.870] // CHECK:STDOUT: %return.param_patt: %pattern_type.3a0 = out_param_pattern [concrete = constants.%return.param_patt.489] // CHECK:STDOUT: %return.patt: %pattern_type.3a0 = return_slot_pattern %return.param_patt, %array_type [concrete = constants.%return.patt.98a] // CHECK:STDOUT: } { -// CHECK:STDOUT: %SelfNestedBadParam.ref.loc195_65: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [concrete = constants.%SelfNestedBadParam] +// CHECK:STDOUT: %SelfNestedBadParam.ref.loc196_65: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [concrete = constants.%SelfNestedBadParam] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4] -// CHECK:STDOUT: %array_type: type = array_type %int_4, %SelfNestedBadParam.ref.loc195_65 [concrete = constants.%array_type.291] -// CHECK:STDOUT: %.loc195_86: Core.Form = init_form %array_type [concrete = constants.%.cc2] +// CHECK:STDOUT: %array_type: type = array_type %int_4, %SelfNestedBadParam.ref.loc196_65 [concrete = constants.%array_type.291] +// CHECK:STDOUT: %.loc196_86: Core.Form = init_form %array_type [concrete = constants.%.cc2] // CHECK:STDOUT: %x.param: %tuple.type.e57 = value_param call_param0 -// CHECK:STDOUT: %.loc195_53.1: type = splice_block %.loc195_53.3 [concrete = constants.%tuple.type.e57] { -// CHECK:STDOUT: %SelfNestedBadParam.ref.loc195_14: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [concrete = constants.%SelfNestedBadParam] -// CHECK:STDOUT: %ptr: type = ptr_type %SelfNestedBadParam.ref.loc195_14 [concrete = constants.%ptr.52e] -// CHECK:STDOUT: %i32.loc195_40: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %i32.loc195_49: type = type_literal constants.%i32 [concrete = constants.%i32] +// CHECK:STDOUT: %.loc196_53.1: type = splice_block %.loc196_53.3 [concrete = constants.%tuple.type.e57] { +// CHECK:STDOUT: %SelfNestedBadParam.ref.loc196_14: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [concrete = constants.%SelfNestedBadParam] +// CHECK:STDOUT: %ptr: type = ptr_type %SelfNestedBadParam.ref.loc196_14 [concrete = constants.%ptr.52e] +// CHECK:STDOUT: %i32.loc196_40: type = type_literal constants.%i32 [concrete = constants.%i32] +// CHECK:STDOUT: %i32.loc196_49: type = type_literal constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %struct_type.x.y: type = struct_type {.x: %i32, .y: %i32} [concrete = constants.%struct_type.x.y.fb8] -// CHECK:STDOUT: %.loc195_53.2: %tuple.type.24b = tuple_literal (%ptr, %struct_type.x.y) [concrete = constants.%tuple.991] -// CHECK:STDOUT: %.loc195_53.3: type = converted %.loc195_53.2, constants.%tuple.type.e57 [concrete = constants.%tuple.type.e57] +// CHECK:STDOUT: %.loc196_53.2: %tuple.type.24b = tuple_literal (%ptr, %struct_type.x.y) [concrete = constants.%tuple.991] +// CHECK:STDOUT: %.loc196_53.3: type = converted %.loc196_53.2, constants.%tuple.type.e57 [concrete = constants.%tuple.type.e57] // CHECK:STDOUT: } // CHECK:STDOUT: %x: %tuple.type.e57 = wrapper_binding x, %x.param // CHECK:STDOUT: %return.param: ref %array_type.291 = out_param call_param1 // CHECK:STDOUT: %return: ref %array_type.291 = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc183_57.1: type = specific_constant @SelfNested.WithSelf.F.%array_type.loc183_57.2, @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d) [concrete = constants.%array_type.291] -// CHECK:STDOUT: %.loc183_57.2: Core.Form = specific_constant @SelfNested.WithSelf.F.%.loc183_57.2, @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d) [concrete = constants.%.cc2] -// CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.decl.loc195_87.2: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.2 = fn_decl @SelfNestedBadParam.as.SelfNested.impl.F.loc195_87.2 [concrete = constants.%SelfNestedBadParam.as.SelfNested.impl.F.5fd896.2] { +// CHECK:STDOUT: %.loc184_57.1: type = specific_constant @SelfNested.WithSelf.F.%array_type.loc184_57.2, @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d) [concrete = constants.%array_type.291] +// CHECK:STDOUT: %.loc184_57.2: Core.Form = specific_constant @SelfNested.WithSelf.F.%.loc184_57.2, @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d) [concrete = constants.%.cc2] +// CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.decl.loc196_87.2: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.2 = fn_decl @SelfNestedBadParam.as.SelfNested.impl.F.loc196_87.2 [concrete = constants.%SelfNestedBadParam.as.SelfNested.impl.F.5fd896.2] { // CHECK:STDOUT: %.1: %pattern_type.94f = specific_constant constants.%x.param_patt.7b9, @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d) [concrete = constants.%x.param_patt.7b9] // CHECK:STDOUT: %x.patt: %pattern_type.94f = wrapper_binding_pattern x, %.1 [concrete = constants.%x.patt.961] // CHECK:STDOUT: %.2: %pattern_type.3a0 = specific_constant constants.%return.patt.98a, @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d) [concrete = constants.%return.patt.98a] @@ -969,18 +970,18 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %return.param: ref %array_type.291 = out_param call_param1 // CHECK:STDOUT: %return: ref %array_type.291 = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %SelfNested.impl_witness_table = impl_witness_table (%SelfNestedBadParam.as.SelfNested.impl.F.decl.loc195_87.2), @SelfNestedBadParam.as.SelfNested.impl [concrete] +// CHECK:STDOUT: %SelfNested.impl_witness_table = impl_witness_table (%SelfNestedBadParam.as.SelfNested.impl.F.decl.loc196_87.2), @SelfNestedBadParam.as.SelfNested.impl [concrete] // CHECK:STDOUT: %SelfNested.impl_witness: = impl_witness %SelfNested.impl_witness_table [concrete = constants.%SelfNested.impl_witness.09d] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .SelfNestedBadParam = -// CHECK:STDOUT: .F = %SelfNestedBadParam.as.SelfNested.impl.F.decl.loc195_87.1 +// CHECK:STDOUT: .F = %SelfNestedBadParam.as.SelfNested.impl.F.decl.loc196_87.1 // CHECK:STDOUT: extend %SelfNested.ref // CHECK:STDOUT: witness = %SelfNested.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: impl @SelfNestedBadReturnType.as.SelfNested.impl: %Self.ref as %SelfNested.ref { -// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc211_112.1: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.1 = fn_decl @SelfNestedBadReturnType.as.SelfNested.impl.F.loc211_112.1 [concrete = constants.%SelfNestedBadReturnType.as.SelfNested.impl.F.5a7d54.1] { +// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc212_112.1: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.1 = fn_decl @SelfNestedBadReturnType.as.SelfNested.impl.F.loc212_112.1 [concrete = constants.%SelfNestedBadReturnType.as.SelfNested.impl.F.5a7d54.1] { // CHECK:STDOUT: %x.param_patt: %pattern_type.5c2 = value_param_pattern [concrete = constants.%x.param_patt.7be] // CHECK:STDOUT: %x.patt: %pattern_type.5c2 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt.608] // CHECK:STDOUT: %return.param_patt: %pattern_type.3a0 = out_param_pattern [concrete = constants.%return.param_patt.489] @@ -989,24 +990,24 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %SelfNestedBadParam.ref: type = name_ref SelfNestedBadParam, file.%SelfNestedBadParam.decl [concrete = constants.%SelfNestedBadParam] // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4] // CHECK:STDOUT: %array_type: type = array_type %int_4, %SelfNestedBadParam.ref [concrete = constants.%array_type.291] -// CHECK:STDOUT: %.loc211_111: Core.Form = init_form %array_type [concrete = constants.%.cc2] +// CHECK:STDOUT: %.loc212_111: Core.Form = init_form %array_type [concrete = constants.%.cc2] // CHECK:STDOUT: %x.param: %tuple.type.829 = value_param call_param0 -// CHECK:STDOUT: %.loc211_78.1: type = splice_block %.loc211_78.3 [concrete = constants.%tuple.type.829] { -// CHECK:STDOUT: %SelfNestedBadReturnType.ref.loc211_14: type = name_ref SelfNestedBadReturnType, file.%SelfNestedBadReturnType.decl [concrete = constants.%SelfNestedBadReturnType] -// CHECK:STDOUT: %ptr: type = ptr_type %SelfNestedBadReturnType.ref.loc211_14 [concrete = constants.%ptr.f55] -// CHECK:STDOUT: %SelfNestedBadReturnType.ref.loc211_45: type = name_ref SelfNestedBadReturnType, file.%SelfNestedBadReturnType.decl [concrete = constants.%SelfNestedBadReturnType] +// CHECK:STDOUT: %.loc212_78.1: type = splice_block %.loc212_78.3 [concrete = constants.%tuple.type.829] { +// CHECK:STDOUT: %SelfNestedBadReturnType.ref.loc212_14: type = name_ref SelfNestedBadReturnType, file.%SelfNestedBadReturnType.decl [concrete = constants.%SelfNestedBadReturnType] +// CHECK:STDOUT: %ptr: type = ptr_type %SelfNestedBadReturnType.ref.loc212_14 [concrete = constants.%ptr.f55] +// CHECK:STDOUT: %SelfNestedBadReturnType.ref.loc212_45: type = name_ref SelfNestedBadReturnType, file.%SelfNestedBadReturnType.decl [concrete = constants.%SelfNestedBadReturnType] // CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %struct_type.x.y: type = struct_type {.x: %SelfNestedBadReturnType, .y: %i32} [concrete = constants.%struct_type.x.y.f6a] -// CHECK:STDOUT: %.loc211_78.2: %tuple.type.24b = tuple_literal (%ptr, %struct_type.x.y) [concrete = constants.%tuple.96d] -// CHECK:STDOUT: %.loc211_78.3: type = converted %.loc211_78.2, constants.%tuple.type.829 [concrete = constants.%tuple.type.829] +// CHECK:STDOUT: %.loc212_78.2: %tuple.type.24b = tuple_literal (%ptr, %struct_type.x.y) [concrete = constants.%tuple.96d] +// CHECK:STDOUT: %.loc212_78.3: type = converted %.loc212_78.2, constants.%tuple.type.829 [concrete = constants.%tuple.type.829] // CHECK:STDOUT: } // CHECK:STDOUT: %x: %tuple.type.829 = wrapper_binding x, %x.param // CHECK:STDOUT: %return.param: ref %array_type.291 = out_param call_param1 // CHECK:STDOUT: %return: ref %array_type.291 = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc183_57.1: type = specific_constant @SelfNested.WithSelf.F.%array_type.loc183_57.2, @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71) [concrete = constants.%array_type.a08] -// CHECK:STDOUT: %.loc183_57.2: Core.Form = specific_constant @SelfNested.WithSelf.F.%.loc183_57.2, @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71) [concrete = constants.%.442] -// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc211_112.2: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.2 = fn_decl @SelfNestedBadReturnType.as.SelfNested.impl.F.loc211_112.2 [concrete = constants.%SelfNestedBadReturnType.as.SelfNested.impl.F.5a7d54.2] { +// CHECK:STDOUT: %.loc184_57.1: type = specific_constant @SelfNested.WithSelf.F.%array_type.loc184_57.2, @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71) [concrete = constants.%array_type.a08] +// CHECK:STDOUT: %.loc184_57.2: Core.Form = specific_constant @SelfNested.WithSelf.F.%.loc184_57.2, @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71) [concrete = constants.%.442] +// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc212_112.2: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.2 = fn_decl @SelfNestedBadReturnType.as.SelfNested.impl.F.loc212_112.2 [concrete = constants.%SelfNestedBadReturnType.as.SelfNested.impl.F.5a7d54.2] { // CHECK:STDOUT: %.1: %pattern_type.5c2 = specific_constant constants.%x.param_patt.7be, @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71) [concrete = constants.%x.param_patt.7be] // CHECK:STDOUT: %x.patt: %pattern_type.5c2 = wrapper_binding_pattern x, %.1 [concrete = constants.%x.patt.608] // CHECK:STDOUT: %.2: %pattern_type.f0d = specific_constant constants.%return.patt.3c4, @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71) [concrete = constants.%return.patt.3c4] @@ -1016,13 +1017,13 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %return.param: ref %array_type.a08 = out_param call_param1 // CHECK:STDOUT: %return: ref %array_type.a08 = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %SelfNested.impl_witness_table = impl_witness_table (%SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc211_112.2), @SelfNestedBadReturnType.as.SelfNested.impl [concrete] +// CHECK:STDOUT: %SelfNested.impl_witness_table = impl_witness_table (%SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc212_112.2), @SelfNestedBadReturnType.as.SelfNested.impl [concrete] // CHECK:STDOUT: %SelfNested.impl_witness: = impl_witness %SelfNested.impl_witness_table [concrete = constants.%SelfNested.impl_witness.849] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .SelfNestedBadReturnType = // CHECK:STDOUT: .SelfNestedBadParam = -// CHECK:STDOUT: .F = %SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc211_112.1 +// CHECK:STDOUT: .F = %SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc212_112.1 // CHECK:STDOUT: extend %SelfNested.ref // CHECK:STDOUT: witness = %SelfNested.impl_witness // CHECK:STDOUT: } @@ -1188,7 +1189,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SelfNestedBadParam [concrete = constants.%SelfNestedBadParam] // CHECK:STDOUT: %SelfNested.ref: type = name_ref SelfNested, file.%SelfNested.decl [concrete = constants.%SelfNested.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc187: = impl_self_witness @SelfNestedBadParam.as.SelfNested.impl.%Self.ref, @SelfNested [concrete = constants.%.83b] +// CHECK:STDOUT: %.loc188: = impl_self_witness @SelfNestedBadParam.as.SelfNested.impl.%Self.ref, @SelfNested [concrete = constants.%.83b] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -1203,7 +1204,7 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SelfNestedBadReturnType [concrete = constants.%SelfNestedBadReturnType] // CHECK:STDOUT: %SelfNested.ref: type = name_ref SelfNested, file.%SelfNested.decl [concrete = constants.%SelfNested.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc200: = impl_self_witness @SelfNestedBadReturnType.as.SelfNested.impl.%Self.ref, @SelfNested [concrete = constants.%.020] +// CHECK:STDOUT: %.loc201: = impl_self_witness @SelfNestedBadReturnType.as.SelfNested.impl.%Self.ref, @SelfNested [concrete = constants.%.020] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -1297,42 +1298,42 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return %FDifferentImplicitParamType.as.J.impl.F.call // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @FDifferentReturnType.as.J.impl.F.loc178_38.1(%self.param: bool, %b.param: bool) -> out %return.param: %FDifferentReturnType; +// CHECK:STDOUT: fn @FDifferentReturnType.as.J.impl.F.loc179_38.1(%self.param: bool, %b.param: bool) -> out %return.param: %FDifferentReturnType; // CHECK:STDOUT: -// CHECK:STDOUT: fn @FDifferentReturnType.as.J.impl.F.loc178_38.2(%self.param: bool, %b.param: bool) -> out %return.param: bool [thunk @FDifferentReturnType.as.J.impl.%FDifferentReturnType.as.J.impl.F.decl.loc178_38.1 for @J.WithSelf.%J.WithSelf.F.decl, @J.WithSelf.F(constants.%J.facet.6a7)] { +// CHECK:STDOUT: fn @FDifferentReturnType.as.J.impl.F.loc179_38.2(%self.param: bool, %b.param: bool) -> out %return.param: bool [thunk @FDifferentReturnType.as.J.impl.%FDifferentReturnType.as.J.impl.F.decl.loc179_38.1 for @J.WithSelf.%J.WithSelf.F.decl, @J.WithSelf.F(constants.%J.facet.6a7)] { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %F.ref: %FDifferentReturnType.as.J.impl.F.type.ff55f4.1 = name_ref F, @FDifferentReturnType.as.J.impl.%FDifferentReturnType.as.J.impl.F.decl.loc178_38.1 [concrete = constants.%FDifferentReturnType.as.J.impl.F.9725a5.1] +// CHECK:STDOUT: %F.ref: %FDifferentReturnType.as.J.impl.F.type.ff55f4.1 = name_ref F, @FDifferentReturnType.as.J.impl.%FDifferentReturnType.as.J.impl.F.decl.loc179_38.1 [concrete = constants.%FDifferentReturnType.as.J.impl.F.9725a5.1] // CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.bound: = bound_method %self.param, %F.ref -// CHECK:STDOUT: %.loc178_38.1: ref %FDifferentReturnType = temporary_storage -// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.call: init %FDifferentReturnType to %.loc178_38.1 = call %FDifferentReturnType.as.J.impl.F.bound(%self.param, %b.param) -// CHECK:STDOUT: %.loc178_38.2: bool = converted %FDifferentReturnType.as.J.impl.F.call, [concrete = ] +// CHECK:STDOUT: %.loc179_38.1: ref %FDifferentReturnType = temporary_storage +// CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.call: init %FDifferentReturnType to %.loc179_38.1 = call %FDifferentReturnType.as.J.impl.F.bound(%self.param, %b.param) +// CHECK:STDOUT: %.loc179_38.2: bool = converted %FDifferentReturnType.as.J.impl.F.call, [concrete = ] // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @SelfNested.WithSelf.F(@SelfNested.%Self: %SelfNested.type) { // CHECK:STDOUT: %Self: %SelfNested.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.e81)] -// CHECK:STDOUT: %Self.as_type.loc183_16.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc183_16.1 (constants.%Self.as_type.8ab)] -// CHECK:STDOUT: %ptr.loc183_16.1: type = ptr_type %Self.as_type.loc183_16.1 [symbolic = %ptr.loc183_16.1 (constants.%ptr.a16)] -// CHECK:STDOUT: %struct_type.x.y.loc183_37.1: type = struct_type {.x: @SelfNested.WithSelf.F.%Self.as_type.loc183_16.1 (%Self.as_type.8ab), .y: %i32} [symbolic = %struct_type.x.y.loc183_37.1 (constants.%struct_type.x.y.4c5)] -// CHECK:STDOUT: %tuple: %tuple.type.24b = tuple_value (%ptr.loc183_16.1, %struct_type.x.y.loc183_37.1) [symbolic = %tuple (constants.%tuple.b6a)] -// CHECK:STDOUT: %tuple.type: type = tuple_type (%ptr.loc183_16.1, %struct_type.x.y.loc183_37.1) [symbolic = %tuple.type (constants.%tuple.type.c49)] -// CHECK:STDOUT: %pattern_type.loc183_9: type = pattern_type %tuple.type [symbolic = %pattern_type.loc183_9 (constants.%pattern_type.60a)] -// CHECK:STDOUT: %x.param_patt.loc183_9.2: @SelfNested.WithSelf.F.%pattern_type.loc183_9 (%pattern_type.60a) = value_param_pattern [symbolic = %x.param_patt.loc183_9.2 (constants.%x.param_patt.e85)] -// CHECK:STDOUT: %x.patt.loc183_9.2: @SelfNested.WithSelf.F.%pattern_type.loc183_9 (%pattern_type.60a) = wrapper_binding_pattern x, %x.param_patt.loc183_9.2 [symbolic = %x.patt.loc183_9.2 (constants.%x.patt.6af)] -// CHECK:STDOUT: %array_type.loc183_57.1: type = array_type constants.%int_4, %Self.as_type.loc183_16.1 [symbolic = %array_type.loc183_57.1 (constants.%array_type.4e4)] -// CHECK:STDOUT: %.loc183_57.1: Core.Form = init_form %array_type.loc183_57.1 [symbolic = %.loc183_57.1 (constants.%.f45)] -// CHECK:STDOUT: %pattern_type.loc183_57: type = pattern_type %array_type.loc183_57.1 [symbolic = %pattern_type.loc183_57 (constants.%pattern_type.2ab)] -// CHECK:STDOUT: %return.param_patt.loc183_57.2: @SelfNested.WithSelf.F.%pattern_type.loc183_57 (%pattern_type.2ab) = out_param_pattern [symbolic = %return.param_patt.loc183_57.2 (constants.%return.param_patt.439)] -// CHECK:STDOUT: %return.patt.loc183_41.2: @SelfNested.WithSelf.F.%pattern_type.loc183_57 (%pattern_type.2ab) = return_slot_pattern %return.param_patt.loc183_57.2, %array_type.loc183_57.1 [symbolic = %return.patt.loc183_41.2 (constants.%return.patt.869)] +// CHECK:STDOUT: %Self.as_type.loc184_16.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc184_16.1 (constants.%Self.as_type.8ab)] +// CHECK:STDOUT: %ptr.loc184_16.1: type = ptr_type %Self.as_type.loc184_16.1 [symbolic = %ptr.loc184_16.1 (constants.%ptr.a16)] +// CHECK:STDOUT: %struct_type.x.y.loc184_37.1: type = struct_type {.x: @SelfNested.WithSelf.F.%Self.as_type.loc184_16.1 (%Self.as_type.8ab), .y: %i32} [symbolic = %struct_type.x.y.loc184_37.1 (constants.%struct_type.x.y.4c5)] +// CHECK:STDOUT: %tuple: %tuple.type.24b = tuple_value (%ptr.loc184_16.1, %struct_type.x.y.loc184_37.1) [symbolic = %tuple (constants.%tuple.b6a)] +// CHECK:STDOUT: %tuple.type: type = tuple_type (%ptr.loc184_16.1, %struct_type.x.y.loc184_37.1) [symbolic = %tuple.type (constants.%tuple.type.c49)] +// CHECK:STDOUT: %pattern_type.loc184_9: type = pattern_type %tuple.type [symbolic = %pattern_type.loc184_9 (constants.%pattern_type.60a)] +// CHECK:STDOUT: %x.param_patt.loc184_9.2: @SelfNested.WithSelf.F.%pattern_type.loc184_9 (%pattern_type.60a) = value_param_pattern [symbolic = %x.param_patt.loc184_9.2 (constants.%x.param_patt.e85)] +// CHECK:STDOUT: %x.patt.loc184_9.2: @SelfNested.WithSelf.F.%pattern_type.loc184_9 (%pattern_type.60a) = wrapper_binding_pattern x, %x.param_patt.loc184_9.2 [symbolic = %x.patt.loc184_9.2 (constants.%x.patt.6af)] +// CHECK:STDOUT: %array_type.loc184_57.1: type = array_type constants.%int_4, %Self.as_type.loc184_16.1 [symbolic = %array_type.loc184_57.1 (constants.%array_type.4e4)] +// CHECK:STDOUT: %.loc184_57.1: Core.Form = init_form %array_type.loc184_57.1 [symbolic = %.loc184_57.1 (constants.%.f45)] +// CHECK:STDOUT: %pattern_type.loc184_57: type = pattern_type %array_type.loc184_57.1 [symbolic = %pattern_type.loc184_57 (constants.%pattern_type.2ab)] +// CHECK:STDOUT: %return.param_patt.loc184_57.2: @SelfNested.WithSelf.F.%pattern_type.loc184_57 (%pattern_type.2ab) = out_param_pattern [symbolic = %return.param_patt.loc184_57.2 (constants.%return.param_patt.439)] +// CHECK:STDOUT: %return.patt.loc184_41.2: @SelfNested.WithSelf.F.%pattern_type.loc184_57 (%pattern_type.2ab) = return_slot_pattern %return.param_patt.loc184_57.2, %array_type.loc184_57.1 [symbolic = %return.patt.loc184_41.2 (constants.%return.patt.869)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%x.param: @SelfNested.WithSelf.F.%tuple.type (%tuple.type.c49)) -> out %return.param: @SelfNested.WithSelf.F.%array_type.loc183_57.1 (%array_type.4e4); +// CHECK:STDOUT: fn(%x.param: @SelfNested.WithSelf.F.%tuple.type (%tuple.type.c49)) -> out %return.param: @SelfNested.WithSelf.F.%array_type.loc184_57.1 (%array_type.4e4); // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @SelfNestedBadParam.as.SelfNested.impl.F.loc195_87.1(%x.param: %tuple.type.e57) -> out %return.param: %array_type.291; +// CHECK:STDOUT: fn @SelfNestedBadParam.as.SelfNested.impl.F.loc196_87.1(%x.param: %tuple.type.e57) -> out %return.param: %array_type.291; // CHECK:STDOUT: -// CHECK:STDOUT: fn @SelfNestedBadParam.as.SelfNested.impl.F.loc195_87.2(%x.param: %tuple.type.9ab) -> out %return.param: %array_type.291 [thunk @SelfNestedBadParam.as.SelfNested.impl.%SelfNestedBadParam.as.SelfNested.impl.F.decl.loc195_87.1 for @SelfNested.WithSelf.%SelfNested.WithSelf.F.decl, @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d)] { +// CHECK:STDOUT: fn @SelfNestedBadParam.as.SelfNested.impl.F.loc196_87.2(%x.param: %tuple.type.9ab) -> out %return.param: %array_type.291 [thunk @SelfNestedBadParam.as.SelfNested.impl.%SelfNestedBadParam.as.SelfNested.impl.F.decl.loc196_87.1 for @SelfNested.WithSelf.%SelfNested.WithSelf.F.decl, @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d)] { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %F.ref: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.1 = name_ref F, @SelfNestedBadParam.as.SelfNested.impl.%SelfNestedBadParam.as.SelfNested.impl.F.decl.loc195_87.1 [concrete = constants.%SelfNestedBadParam.as.SelfNested.impl.F.5fd896.1] +// CHECK:STDOUT: %F.ref: %SelfNestedBadParam.as.SelfNested.impl.F.type.4325e7.1 = name_ref F, @SelfNestedBadParam.as.SelfNested.impl.%SelfNestedBadParam.as.SelfNested.impl.F.decl.loc196_87.1 [concrete = constants.%SelfNestedBadParam.as.SelfNested.impl.F.5fd896.1] // CHECK:STDOUT: %.3: ref %array_type.291 = splice_block %return.param {} // CHECK:STDOUT: %tuple.elem0: %ptr.52e = tuple_access %x.param, element0 // CHECK:STDOUT: %tuple.elem1: %struct_type.x.y.da2 = tuple_access %x.param, element1 @@ -1345,14 +1346,14 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return %SelfNestedBadParam.as.SelfNested.impl.F.call to %return.param // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @SelfNestedBadReturnType.as.SelfNested.impl.F.loc211_112.1(%x.param: %tuple.type.829) -> out %return.param: %array_type.291; +// CHECK:STDOUT: fn @SelfNestedBadReturnType.as.SelfNested.impl.F.loc212_112.1(%x.param: %tuple.type.829) -> out %return.param: %array_type.291; // CHECK:STDOUT: -// CHECK:STDOUT: fn @SelfNestedBadReturnType.as.SelfNested.impl.F.loc211_112.2(%x.param: %tuple.type.829) -> out %return.param: %array_type.a08 [thunk @SelfNestedBadReturnType.as.SelfNested.impl.%SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc211_112.1 for @SelfNested.WithSelf.%SelfNested.WithSelf.F.decl, @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71)] { +// CHECK:STDOUT: fn @SelfNestedBadReturnType.as.SelfNested.impl.F.loc212_112.2(%x.param: %tuple.type.829) -> out %return.param: %array_type.a08 [thunk @SelfNestedBadReturnType.as.SelfNested.impl.%SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc212_112.1 for @SelfNested.WithSelf.%SelfNested.WithSelf.F.decl, @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71)] { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %F.ref: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.1 = name_ref F, @SelfNestedBadReturnType.as.SelfNested.impl.%SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc211_112.1 [concrete = constants.%SelfNestedBadReturnType.as.SelfNested.impl.F.5a7d54.1] -// CHECK:STDOUT: %.loc211_112.1: ref %array_type.291 = temporary_storage -// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.call: init %array_type.291 to %.loc211_112.1 = call %F.ref(%x.param) -// CHECK:STDOUT: %.loc211_112.2: %array_type.a08 = converted %SelfNestedBadReturnType.as.SelfNested.impl.F.call, [concrete = ] +// CHECK:STDOUT: %F.ref: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.1cbabe.1 = name_ref F, @SelfNestedBadReturnType.as.SelfNested.impl.%SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc212_112.1 [concrete = constants.%SelfNestedBadReturnType.as.SelfNested.impl.F.5a7d54.1] +// CHECK:STDOUT: %.loc212_112.1: ref %array_type.291 = temporary_storage +// CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.call: init %array_type.291 to %.loc212_112.1 = call %F.ref(%x.param) +// CHECK:STDOUT: %.loc212_112.2: %array_type.a08 = converted %SelfNestedBadReturnType.as.SelfNested.impl.F.call, [concrete = ] // CHECK:STDOUT: return to %return.param // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1478,19 +1479,19 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: // CHECK:STDOUT: specific @SelfNested.WithSelf.F(constants.%Self.e81) { // CHECK:STDOUT: %Self => constants.%Self.e81 -// CHECK:STDOUT: %Self.as_type.loc183_16.1 => constants.%Self.as_type.8ab -// CHECK:STDOUT: %ptr.loc183_16.1 => constants.%ptr.a16 -// CHECK:STDOUT: %struct_type.x.y.loc183_37.1 => constants.%struct_type.x.y.4c5 +// CHECK:STDOUT: %Self.as_type.loc184_16.1 => constants.%Self.as_type.8ab +// CHECK:STDOUT: %ptr.loc184_16.1 => constants.%ptr.a16 +// CHECK:STDOUT: %struct_type.x.y.loc184_37.1 => constants.%struct_type.x.y.4c5 // CHECK:STDOUT: %tuple => constants.%tuple.b6a // CHECK:STDOUT: %tuple.type => constants.%tuple.type.c49 -// CHECK:STDOUT: %pattern_type.loc183_9 => constants.%pattern_type.60a -// CHECK:STDOUT: %x.param_patt.loc183_9.2 => constants.%x.param_patt.e85 -// CHECK:STDOUT: %x.patt.loc183_9.2 => constants.%x.patt.6af -// CHECK:STDOUT: %array_type.loc183_57.1 => constants.%array_type.4e4 -// CHECK:STDOUT: %.loc183_57.1 => constants.%.f45 -// CHECK:STDOUT: %pattern_type.loc183_57 => constants.%pattern_type.2ab -// CHECK:STDOUT: %return.param_patt.loc183_57.2 => constants.%return.param_patt.439 -// CHECK:STDOUT: %return.patt.loc183_41.2 => constants.%return.patt.869 +// CHECK:STDOUT: %pattern_type.loc184_9 => constants.%pattern_type.60a +// CHECK:STDOUT: %x.param_patt.loc184_9.2 => constants.%x.param_patt.e85 +// CHECK:STDOUT: %x.patt.loc184_9.2 => constants.%x.patt.6af +// CHECK:STDOUT: %array_type.loc184_57.1 => constants.%array_type.4e4 +// CHECK:STDOUT: %.loc184_57.1 => constants.%.f45 +// CHECK:STDOUT: %pattern_type.loc184_57 => constants.%pattern_type.2ab +// CHECK:STDOUT: %return.param_patt.loc184_57.2 => constants.%return.param_patt.439 +// CHECK:STDOUT: %return.patt.loc184_41.2 => constants.%return.patt.869 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @SelfNested.WithSelf(constants.%SelfNested.facet.d0d) { @@ -1502,19 +1503,19 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: // CHECK:STDOUT: specific @SelfNested.WithSelf.F(constants.%SelfNested.facet.d0d) { // CHECK:STDOUT: %Self => constants.%SelfNested.facet.d0d -// CHECK:STDOUT: %Self.as_type.loc183_16.1 => constants.%SelfNestedBadParam -// CHECK:STDOUT: %ptr.loc183_16.1 => constants.%ptr.52e -// CHECK:STDOUT: %struct_type.x.y.loc183_37.1 => constants.%struct_type.x.y.da2 +// CHECK:STDOUT: %Self.as_type.loc184_16.1 => constants.%SelfNestedBadParam +// CHECK:STDOUT: %ptr.loc184_16.1 => constants.%ptr.52e +// CHECK:STDOUT: %struct_type.x.y.loc184_37.1 => constants.%struct_type.x.y.da2 // CHECK:STDOUT: %tuple => constants.%tuple.09d // CHECK:STDOUT: %tuple.type => constants.%tuple.type.9ab -// CHECK:STDOUT: %pattern_type.loc183_9 => constants.%pattern_type.94f -// CHECK:STDOUT: %x.param_patt.loc183_9.2 => constants.%x.param_patt.7b9 -// CHECK:STDOUT: %x.patt.loc183_9.2 => constants.%x.patt.961 -// CHECK:STDOUT: %array_type.loc183_57.1 => constants.%array_type.291 -// CHECK:STDOUT: %.loc183_57.1 => constants.%.cc2 -// CHECK:STDOUT: %pattern_type.loc183_57 => constants.%pattern_type.3a0 -// CHECK:STDOUT: %return.param_patt.loc183_57.2 => constants.%return.param_patt.489 -// CHECK:STDOUT: %return.patt.loc183_41.2 => constants.%return.patt.98a +// CHECK:STDOUT: %pattern_type.loc184_9 => constants.%pattern_type.94f +// CHECK:STDOUT: %x.param_patt.loc184_9.2 => constants.%x.param_patt.7b9 +// CHECK:STDOUT: %x.patt.loc184_9.2 => constants.%x.patt.961 +// CHECK:STDOUT: %array_type.loc184_57.1 => constants.%array_type.291 +// CHECK:STDOUT: %.loc184_57.1 => constants.%.cc2 +// CHECK:STDOUT: %pattern_type.loc184_57 => constants.%pattern_type.3a0 +// CHECK:STDOUT: %return.param_patt.loc184_57.2 => constants.%return.param_patt.489 +// CHECK:STDOUT: %return.patt.loc184_41.2 => constants.%return.patt.98a // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @SelfNested.WithSelf(constants.%SelfNested.facet.e71) { @@ -1526,18 +1527,18 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: // CHECK:STDOUT: specific @SelfNested.WithSelf.F(constants.%SelfNested.facet.e71) { // CHECK:STDOUT: %Self => constants.%SelfNested.facet.e71 -// CHECK:STDOUT: %Self.as_type.loc183_16.1 => constants.%SelfNestedBadReturnType -// CHECK:STDOUT: %ptr.loc183_16.1 => constants.%ptr.f55 -// CHECK:STDOUT: %struct_type.x.y.loc183_37.1 => constants.%struct_type.x.y.f6a +// CHECK:STDOUT: %Self.as_type.loc184_16.1 => constants.%SelfNestedBadReturnType +// CHECK:STDOUT: %ptr.loc184_16.1 => constants.%ptr.f55 +// CHECK:STDOUT: %struct_type.x.y.loc184_37.1 => constants.%struct_type.x.y.f6a // CHECK:STDOUT: %tuple => constants.%tuple.96d // CHECK:STDOUT: %tuple.type => constants.%tuple.type.829 -// CHECK:STDOUT: %pattern_type.loc183_9 => constants.%pattern_type.5c2 -// CHECK:STDOUT: %x.param_patt.loc183_9.2 => constants.%x.param_patt.7be -// CHECK:STDOUT: %x.patt.loc183_9.2 => constants.%x.patt.608 -// CHECK:STDOUT: %array_type.loc183_57.1 => constants.%array_type.a08 -// CHECK:STDOUT: %.loc183_57.1 => constants.%.442 -// CHECK:STDOUT: %pattern_type.loc183_57 => constants.%pattern_type.f0d -// CHECK:STDOUT: %return.param_patt.loc183_57.2 => constants.%return.param_patt.039 -// CHECK:STDOUT: %return.patt.loc183_41.2 => constants.%return.patt.3c4 +// CHECK:STDOUT: %pattern_type.loc184_9 => constants.%pattern_type.5c2 +// CHECK:STDOUT: %x.param_patt.loc184_9.2 => constants.%x.param_patt.7be +// CHECK:STDOUT: %x.patt.loc184_9.2 => constants.%x.patt.608 +// CHECK:STDOUT: %array_type.loc184_57.1 => constants.%array_type.a08 +// CHECK:STDOUT: %.loc184_57.1 => constants.%.442 +// CHECK:STDOUT: %pattern_type.loc184_57 => constants.%pattern_type.f0d +// CHECK:STDOUT: %return.param_patt.loc184_57.2 => constants.%return.param_patt.039 +// CHECK:STDOUT: %return.patt.loc184_41.2 => constants.%return.patt.3c4 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/language_server/handle_position.cpp b/toolchain/language_server/handle_position.cpp index 891b81434e0a..9e82788dec79 100644 --- a/toolchain/language_server/handle_position.cpp +++ b/toolchain/language_server/handle_position.cpp @@ -20,18 +20,16 @@ namespace Carbon::LanguageServer { // if it has no type. Instructions that aren't values, such as declarations of // namespaces, have no type to show. // -// TODO: `StringifyConstantInst` renders some types as placeholders such as +// TODO: `StringifyTypeOfInst` renders some types as placeholders such as // `` for a function and `` for a binding pattern, // which is unhelpful as hover text. Show the signature for a function, and the // bound type rather than the pattern type for a binding. -static auto StringifyTypeOfInst(const SemIR::File& sem_ir, - SemIR::InstId inst_id) -> std::string { - auto type_id = sem_ir.insts().Get(inst_id).type_id(); - if (!type_id.has_value()) { +static auto StringifyTypeForHover(const SemIR::File& sem_ir, + SemIR::InstId inst_id) -> std::string { + if (!sem_ir.insts().Get(inst_id).type_id().has_value()) { return ""; } - return SemIR::StringifyConstantInst(sem_ir, - sem_ir.types().GetTypeInstId(type_id)); + return SemIR::StringifyTypeOfInst(sem_ir, inst_id); } // Given a position-based query, returns the corresponding position information. @@ -78,7 +76,7 @@ auto HandleHover( const auto& sem_ir = *info.file->sem_ir(); RawStringOstream text; text << "```carbon\n" << info.file->tokens().GetTokenText(info.token); - if (auto type = StringifyTypeOfInst(sem_ir, info.inst_id); !type.empty()) { + if (auto type = StringifyTypeForHover(sem_ir, info.inst_id); !type.empty()) { text << ": " << type; } text << "\n```"; diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index 29ddb43f0f39..c08c174cf2dc 100644 --- a/toolchain/sem_ir/BUILD +++ b/toolchain/sem_ir/BUILD @@ -201,12 +201,26 @@ cc_library( ], ) +cc_library( + name = "sugared_type", + srcs = ["sugared_type.cpp"], + hdrs = ["sugared_type.h"], + deps = [ + ":file", + ":typed_insts", + "//common:check", + "//toolchain/base:kind_switch", + "@llvm-project//llvm:Support", + ], +) + cc_library( name = "stringify", srcs = ["stringify.cpp"], hdrs = ["stringify.h"], deps = [ ":file", + ":sugared_type", ":typed_insts", "//common:check", "//common:concepts", diff --git a/toolchain/sem_ir/stringify.cpp b/toolchain/sem_ir/stringify.cpp index e098f818ba61..7f3145a71172 100644 --- a/toolchain/sem_ir/stringify.cpp +++ b/toolchain/sem_ir/stringify.cpp @@ -19,6 +19,7 @@ #include "toolchain/sem_ir/singleton_insts.h" #include "toolchain/sem_ir/specific_interface.h" #include "toolchain/sem_ir/struct_type_field.h" +#include "toolchain/sem_ir/sugared_type.h" #include "toolchain/sem_ir/type_info.h" #include "toolchain/sem_ir/typed_insts.h" @@ -876,6 +877,10 @@ auto StringifyConstantInst(const File& sem_ir, InstId outer_inst_id) return Stringify(sem_ir, step_stack); } +auto StringifyTypeOfInst(const File& sem_ir, InstId inst_id) -> std::string { + return StringifyConstantInst(sem_ir, GetSugaredTypeOfInst(sem_ir, inst_id)); +} + auto StringifySpecific(const File& sem_ir, SpecificId specific_id) -> std::string { StepStack step_stack(&sem_ir); diff --git a/toolchain/sem_ir/stringify.h b/toolchain/sem_ir/stringify.h index fcc470deaef9..6fb309214b31 100644 --- a/toolchain/sem_ir/stringify.h +++ b/toolchain/sem_ir/stringify.h @@ -19,6 +19,12 @@ namespace Carbon::SemIR { auto StringifyConstantInst(const File& sem_ir, InstId outer_inst_id) -> std::string; +// Produces a string version of the type of an instruction, describing the type +// the way it was written in the source where we can determine that. Generally, +// this should not be called directly. To format the type of an expression into +// a diagnostic, use a diagnostic parameter of type `TypeOfInstId`. +auto StringifyTypeOfInst(const File& sem_ir, InstId inst_id) -> std::string; + // Produces a string version of the name of a specific. Generally, this should // not be called directly. To format a string into a diagnostic, use a // diagnostic parameter of type `SpecificId`. diff --git a/toolchain/sem_ir/sugared_type.cpp b/toolchain/sem_ir/sugared_type.cpp new file mode 100644 index 000000000000..80cceed3ffbb --- /dev/null +++ b/toolchain/sem_ir/sugared_type.cpp @@ -0,0 +1,209 @@ +// 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 + +#include "toolchain/sem_ir/sugared_type.h" + +#include + +#include "common/check.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "toolchain/base/kind_switch.h" +#include "toolchain/sem_ir/function.h" +#include "toolchain/sem_ir/ids.h" +#include "toolchain/sem_ir/inst.h" +#include "toolchain/sem_ir/inst_categories.h" +#include "toolchain/sem_ir/typed_insts.h" + +namespace Carbon::SemIR { + +namespace { + +// Searches for an instruction that describes how the type of a given +// instruction was written. See `GetSugaredTypeOfInst`. +class SugaredTypeFinder { + public: + explicit SugaredTypeFinder(const File* sem_ir) : sem_ir_(sem_ir) {} + + // Finds the best spelling we can for the type of `inst_id`. + auto Find(InstId inst_id) -> TypeInstId; + + private: + // A transformation that is applied to a type that we find in order to produce + // the type of the instruction that the search started from. + enum class TypeTransformStep { + // Replace a pointer type `T*` with its pointee type `T`. + Pointee, + }; + + // Walks from `inst_id` towards the instructions that determined its type, + // until we find an instruction that tracks how its type was written, adding + // to `steps_` as we go. Returns `None` if no such instruction is found. + auto FindSpelledType(InstId inst_id) -> TypeInstId; + + // Finds the declared return type of `call`, as written. + auto FindCallReturnType(Call call) -> TypeInstId; + + // Applies `step` to `type_inst_id`, desugaring it if necessary. Returns + // `None` if the step can't be applied. + auto ApplyStep(TypeTransformStep step, TypeInstId type_inst_id) -> TypeInstId; + + // Returns `operand_id` if it has type `type_id`, and `None` otherwise. This + // is used when looking through an instruction that is expected to have the + // same type as one of its operands: if that turns out not to hold, we stop + // the search rather than describing the wrong type. + auto LookThrough(TypeId type_id, InstId operand_id) -> InstId; + + const File* sem_ir_; + + // The steps to apply to the type that we find, in reverse order. + llvm::SmallVector steps_; +}; + +auto SugaredTypeFinder::LookThrough(TypeId type_id, InstId operand_id) + -> InstId { + if (!operand_id.has_value() || + sem_ir_->insts().Get(operand_id).type_id() != type_id) { + return InstId::None; + } + return operand_id; +} + +auto SugaredTypeFinder::FindCallReturnType(Call call) -> TypeInstId { + auto callee = GetCallee(*sem_ir_, call.callee_id); + auto* function_callee = std::get_if(&callee); + if (!function_callee) { + return TypeInstId::None; + } + + // TODO: For a call to a generic function, substitute the call's arguments + // into the declared return type so that we can describe how it was written. + if (function_callee->enclosing_specific_id.has_value() || + function_callee->resolved_specific_id.has_value()) { + return TypeInstId::None; + } + + // This is `None` if no return type was declared, in which case we have no + // spelling to offer. + return sem_ir_->functions() + .Get(function_callee->function_id) + .return_type_inst_id; +} + +auto SugaredTypeFinder::ApplyStep(TypeTransformStep step, + TypeInstId type_inst_id) -> TypeInstId { + switch (step) { + case TypeTransformStep::Pointee: { + auto pointer_type = sem_ir_->insts().TryGetAs(type_inst_id); + if (!pointer_type) { + // The spelling we found isn't syntactically a pointer type, for example + // because the pointer type was named by an alias. Desugar it and try + // again: the canonical instruction for a pointer type is a + // `PointerType`. + type_inst_id = sem_ir_->types().GetTypeInstId( + sem_ir_->types().GetTypeIdForTypeInstId(type_inst_id)); + pointer_type = sem_ir_->insts().TryGetAs(type_inst_id); + if (!pointer_type) { + return TypeInstId::None; + } + } + return pointer_type->pointee_id; + } + } +} + +auto SugaredTypeFinder::FindSpelledType(InstId inst_id) -> TypeInstId { + while (inst_id.has_value()) { + auto inst = sem_ir_->insts().Get(inst_id); + CARBON_KIND_SWITCH(inst) { + // The type of a call is the declared return type of the callee. + case CARBON_KIND(Call call): { + return FindCallReturnType(call); + } + + // The type of a dereference is the pointee type of the pointer. + case CARBON_KIND(Deref deref): { + steps_.push_back(TypeTransformStep::Pointee); + inst_id = deref.pointer_id; + continue; + } + + // The following instructions have the same type as one of their operands, + // so look through them to that operand. + case CARBON_KIND(NameRef name_ref): { + inst_id = LookThrough(inst.type_id(), name_ref.value_id); + continue; + } + case CARBON_KIND_ANY(AnyBinding, binding): { + inst_id = LookThrough(inst.type_id(), binding.value_id); + continue; + } + case CARBON_KIND(AcquireValue acquire_value): { + inst_id = LookThrough(inst.type_id(), acquire_value.value_id); + continue; + } + case CARBON_KIND(Converted converted): { + inst_id = LookThrough(inst.type_id(), converted.result_id); + continue; + } + case CARBON_KIND(SpliceBlock splice_block): { + inst_id = LookThrough(inst.type_id(), splice_block.result_id); + continue; + } + case CARBON_KIND(Temporary temporary): { + inst_id = LookThrough(inst.type_id(), temporary.init_id); + continue; + } + case CARBON_KIND(ValueOfInitializer value_of_initializer): { + inst_id = LookThrough(inst.type_id(), value_of_initializer.init_id); + continue; + } + + default: { + // TODO: Handle more cases here. For example, the type of a name + // reference to a binding or field should use the type as written in + // the declaration of that binding or field, and the type of an index + // into an array should be the element type as written in the array + // type. + return TypeInstId::None; + } + } + } + return TypeInstId::None; +} + +auto SugaredTypeFinder::Find(InstId inst_id) -> TypeInstId { + auto type_id = sem_ir_->insts().Get(inst_id).type_id(); + if (!type_id.has_value()) { + return TypeInstId::None; + } + + auto result = FindSpelledType(inst_id); + for (auto step : llvm::reverse(steps_)) { + if (!result.has_value()) { + break; + } + result = ApplyStep(step, result); + } + + if (!result.has_value()) { + // We've no better spelling for this type, so use the canonical one. + return sem_ir_->types().GetTypeInstId(type_id); + } + + CARBON_CHECK(sem_ir_->types().GetTypeIdForTypeInstId(result) == type_id, + "Spelling {0} found for the type of {1} describes type {2}, but " + "its type is {3}", + result, inst_id, sem_ir_->types().GetTypeIdForTypeInstId(result), + type_id); + return result; +} + +} // namespace + +auto GetSugaredTypeOfInst(const File& sem_ir, InstId inst_id) -> TypeInstId { + return SugaredTypeFinder(&sem_ir).Find(inst_id); +} + +} // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/sugared_type.h b/toolchain/sem_ir/sugared_type.h new file mode 100644 index 000000000000..f0f05c2f009f --- /dev/null +++ b/toolchain/sem_ir/sugared_type.h @@ -0,0 +1,35 @@ +// 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 + +#ifndef CARBON_TOOLCHAIN_SEM_IR_SUGARED_TYPE_H_ +#define CARBON_TOOLCHAIN_SEM_IR_SUGARED_TYPE_H_ + +#include "toolchain/sem_ir/file.h" +#include "toolchain/sem_ir/ids.h" + +namespace Carbon::SemIR { + +// Returns an instruction describing the type of `inst_id`, preferring an +// instruction that reflects how the type was written in the source over the +// canonical instruction for the type. +// +// The type of an instruction is tracked as a `TypeId`, which is canonical, and +// so says nothing about how the type was spelled: for example, a type named by +// an alias is indistinguishable from the type that the alias names. However, +// the instructions that formed the type as written are usually still present, +// and can often be found by looking at the instruction that has the type, +// rather than at the type itself. For example, the type of a call to a +// non-generic function is the declared return type of that function, and the +// function tracks the instruction for its return type as written. +// +// This process is opportunistic: where we can't do better, the canonical type +// instruction is returned. The result always describes the same type as +// `sem_ir.insts().Get(inst_id).type_id()`; only the spelling can differ. +// +// Returns `None` if `inst_id` has no type. +auto GetSugaredTypeOfInst(const File& sem_ir, InstId inst_id) -> TypeInstId; + +} // namespace Carbon::SemIR + +#endif // CARBON_TOOLCHAIN_SEM_IR_SUGARED_TYPE_H_