Start to preserve type sugar in diagnostics. (#7768)

Instead of always printing types as canonical, attempt to find a sugared
type where possible, and include that type in the diagnostic. We can
only do this when given the instruction whose type is being printed
(`TypeOfInstId`) rather than the canonical type ID.

Initial support here is intentionally minimal: just looking through
calls to the callee's declared return type, and looking through pointer
dereferences and corresponding pointer types, to build out the initial
infrastructure. More cases can be added later; this degrades gracefully
to using the canonical type if a better type can't be found.

Assisted-by: Claude Opus 5 via Antigravity
This commit is contained in:
Richard Smith
2026-09-15 23:11:58 +00:00
committed by GitHub
parent d8c4fc51cd
commit f3d67de480
9 changed files with 435 additions and 146 deletions
+1 -8
View File
@@ -92,14 +92,7 @@ auto DiagnosticEmitter::ConvertArg(llvm::Any arg) const -> llvm::Any {
if (!type_of_expr->inst_id.has_value()) {
return "<none>";
}
// 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<InstIdAsConstant>(&arg)) {
return "`" + StringifyConstantInst(*sem_ir_, expr->inst_id) + "`";
@@ -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())();
}
+131 -130
View File
@@ -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: <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: <witness> = impl_witness %SelfNested.impl_witness_table [concrete = constants.%SelfNested.impl_witness.09d]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .SelfNestedBadParam = <poisoned>
// 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: <witness> = impl_witness %SelfNested.impl_witness_table [concrete = constants.%SelfNested.impl_witness.849]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .SelfNestedBadReturnType = <poisoned>
// CHECK:STDOUT: .SelfNestedBadParam = <poisoned>
// 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: <witness> = impl_self_witness @SelfNestedBadParam.as.SelfNested.impl.%Self.ref, @SelfNested [concrete = constants.%.83b]
// CHECK:STDOUT: %.loc188: <witness> = impl_self_witness @SelfNestedBadParam.as.SelfNested.impl.%Self.ref, @SelfNested [concrete = constants.%.83b]
// CHECK:STDOUT: %complete_type: <witness> = 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: <witness> = impl_self_witness @SelfNestedBadReturnType.as.SelfNested.impl.%Self.ref, @SelfNested [concrete = constants.%.020]
// CHECK:STDOUT: %.loc201: <witness> = impl_self_witness @SelfNestedBadReturnType.as.SelfNested.impl.%Self.ref, @SelfNested [concrete = constants.%.020]
// CHECK:STDOUT: %complete_type: <witness> = 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> = 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, <error> [concrete = <error>]
// 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, <error> [concrete = <error>]
// CHECK:STDOUT: return <error>
// 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, <error> [concrete = <error>]
// 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, <error> [concrete = <error>]
// CHECK:STDOUT: return <error> 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:
@@ -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
// `<type of F>` for a function and `<pattern for i32>` 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```";
+14
View File
@@ -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",
+5
View File
@@ -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);
+6
View File
@@ -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`.
+209
View File
@@ -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 <variant>
#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<TypeTransformStep> 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<CalleeFunction>(&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<PointerType>(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<PointerType>(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
+35
View File
@@ -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_