From cc5a42691ed840c923d53089e46ad932eff94b1a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 10 Apr 2026 10:29:36 -0400 Subject: [PATCH] Add `where T impls X` constraints into the FacetTypeInfo (#7038) This makes them part of the identified facet type, and we can see the constraints as part of stringify and format output. But this does not do enough to make them useful yet: Any `T impls X` constraint must contain a reference to `.Self` somewhere. And `.Self` references do not get substituted, so neither `T(.Self) impls X` and `T impls X(.Self)` will match against an incoming facet value derived from an `impl T(U) as X` or `impl T as X(U)`, since `U` and `.Self` are never the same thing until `.Self` can be substituted. Now that impl lookup runs into facet values containing `.Self` (a symbolic binding), such as in `C(.Self)`, we were crashing assuming the type of `.Self` is a FacetType, but it can be `type` in the case of `type where C(.Self) impls...`. Instead, use an empty facet type for the type of `.Self` so it is always a facet. This assists with substituting other facets into it, without having to insert an extra FacetAccessType. `MakePeriodSelfFacetValue()` now enforces this requirement. --------- Co-authored-by: Richard Smith --- toolchain/check/eval.cpp | 118 ++++++++++++++---- toolchain/check/facet_type.cpp | 2 + toolchain/check/facet_type.h | 6 +- toolchain/check/handle_binding_pattern.cpp | 9 +- toolchain/check/handle_where.cpp | 17 ++- .../testdata/deduce/binding_pattern.carbon | 90 ++++++------- ..._facet_value_to_narrowed_facet_type.carbon | 56 +++++---- .../facet/validate_impl_constraints.carbon | 79 +++++++++++- .../testdata/impl/assoc_const_self.carbon | 22 ++-- .../impl/fail_impl_bad_interface.carbon | 23 ++-- .../interface/fail_lookup_in_type_type.carbon | 11 +- .../extend_name_lookup.carbon | 10 +- .../testdata/named_constraint/require.carbon | 4 +- .../testdata/where_expr/constraints.carbon | 18 +-- .../testdata/where_expr/designator.carbon | 16 ++- toolchain/sem_ir/stringify.cpp | 4 +- 16 files changed, 330 insertions(+), 155 deletions(-) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 6b6e668cb62a..b4103b47a963 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -36,6 +36,7 @@ #include "toolchain/sem_ir/impl.h" #include "toolchain/sem_ir/inst_categories.h" #include "toolchain/sem_ir/inst_kind.h" +#include "toolchain/sem_ir/specific_named_constraint.h" #include "toolchain/sem_ir/typed_insts.h" namespace Carbon::Check { @@ -2633,36 +2634,109 @@ static auto AddRequirementImpls(Context& context, SemIR::RequirementImpls impls, return; } + auto facet_type = context.insts().GetAs(rhs_id); + const auto& rhs = context.facet_types().Get(facet_type.facet_type_id); + if (IsSameFacetValue(context, context.constant_values().Get(lhs_id), period_self_id)) { - auto facet_type = context.insts().GetAs(rhs_id); - const auto& more_info = context.facet_types().Get(facet_type.facet_type_id); - // The way to prevent lookup into the interface requirements of a - // facet type is to put it to the right of a `.Self impls`, which we - // accomplish by putting them into `self_impls_constraints`. + // A facet type with `.Self impls `. Whatever the RHS facet + // type constrains for `.Self` gets forwarded to the output facet type to + // also constrain `.Self`. Nothing on the RHS of `impls` can extend the + // resulting facet type. + llvm::append_range(info->self_impls_constraints, rhs.extend_constraints); llvm::append_range(info->self_impls_constraints, - more_info.extend_constraints); - llvm::append_range(info->self_impls_constraints, - more_info.self_impls_constraints); + rhs.self_impls_constraints); llvm::append_range(info->self_impls_named_constraints, - more_info.extend_named_constraints); + rhs.extend_named_constraints); llvm::append_range(info->self_impls_named_constraints, - more_info.self_impls_named_constraints); - // If `.Self impls Z` and Z implies `C impls Y`, then the facet type - // of `.Self` also knows `C impls Y`. - llvm::append_range(info->type_impls_interfaces, - more_info.type_impls_interfaces); + rhs.self_impls_named_constraints); + llvm::append_range(info->type_impls_interfaces, rhs.type_impls_interfaces); llvm::append_range(info->type_impls_named_constraints, - more_info.type_impls_named_constraints); - // Other requirements are copied in. - llvm::append_range(info->rewrite_constraints, - more_info.rewrite_constraints); - info->other_requirements |= more_info.other_requirements; - return; + rhs.type_impls_named_constraints); + } else { + // Consider `I where C(.Self) impls (J(.Self) where .Self impls K(.Self))`, + // when we are evaluating the `C(.Self) impls ()` requirement. + // The is our `rhs` here, and it will contain: + // * extend constraint: J(.Self) + // * self impls constraint: K(.Self) + // + // The value of `.Self` changes where we cross a `where` operator. This + // means extend constraints retain their original `.Self`, but self impls + // constraints should have their `.Self` replaced by the LHS of the impls + // requirement. + // + // However that is not quite enough. The view of the LHS of the impls + // requirement should be a facet with a facet type of the RHS extend + // constraints. In this case the LHS is C(.Self) and the RHS facet type is + // `J(.Self) where .Self impls K(.Self)`. The RHS facet type has impls + // constraints (which are on the RHS of a `where` operator), in which their + // `.Self` should be replaced by `C(.Self)` converted to the RHS facet + // type's extend constraints (which are on the LHS of a `where` operator), + // which is `C(.Self) as J(.Self)`. It should be enough to convert the LHS + // type to the type of the `.Self` that it is replacing, as that contains + // the extend constraints. + // + // So the final RHS facet type to be merged into `info` is: + // + // `J(.Self) where (C(.Self) as J(.Self)) impls K(C(.Self) as J(.Self))`. + + auto lhs_facet_or_type = GetCanonicalFacetOrTypeValue(context, lhs_id); + + auto impls_interface = [&](SemIR::SpecificInterface si) + -> SemIR::FacetTypeInfo::TypeImplsInterface { + return {lhs_facet_or_type, si}; + }; + auto impls_constraint = [&](SemIR::SpecificNamedConstraint sc) + -> SemIR::FacetTypeInfo::TypeImplsNamedConstraint { + return {lhs_facet_or_type, sc}; + }; + + // Extend constraints are copied over without replacing anything, but are + // converted to type impls constraints so they apply to the LHS type. + llvm::append_range( + info->type_impls_interfaces, + llvm::map_range(rhs.extend_constraints, impls_interface)); + llvm::append_range( + info->type_impls_named_constraints, + llvm::map_range(rhs.extend_named_constraints, impls_constraint)); + + // To replace the `.Self` in `.Self impls X` we convert from a self impls + // constraint to a type impls constraint where the type is the impls LHS + // type. We must also replace any `.Self` references in the constraint in + // the same way. The LHS type needs to be converted to a facet with its type + // containing the RHS facet type's extend constraints so that the extend + // constraints can be referenced in impls constraints. + // + // TODO: Convert the LHS used in the TypeImplsNamedConstraint to a facet + // with the RHS extend constraints (interfaces and named constraints). + // + // TODO: Replace `.Self` with the LHS type as a facet with the RHS extend + // constraints. + llvm::append_range( + info->type_impls_interfaces, + llvm::map_range(rhs.self_impls_constraints, impls_interface)); + llvm::append_range( + info->type_impls_named_constraints, + llvm::map_range(rhs.self_impls_named_constraints, impls_constraint)); + + // Type impls constraints are copied in, but need to have their `.Self` + // references replaced by the impls LHS type. Like above, the LHS type + // should be converted to a facet type containing the RHS facet type's + // extend constraints. + // + // TODO: Convert the LHS used in the TypeImplsNamedConstraint to a facet + // with the RHS extend constraints (interfaces and named constraints). + // + // TODO: Replace `.Self` with the LHS type as a facet with the RHS extend + // constraints. + llvm::append_range(info->type_impls_interfaces, rhs.type_impls_interfaces); + llvm::append_range(info->type_impls_named_constraints, + rhs.type_impls_named_constraints); } - // TODO: Handle `impls` constraints beyond `.Self impls`. - info->other_requirements = true; + // Other requirements are copied in. + llvm::append_range(info->rewrite_constraints, rhs.rewrite_constraints); + info->other_requirements |= rhs.other_requirements; } // Add the constraints from the WhereExpr instruction into a FacetTypeInfo in diff --git a/toolchain/check/facet_type.cpp b/toolchain/check/facet_type.cpp index 0945538c3daf..d321af6dc43d 100644 --- a/toolchain/check/facet_type.cpp +++ b/toolchain/check/facet_type.cpp @@ -403,6 +403,8 @@ auto ResolveFacetTypeRewriteConstraints( auto MakePeriodSelfFacetValue(Context& context, SemIR::TypeId self_type_id) -> SemIR::InstId { + CARBON_CHECK(self_type_id == SemIR::ErrorInst::TypeId || + context.types().Is(self_type_id)); auto entity_name_id = context.entity_names().AddCanonical({ .name_id = SemIR::NameId::PeriodSelf, .parent_scope_id = context.scope_stack().PeekNameScopeId(), diff --git a/toolchain/check/facet_type.h b/toolchain/check/facet_type.h index 1d13fcaeee69..842c9ec85134 100644 --- a/toolchain/check/facet_type.h +++ b/toolchain/check/facet_type.h @@ -64,8 +64,10 @@ auto ResolveFacetTypeRewriteConstraints( // Introduce `.Self` as a symbolic binding into the current scope, and return // the `SymbolicBinding` instruction. // -// The `self_type_id` is either a facet type (as `FacetType`) or `type` (as -// `TypeType`). +// The type of `.Self` must be a `FacetType`, so that it gets wrapped in +// `FacetAccessType` when used in a type position, such as in `U:! I(.Self)`. +// This allows substitution with other facet values without requiring an +// additional `FacetAccessType` to be inserted. auto MakePeriodSelfFacetValue(Context& context, SemIR::TypeId self_type_id) -> SemIR::InstId; diff --git a/toolchain/check/handle_binding_pattern.cpp b/toolchain/check/handle_binding_pattern.cpp index b2f211c9d65b..9e9a8f9bf692 100644 --- a/toolchain/check/handle_binding_pattern.cpp +++ b/toolchain/check/handle_binding_pattern.cpp @@ -404,14 +404,7 @@ auto HandleParseNode(Context& context, // compile time binding. This is popped when handling the // CompileTimeBindingPatternId. context.scope_stack().PushForSameRegion(); - - // The `.Self` must have a type of `FacetType`, so that it gets wrapped in - // `FacetAccessType` when used in a type position, such as in `U:! I(.Self)`. - // This allows substitution with other facet values without requiring an - // additional `FacetAccessType` to be inserted. - auto type_id = GetEmptyFacetType(context); - - MakePeriodSelfFacetValue(context, type_id); + MakePeriodSelfFacetValue(context, GetEmptyFacetType(context)); return true; } diff --git a/toolchain/check/handle_where.cpp b/toolchain/check/handle_where.cpp index 5d977ef923f7..32d5267edb93 100644 --- a/toolchain/check/handle_where.cpp +++ b/toolchain/check/handle_where.cpp @@ -41,15 +41,22 @@ auto HandleParseNode(Context& context, Parse::WhereOperandId node_id) -> bool { // Any references to `.Self` in constraints for the current `WhereExpr` will // not see constraints in the `Self` facet type, but they will resolve to // values through the constraints explicitly when they are combined together. - auto self_without_constraints_type_id = self_with_constraints_type_id; - if (auto facet_type = context.types().TryGetAs( - self_without_constraints_type_id)) { + auto period_self_type_id = self_with_constraints_type_id; + if (auto facet_type = + context.types().TryGetAs(period_self_type_id)) { const auto& info = context.facet_types().Get(facet_type->facet_type_id); // TODO: Missing named constraints here. auto stripped_info = SemIR::FacetTypeInfo{.extend_constraints = info.extend_constraints}; stripped_info.Canonicalize(); - self_without_constraints_type_id = GetFacetType(context, stripped_info); + period_self_type_id = GetFacetType(context, stripped_info); + } else if (period_self_type_id == SemIR::TypeType::TypeId) { + // The self may be `TypeType` in `type where X impls Y`, so we use an empty + // facet type. + period_self_type_id = GetEmptyFacetType(context); + } else { + CARBON_CHECK(period_self_type_id == SemIR::ErrorInst::TypeId, + "unexpected .Self type {0}", period_self_type_id); } // Introduce a name scope so that we can remove the `.Self` entry we are @@ -58,7 +65,7 @@ auto HandleParseNode(Context& context, Parse::WhereOperandId node_id) -> bool { // Introduce `.Self` as a symbolic binding. Its type is the value of the // expression to the left of `where`, so `MyInterface` in the example above. auto period_self_inst_id = - MakePeriodSelfFacetValue(context, self_without_constraints_type_id); + MakePeriodSelfFacetValue(context, period_self_type_id); // Save the `.Self` symbolic binding on the node stack. It will become the // first argument to the `WhereExpr` instruction. diff --git a/toolchain/check/testdata/deduce/binding_pattern.carbon b/toolchain/check/testdata/deduce/binding_pattern.carbon index 5eb7762da5c5..9161cf6a7a7b 100644 --- a/toolchain/check/testdata/deduce/binding_pattern.carbon +++ b/toolchain/check/testdata/deduce/binding_pattern.carbon @@ -257,7 +257,7 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %type: type = facet_type [concrete] -// CHECK:STDOUT: %.Self.c39: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] @@ -271,7 +271,6 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.944: = require_complete_type %T [symbolic] // CHECK:STDOUT: %U: type = symbolic_binding U, 0 [symbolic] -// CHECK:STDOUT: %.Self.16f: type = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] @@ -281,24 +280,25 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %ImplicitAs.assoc_type.ff3: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic] // CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.b3a: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%Dest, %Self.738) [symbolic] // CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.1de: %ImplicitAs.WithSelf.Convert.type.b3a = struct_value () [symbolic] -// CHECK:STDOUT: %ImplicitAs.type.f60: type = facet_type <@ImplicitAs, @ImplicitAs(%.Self.16f)> [symbolic_self] -// CHECK:STDOUT: %type_where: type = facet_type [concrete] -// CHECK:STDOUT: %pattern_type.354: type = pattern_type %type_where [concrete] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] +// CHECK:STDOUT: %ImplicitAs.type.164: type = facet_type <@ImplicitAs, @ImplicitAs(%.Self.binding.as_type)> [symbolic_self] +// CHECK:STDOUT: %type_where: type = facet_type [symbolic_self] +// CHECK:STDOUT: %pattern_type.9a5: type = pattern_type %type_where [symbolic_self] // CHECK:STDOUT: %V: %type_where = symbolic_binding V, 1 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %V.binding.as_type: type = symbolic_binding_type V, 1, %V [symbolic] -// CHECK:STDOUT: %C.bca: type = class_type @C, @C(%V.binding.as_type) [symbolic] -// CHECK:STDOUT: %C.Create.type.242: type = fn_type @C.Create, @C(%V.binding.as_type) [symbolic] -// CHECK:STDOUT: %C.Create.206: %C.Create.type.242 = struct_value () [symbolic] -// CHECK:STDOUT: %require_complete.232: = require_complete_type %C.bca [symbolic] -// CHECK:STDOUT: %pattern_type.20b: type = pattern_type %V.binding.as_type [symbolic] -// CHECK:STDOUT: %C.Create.specific_fn: = specific_function %C.Create.206, @C.Create(%V.binding.as_type) [symbolic] -// CHECK:STDOUT: %require_complete.94b: = require_complete_type %V.binding.as_type [symbolic] -// CHECK:STDOUT: %ImplicitAs.type.ee4: type = facet_type <@ImplicitAs, @ImplicitAs(%V.binding.as_type)> [symbolic] -// CHECK:STDOUT: %ImplicitAs.assoc_type.f30: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%V.binding.as_type) [symbolic] -// CHECK:STDOUT: %assoc0.a1c: %ImplicitAs.assoc_type.f30 = assoc_entity element0, imports.%Core.import_ref.201 [symbolic] -// CHECK:STDOUT: %require_complete.24c: = require_complete_type %ImplicitAs.type.ee4 [symbolic] +// CHECK:STDOUT: %C.635: type = class_type @C, @C(%V.binding.as_type) [symbolic] +// CHECK:STDOUT: %C.Create.type.069: type = fn_type @C.Create, @C(%V.binding.as_type) [symbolic] +// CHECK:STDOUT: %C.Create.63a: %C.Create.type.069 = struct_value () [symbolic] +// CHECK:STDOUT: %require_complete.829: = require_complete_type %C.635 [symbolic] +// CHECK:STDOUT: %pattern_type.29e: type = pattern_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %C.Create.specific_fn: = specific_function %C.Create.63a, @C.Create(%V.binding.as_type) [symbolic] +// CHECK:STDOUT: %require_complete.3f7: = require_complete_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %ImplicitAs.type.3ee: type = facet_type <@ImplicitAs, @ImplicitAs(%V.binding.as_type)> [symbolic] +// CHECK:STDOUT: %ImplicitAs.assoc_type.efc: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%V.binding.as_type) [symbolic] +// CHECK:STDOUT: %assoc0.57e: %ImplicitAs.assoc_type.efc = assoc_entity element0, imports.%Core.import_ref.201 [symbolic] +// CHECK:STDOUT: %require_complete.8dc: = require_complete_type %ImplicitAs.type.3ee [symbolic] // CHECK:STDOUT: %assoc0.843: %ImplicitAs.assoc_type.ff3 = assoc_entity element0, imports.%Core.import_ref.cc1 [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -325,31 +325,33 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc4_13.1: type = splice_block %.loc4_13.2 [concrete = type] { -// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc4_13.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %T.loc4_10.2: type = symbolic_binding T, 0 [symbolic = %T.loc4_10.1 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %U.patt: %pattern_type.98f = symbolic_binding_pattern U, 0 [concrete] -// CHECK:STDOUT: %V.patt: %pattern_type.354 = symbolic_binding_pattern V, 1 [concrete] +// CHECK:STDOUT: %V.patt: %pattern_type.9a5 = symbolic_binding_pattern V, 1 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc9_17.1: type = splice_block %.loc9_17.2 [concrete = type] { -// CHECK:STDOUT: %.Self.3: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self.3: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc9_17.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %U.loc9_14.2: type = symbolic_binding U, 0 [symbolic = %U.loc9_14.1 (constants.%U)] -// CHECK:STDOUT: %.loc9_32.1: type = splice_block %.loc9_32.2 [concrete = constants.%type_where] { -// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.loc9_32.1: type = splice_block %.loc9_32.2 [symbolic_self = constants.%type_where] { +// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc9_27: type = type_literal type [concrete = type] -// CHECK:STDOUT: %.Self.2: type = symbolic_binding .Self [symbolic_self = constants.%.Self.16f] +// CHECK:STDOUT: %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc9_39.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %ImplicitAs.ref: %ImplicitAs.type.cc7 = name_ref ImplicitAs, imports.%Core.ImplicitAs [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.16f] -// CHECK:STDOUT: %ImplicitAs.type.loc9: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%.Self.16f)> [symbolic_self = constants.%ImplicitAs.type.f60] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc9_68: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %ImplicitAs.type.loc9: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%.Self.binding.as_type)> [symbolic_self = constants.%ImplicitAs.type.164] // CHECK:STDOUT: %.loc9_39.2: type = converted %.loc9_39.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %.loc9_32.2: type = where_expr %.Self.2 [concrete = constants.%type_where] { +// CHECK:STDOUT: %.loc9_32.2: type = where_expr %.Self.2 [symbolic_self = constants.%type_where] { // CHECK:STDOUT: requirement_base_facet_type type // CHECK:STDOUT: requirement_impls %.loc9_39.2, %ImplicitAs.type.loc9 // CHECK:STDOUT: } @@ -403,16 +405,16 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %V.binding.as_type: type = symbolic_binding_type V, 1, %V.loc9_24.1 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] -// CHECK:STDOUT: %C.loc20_6.2: type = class_type @C, @C(%V.binding.as_type) [symbolic = %C.loc20_6.2 (constants.%C.bca)] -// CHECK:STDOUT: %require_complete.loc20_7: = require_complete_type %C.loc20_6.2 [symbolic = %require_complete.loc20_7 (constants.%require_complete.232)] -// CHECK:STDOUT: %C.Create.type: type = fn_type @C.Create, @C(%V.binding.as_type) [symbolic = %C.Create.type (constants.%C.Create.type.242)] -// CHECK:STDOUT: %C.Create: @F.%C.Create.type (%C.Create.type.242) = struct_value () [symbolic = %C.Create (constants.%C.Create.206)] +// CHECK:STDOUT: %C.loc20_6.2: type = class_type @C, @C(%V.binding.as_type) [symbolic = %C.loc20_6.2 (constants.%C.635)] +// CHECK:STDOUT: %require_complete.loc20_7: = require_complete_type %C.loc20_6.2 [symbolic = %require_complete.loc20_7 (constants.%require_complete.829)] +// CHECK:STDOUT: %C.Create.type: type = fn_type @C.Create, @C(%V.binding.as_type) [symbolic = %C.Create.type (constants.%C.Create.type.069)] +// CHECK:STDOUT: %C.Create: @F.%C.Create.type (%C.Create.type.069) = struct_value () [symbolic = %C.Create (constants.%C.Create.63a)] // CHECK:STDOUT: %C.Create.specific_fn.loc20_7.2: = specific_function %C.Create, @C.Create(%V.binding.as_type) [symbolic = %C.Create.specific_fn.loc20_7.2 (constants.%C.Create.specific_fn)] -// CHECK:STDOUT: %require_complete.loc20_16.1: = require_complete_type %V.binding.as_type [symbolic = %require_complete.loc20_16.1 (constants.%require_complete.94b)] -// CHECK:STDOUT: %ImplicitAs.type.loc20_16.2: type = facet_type <@ImplicitAs, @ImplicitAs(%V.binding.as_type)> [symbolic = %ImplicitAs.type.loc20_16.2 (constants.%ImplicitAs.type.ee4)] -// CHECK:STDOUT: %require_complete.loc20_16.2: = require_complete_type %ImplicitAs.type.loc20_16.2 [symbolic = %require_complete.loc20_16.2 (constants.%require_complete.24c)] -// CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%V.binding.as_type) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.f30)] -// CHECK:STDOUT: %assoc0: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.f30) = assoc_entity element0, imports.%Core.import_ref.201 [symbolic = %assoc0 (constants.%assoc0.a1c)] +// CHECK:STDOUT: %require_complete.loc20_16.1: = require_complete_type %V.binding.as_type [symbolic = %require_complete.loc20_16.1 (constants.%require_complete.3f7)] +// CHECK:STDOUT: %ImplicitAs.type.loc20_16.2: type = facet_type <@ImplicitAs, @ImplicitAs(%V.binding.as_type)> [symbolic = %ImplicitAs.type.loc20_16.2 (constants.%ImplicitAs.type.3ee)] +// CHECK:STDOUT: %require_complete.loc20_16.2: = require_complete_type %ImplicitAs.type.loc20_16.2 [symbolic = %require_complete.loc20_16.2 (constants.%require_complete.8dc)] +// CHECK:STDOUT: %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%V.binding.as_type) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.efc)] +// CHECK:STDOUT: %assoc0: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.efc) = assoc_entity element0, imports.%Core.import_ref.201 [symbolic = %assoc0 (constants.%assoc0.57e)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { // CHECK:STDOUT: !entry: @@ -420,14 +422,14 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %V.ref: %type_where = name_ref V, %V.loc9_24.2 [symbolic = %V.loc9_24.1 (constants.%V)] // CHECK:STDOUT: %V.as_type: type = facet_access_type %V.ref [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] // CHECK:STDOUT: %.loc20_6: type = converted %V.ref, %V.as_type [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] -// CHECK:STDOUT: %C.loc20_6.1: type = class_type @C, @C(constants.%V.binding.as_type) [symbolic = %C.loc20_6.2 (constants.%C.bca)] -// CHECK:STDOUT: %.loc20_7: @F.%C.Create.type (%C.Create.type.242) = specific_constant @C.%C.Create.decl, @C(constants.%V.binding.as_type) [symbolic = %C.Create (constants.%C.Create.206)] -// CHECK:STDOUT: %Create.ref: @F.%C.Create.type (%C.Create.type.242) = name_ref Create, %.loc20_7 [symbolic = %C.Create (constants.%C.Create.206)] +// CHECK:STDOUT: %C.loc20_6.1: type = class_type @C, @C(constants.%V.binding.as_type) [symbolic = %C.loc20_6.2 (constants.%C.635)] +// CHECK:STDOUT: %.loc20_7: @F.%C.Create.type (%C.Create.type.069) = specific_constant @C.%C.Create.decl, @C(constants.%V.binding.as_type) [symbolic = %C.Create (constants.%C.Create.63a)] +// CHECK:STDOUT: %Create.ref: @F.%C.Create.type (%C.Create.type.069) = name_ref Create, %.loc20_7 [symbolic = %C.Create (constants.%C.Create.63a)] // CHECK:STDOUT: %.loc20_16.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] // CHECK:STDOUT: %C.Create.specific_fn.loc20_7.1: = specific_function %Create.ref, @C.Create(constants.%V.binding.as_type) [symbolic = %C.Create.specific_fn.loc20_7.2 (constants.%C.Create.specific_fn)] -// CHECK:STDOUT: %ImplicitAs.type.loc20_16.1: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%V.binding.as_type)> [symbolic = %ImplicitAs.type.loc20_16.2 (constants.%ImplicitAs.type.ee4)] -// CHECK:STDOUT: %.loc20_16.2: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.f30) = specific_constant imports.%Core.import_ref.178, @ImplicitAs.WithSelf(constants.%V.binding.as_type, constants.%Self.738) [symbolic = %assoc0 (constants.%assoc0.a1c)] -// CHECK:STDOUT: %Convert.ref: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.f30) = name_ref Convert, %.loc20_16.2 [symbolic = %assoc0 (constants.%assoc0.a1c)] +// CHECK:STDOUT: %ImplicitAs.type.loc20_16.1: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%V.binding.as_type)> [symbolic = %ImplicitAs.type.loc20_16.2 (constants.%ImplicitAs.type.3ee)] +// CHECK:STDOUT: %.loc20_16.2: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.efc) = specific_constant imports.%Core.import_ref.178, @ImplicitAs.WithSelf(constants.%V.binding.as_type, constants.%Self.738) [symbolic = %assoc0 (constants.%assoc0.57e)] +// CHECK:STDOUT: %Convert.ref: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.efc) = name_ref Convert, %.loc20_16.2 [symbolic = %assoc0 (constants.%assoc0.57e)] // CHECK:STDOUT: %.loc20_16.3: @F.%V.binding.as_type (%V.binding.as_type) = converted %.loc20_16.1, [concrete = ] // CHECK:STDOUT: %C.Create.call: init %empty_tuple.type = call %C.Create.specific_fn.loc20_7.1() // CHECK:STDOUT: return @@ -456,15 +458,15 @@ fn F(unused U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %T.loc4_10.1 => constants.%V.binding.as_type // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %C.Create.type => constants.%C.Create.type.242 -// CHECK:STDOUT: %C.Create => constants.%C.Create.206 +// CHECK:STDOUT: %C.Create.type => constants.%C.Create.type.069 +// CHECK:STDOUT: %C.Create => constants.%C.Create.63a // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @C.Create(constants.%V.binding.as_type) { // CHECK:STDOUT: %T => constants.%V.binding.as_type -// CHECK:STDOUT: %pattern_type => constants.%pattern_type.20b +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.29e // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%require_complete.94b +// CHECK:STDOUT: %require_complete => constants.%require_complete.3f7 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/convert_facet_value_to_narrowed_facet_type.carbon b/toolchain/check/testdata/facet/convert_facet_value_to_narrowed_facet_type.carbon index 329bdc350ff9..603e94ba1df6 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_to_narrowed_facet_type.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_to_narrowed_facet_type.carbon @@ -959,7 +959,7 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %type: type = facet_type [concrete] -// CHECK:STDOUT: %.Self.c39: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %T.67db0b.1: type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.51d: type = pattern_type %T.67db0b.1 [symbolic] @@ -967,7 +967,7 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %TakesTypeDeduced: %TakesTypeDeduced.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.944: = require_complete_type %T.67db0b.1 [symbolic] -// CHECK:STDOUT: %.Self.16f: type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] // CHECK:STDOUT: %pattern_type.9a5: type = pattern_type %type [concrete] // CHECK:STDOUT: %U: %type = symbolic_binding U, 0 [symbolic] // CHECK:STDOUT: %U.binding.as_type: type = symbolic_binding_type U, 0, %U [symbolic] @@ -1006,7 +1006,7 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %x.patt: @TakesTypeDeduced.%pattern_type (%pattern_type.51d) = at_binding_pattern x, %x.param_patt [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc3_25.1: type = splice_block %.loc3_25.2 [concrete = type] { -// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc3_25.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %T.loc3_22.2: type = symbolic_binding T, 0 [symbolic = %T.loc3_22.1 (constants.%T.67db0b.1)] @@ -1020,14 +1020,16 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %y.patt: @CallsWithExtraWhere.%pattern_type (%pattern_type.349) = at_binding_pattern y, %y.param_patt [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc4_33.1: type = splice_block %.loc4_33.2 [concrete = constants.%type] { -// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc4_28: type = type_literal type [concrete = type] -// CHECK:STDOUT: %.Self.2: type = symbolic_binding .Self [symbolic_self = constants.%.Self.16f] -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.16f] +// CHECK:STDOUT: %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc4_51: type = type_literal type [concrete = type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc4_39: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc4_33.2: type = where_expr %.Self.2 [concrete = constants.%type] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %.loc4_51 +// CHECK:STDOUT: requirement_impls %.loc4_39, %.loc4_51 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %U.loc4_25.2: %type = symbolic_binding U, 0 [symbolic = %U.loc4_25.1 (constants.%U)] @@ -1043,7 +1045,7 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc8_33.1: type = splice_block %.loc8_33.2 [concrete = type] { -// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc8_33.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %T.loc8_30.3: type = symbolic_binding T, 0 [symbolic = %T.loc8_30.2 (constants.%T.67db0b.2)] @@ -1052,14 +1054,16 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %U.patt: %pattern_type.9a5 = symbolic_binding_pattern U, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc9_41.1: type = splice_block %.loc9_41.2 [concrete = constants.%type] { -// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc9_36: type = type_literal type [concrete = type] -// CHECK:STDOUT: %.Self.2: type = symbolic_binding .Self [symbolic_self = constants.%.Self.16f] -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.16f] +// CHECK:STDOUT: %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc9_59: type = type_literal type [concrete = type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc9_47: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc9_41.2: type = where_expr %.Self.2 [concrete = constants.%type] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %.loc9_59 +// CHECK:STDOUT: requirement_impls %.loc9_47, %.loc9_59 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %U.loc9_33.2: %type = symbolic_binding U, 0 [symbolic = %U.loc9_33.1 (constants.%U)] @@ -1168,8 +1172,8 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %type: type = facet_type [concrete] -// CHECK:STDOUT: %.Self.c39: %type = symbolic_binding .Self [symbolic_self] -// CHECK:STDOUT: %.Self.16f: type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] // CHECK:STDOUT: %pattern_type.9a5: type = pattern_type %type [concrete] // CHECK:STDOUT: %T.f45530.1: %type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.f45530.1 [symbolic] @@ -1216,14 +1220,16 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %x.patt: @TakesExtraWhereDeduced.%pattern_type (%pattern_type.349) = at_binding_pattern x, %x.param_patt [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc3_36.1: type = splice_block %.loc3_36.2 [concrete = constants.%type] { -// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc3_31: type = type_literal type [concrete = type] -// CHECK:STDOUT: %.Self.2: type = symbolic_binding .Self [symbolic_self = constants.%.Self.16f] -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.16f] +// CHECK:STDOUT: %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc3_54: type = type_literal type [concrete = type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc3_42: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc3_36.2: type = where_expr %.Self.2 [concrete = constants.%type] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %.loc3_54 +// CHECK:STDOUT: requirement_impls %.loc3_42, %.loc3_54 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %T.loc3_28.2: %type = symbolic_binding T, 0 [symbolic = %T.loc3_28.1 (constants.%T.f45530.1)] @@ -1241,7 +1247,7 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %y.patt: @CallsWithType.%pattern_type (%pattern_type.51d) = at_binding_pattern y, %y.param_patt [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc4_22.1: type = splice_block %.loc4_22.2 [concrete = type] { -// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc4_22.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %U.loc4_19.2: type = symbolic_binding U, 0 [symbolic = %U.loc4_19.1 (constants.%U)] @@ -1253,14 +1259,16 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %T.patt: %pattern_type.9a5 = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc8_44.1: type = splice_block %.loc8_44.2 [concrete = constants.%type] { -// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc8_39: type = type_literal type [concrete = type] -// CHECK:STDOUT: %.Self.2: type = symbolic_binding .Self [symbolic_self = constants.%.Self.16f] -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.16f] +// CHECK:STDOUT: %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc8_62: type = type_literal type [concrete = type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_50: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc8_44.2: type = where_expr %.Self.2 [concrete = constants.%type] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %.loc8_62 +// CHECK:STDOUT: requirement_impls %.loc8_50, %.loc8_62 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %T.loc8_36.3: %type = symbolic_binding T, 0 [symbolic = %T.loc8_36.2 (constants.%T.f45530.2)] @@ -1269,7 +1277,7 @@ fn CallsWithTypeExplicit(U:! type) { // CHECK:STDOUT: %U.patt: %pattern_type.98f = symbolic_binding_pattern U, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc9_30.1: type = splice_block %.loc9_30.2 [concrete = type] { -// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc9_30.2: type = type_literal type [concrete = type] // CHECK:STDOUT: } // CHECK:STDOUT: %U.loc9_27.2: type = symbolic_binding U, 0 [symbolic = %U.loc9_27.1 (constants.%U)] diff --git a/toolchain/check/testdata/facet/validate_impl_constraints.carbon b/toolchain/check/testdata/facet/validate_impl_constraints.carbon index 04c62cf7358c..ecce9108e3a6 100644 --- a/toolchain/check/testdata/facet/validate_impl_constraints.carbon +++ b/toolchain/check/testdata/facet/validate_impl_constraints.carbon @@ -55,12 +55,12 @@ impl forall [U:! L] C(U) as M where .M0 = {} {} fn F(unused U:! type where C(.Self) impls (M where .M0 = {})) {} fn G(T:! L) { - // CHECK:STDERR: fail_todo_where_impls_tests_associated_constant_of_generic_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `L` into type implementing `type where...` [ConversionFailureFacetToFacet] + // CHECK:STDERR: fail_todo_where_impls_tests_associated_constant_of_generic_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `L` into type implementing `type where C(.Self) impls M and .(M.M0) = {}` [ConversionFailureFacetToFacet] // CHECK:STDERR: F(T); // CHECK:STDERR: ^~~~ - // CHECK:STDERR: fail_todo_where_impls_tests_associated_constant_of_generic_type.carbon:[[@LINE-6]]:13: note: initializing generic parameter `U` declared here [InitializingGenericParam] + // CHECK:STDERR: fail_todo_where_impls_tests_associated_constant_of_generic_type.carbon:[[@LINE-6]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] // CHECK:STDERR: fn F(unused U:! type where C(.Self) impls (M where .M0 = {})) {} - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: F(T); } @@ -81,12 +81,12 @@ impl forall [U:! L] C(U) as M where .M0 = () {} fn F(unused U:! type where C(.Self) impls (M where .M0 = {})) {} fn G(T:! L) { - // CHECK:STDERR: fail_where_impls_tests_associated_constant_of_generic_type_type_differs.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `L` into type implementing `type where...` [ConversionFailureFacetToFacet] + // CHECK:STDERR: fail_where_impls_tests_associated_constant_of_generic_type_type_differs.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `L` into type implementing `type where C(.Self) impls M and .(M.M0) = {}` [ConversionFailureFacetToFacet] // CHECK:STDERR: F(T); // CHECK:STDERR: ^~~~ - // CHECK:STDERR: fail_where_impls_tests_associated_constant_of_generic_type_type_differs.carbon:[[@LINE-6]]:13: note: initializing generic parameter `U` declared here [InitializingGenericParam] + // CHECK:STDERR: fail_where_impls_tests_associated_constant_of_generic_type_type_differs.carbon:[[@LINE-6]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] // CHECK:STDERR: fn F(unused U:! type where C(.Self) impls (M where .M0 = {})) {} - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: F(T); } @@ -130,3 +130,70 @@ fn F(unused T:! I(.Self) where .Self impls Z) {} fn G(T:! Z & I(.Self)) { F(T); } + +// --- fail_todo_where_period_self_rhs_sees_lhs.carbon +library "[[@TEST_NAME]]"; + +interface Z {} +interface Y {} +interface X(T:! Z & Y) {} + +constraint N { + require impls Y; +} + +// The RHS of `where` can see the extend constraints on the LHS of `where`. +// CHECK:STDERR: fail_todo_where_period_self_rhs_sees_lhs.carbon:[[@LINE+7]]:34: error: cannot convert type `.Self` that implements `Z` into type implementing `Z & Y` [ConversionFailureFacetToFacet] +// CHECK:STDERR: fn F(_:! Z & N where .Self impls X(.Self)) {} +// CHECK:STDERR: ^~~~~~~~ +// CHECK:STDERR: fail_todo_where_period_self_rhs_sees_lhs.carbon:[[@LINE-10]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam] +// CHECK:STDERR: interface X(T:! Z & Y) {} +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +fn F(_:! Z & N where .Self impls X(.Self)) {} + +fn G() { + class C; + impl C as Z {} + impl C as Y {} + impl C as X(C) {} + F(C); +} + +// --- fail_todo_where_type_rhs_sees_lhs.carbon +library "[[@TEST_NAME]]"; + +interface Z {} +interface Y {} +interface X(T:! Z & Y) {} + +constraint N { + require impls Y; +} + +class R(T:! Z & Y); + +// The RHS of `where` can see the extend constraints on the LHS of `where`. +// CHECK:STDERR: fail_todo_where_type_rhs_sees_lhs.carbon:[[@LINE+14]]:22: error: cannot convert type `.Self` that implements `Z` into type implementing `Z & Y` [ConversionFailureFacetToFacet] +// CHECK:STDERR: fn F(_:! Z & N where R(.Self) impls X(.Self)) {} +// CHECK:STDERR: ^~~~~~~~ +// CHECK:STDERR: fail_todo_where_type_rhs_sees_lhs.carbon:[[@LINE-6]]:9: note: initializing generic parameter `T` declared here [InitializingGenericParam] +// CHECK:STDERR: class R(T:! Z & Y); +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_todo_where_type_rhs_sees_lhs.carbon:[[@LINE+7]]:37: error: cannot convert type `.Self` that implements `Z` into type implementing `Z & Y` [ConversionFailureFacetToFacet] +// CHECK:STDERR: fn F(_:! Z & N where R(.Self) impls X(.Self)) {} +// CHECK:STDERR: ^~~~~~~~ +// CHECK:STDERR: fail_todo_where_type_rhs_sees_lhs.carbon:[[@LINE-19]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam] +// CHECK:STDERR: interface X(T:! Z & Y) {} +// CHECK:STDERR: ^~~~~~~~~ +// CHECK:STDERR: +fn F(_:! Z & N where R(.Self) impls X(.Self)) {} + +fn G() { + class C; + impl C as Z {} + impl C as Y {} + impl R(C) as X(C) {} + F(C); +} diff --git a/toolchain/check/testdata/impl/assoc_const_self.carbon b/toolchain/check/testdata/impl/assoc_const_self.carbon index 7c980546791b..afcde64fa908 100644 --- a/toolchain/check/testdata/impl/assoc_const_self.carbon +++ b/toolchain/check/testdata/impl/assoc_const_self.carbon @@ -90,12 +90,12 @@ fn F(T:! I where {} impls Core.ImplicitAs(.Self) and .V = {}); fn CallF() { // TODO: This call should eventually work. - // CHECK:STDERR: fail_todo_constrained_fn.carbon:[[@LINE+7]]:3: error: cannot convert type `{}` into type implementing `I where .(I.V) = {} and...` [ConversionFailureTypeToFacet] + // CHECK:STDERR: fail_todo_constrained_fn.carbon:[[@LINE+7]]:3: error: cannot convert type `{}` into type implementing `I where {} impls Core.ImplicitAs(.Self) and .(I.V) = {}` [ConversionFailureTypeToFacet] // CHECK:STDERR: F({}); // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: fail_todo_constrained_fn.carbon:[[@LINE-7]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam] + // CHECK:STDERR: fail_todo_constrained_fn.carbon:[[@LINE-7]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] // CHECK:STDERR: fn F(T:! I where {} impls Core.ImplicitAs(.Self) and .V = {}); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: F({}); } @@ -742,10 +742,10 @@ fn CallF() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self.1dc [symbolic_self] // CHECK:STDOUT: %ImplicitAs.type.d65: type = facet_type <@ImplicitAs, @ImplicitAs(%.Self.binding.as_type)> [symbolic_self] -// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.1dc, @I [symbolic_self] -// CHECK:STDOUT: %impl.elem0: %.Self.binding.as_type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] -// CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_struct and TODO> [concrete] -// CHECK:STDOUT: %pattern_type.d53: type = pattern_type %I_where.type [concrete] +// CHECK:STDOUT: %I.lookup_impl_witness.c4b: = lookup_impl_witness %.Self.1dc, @I [symbolic_self] +// CHECK:STDOUT: %impl.elem0: %.Self.binding.as_type = impl_witness_access %I.lookup_impl_witness.c4b, element0 [symbolic_self] +// CHECK:STDOUT: %I_where.type: type = facet_type <@I where %empty_struct_type impls @ImplicitAs, @ImplicitAs(%.Self.binding.as_type) and %impl.elem0 = %empty_struct> [symbolic_self] +// CHECK:STDOUT: %pattern_type.81c: type = pattern_type %I_where.type [symbolic_self] // CHECK:STDOUT: %T: %I_where.type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] @@ -772,9 +772,9 @@ fn CallF() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %T.patt: %pattern_type.d53 = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.81c = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %.loc8_12.1: type = splice_block %.loc8_12.2 [concrete = constants.%I_where.type] { +// CHECK:STDOUT: %.loc8_12.1: type = splice_block %.loc8_12.2 [symbolic_self = constants.%I_where.type] { // CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.c39] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %.Self.2: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self.1dc] @@ -790,11 +790,11 @@ fn CallF() { // CHECK:STDOUT: %.Self.as_type.loc8_54: type = facet_access_type %.Self.ref.loc8_54 [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc8_54: type = converted %.Self.ref.loc8_54, %.Self.as_type.loc8_54 [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %V.ref: %I.assoc_type = name_ref V, @V.%assoc0 [concrete = constants.%assoc0.490] -// CHECK:STDOUT: %impl.elem0: %.Self.binding.as_type = impl_witness_access constants.%I.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0] +// CHECK:STDOUT: %impl.elem0: %.Self.binding.as_type = impl_witness_access constants.%I.lookup_impl_witness.c4b, element0 [symbolic_self = constants.%impl.elem0] // CHECK:STDOUT: %.loc8_60.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] // CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete = constants.%empty_struct] // CHECK:STDOUT: %.loc8_60.2: %empty_struct_type = converted %.loc8_60.1, %empty_struct [concrete = constants.%empty_struct] -// CHECK:STDOUT: %.loc8_12.2: type = where_expr %.Self.2 [concrete = constants.%I_where.type] { +// CHECK:STDOUT: %.loc8_12.2: type = where_expr %.Self.2 [symbolic_self = constants.%I_where.type] { // CHECK:STDOUT: requirement_base_facet_type constants.%I.type // CHECK:STDOUT: requirement_impls %.loc8_19.2, %ImplicitAs.type // CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc8_60.2 diff --git a/toolchain/check/testdata/impl/fail_impl_bad_interface.carbon b/toolchain/check/testdata/impl/fail_impl_bad_interface.carbon index a65250a5f087..31bec456e082 100644 --- a/toolchain/check/testdata/impl/fail_impl_bad_interface.carbon +++ b/toolchain/check/testdata/impl/fail_impl_bad_interface.carbon @@ -136,8 +136,9 @@ impl {.a: bool} as type where .Self impls I {} // CHECK:STDOUT: %Float.type: type = generic_class_type @Float [concrete] // CHECK:STDOUT: %Float.generic: %Float.type = struct_value () [concrete] // CHECK:STDOUT: %f64: type = class_type @Float, @Float(%int_64) [concrete] -// CHECK:STDOUT: %.Self: type = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -157,12 +158,14 @@ impl {.a: bool} as type where .Self impls I {} // CHECK:STDOUT: impl_decl @f64.as..impl [concrete] {} { // CHECK:STDOUT: %f64: type = type_literal constants.%f64 [concrete = constants.%f64] // CHECK:STDOUT: %.loc8_13: type = type_literal type [concrete = type] -// CHECK:STDOUT: %.Self: type = symbolic_binding .Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc8_36: type = type_literal type [concrete = type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_24: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc8_18: type = where_expr %.Self [concrete = constants.%type] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %.loc8_36 +// CHECK:STDOUT: requirement_impls %.loc8_24, %.loc8_36 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -180,7 +183,9 @@ impl {.a: bool} as type where .Self impls I {} // CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete] // CHECK:STDOUT: %Bool: %Bool.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: bool} [concrete] -// CHECK:STDOUT: %.Self: type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] // CHECK:STDOUT: %type_where: type = facet_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -204,12 +209,14 @@ impl {.a: bool} as type where .Self impls I {} // CHECK:STDOUT: %.loc10_11: type = type_literal bool [concrete = bool] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: bool} [concrete = constants.%struct_type.a] // CHECK:STDOUT: %.loc10_20: type = type_literal type [concrete = type] -// CHECK:STDOUT: %.Self: type = symbolic_binding .Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc10_31: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc10_25: type = where_expr %.Self [concrete = constants.%type_where] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %I.ref +// CHECK:STDOUT: requirement_impls %.loc10_31, %I.ref // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/interface/fail_lookup_in_type_type.carbon b/toolchain/check/testdata/interface/fail_lookup_in_type_type.carbon index 7e3411e64130..7b1f15e098af 100644 --- a/toolchain/check/testdata/interface/fail_lookup_in_type_type.carbon +++ b/toolchain/check/testdata/interface/fail_lookup_in_type_type.carbon @@ -59,8 +59,9 @@ let U: (type where .Self impls type).missing = {}; // CHECK:STDOUT: --- fail_lookup_type_where.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %.Self: type = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] // CHECK:STDOUT: } @@ -74,12 +75,14 @@ let U: (type where .Self impls type).missing = {}; // CHECK:STDOUT: } // CHECK:STDOUT: %.1: = splice_block [concrete = ] { // CHECK:STDOUT: %.loc8_9: type = type_literal type [concrete = type] -// CHECK:STDOUT: %.Self: type = symbolic_binding .Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %.loc8_32: type = type_literal type [concrete = type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_20: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc8_14: type = where_expr %.Self [concrete = constants.%type] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %.loc8_32 +// CHECK:STDOUT: requirement_impls %.loc8_20, %.loc8_32 // CHECK:STDOUT: } // CHECK:STDOUT: %missing.ref: = name_ref missing, [concrete = ] // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/named_constraint/extend_name_lookup.carbon b/toolchain/check/testdata/named_constraint/extend_name_lookup.carbon index 12290e98419f..0f69130a08a1 100644 --- a/toolchain/check/testdata/named_constraint/extend_name_lookup.carbon +++ b/toolchain/check/testdata/named_constraint/extend_name_lookup.carbon @@ -192,7 +192,9 @@ fn F(T:! type where .Self impls W) { // CHECK:STDOUT: %Y.assoc_type: type = assoc_entity_type @Y [concrete] // CHECK:STDOUT: %assoc0.2e5: %Y.assoc_type = assoc_entity element0, @Y.WithSelf.%Y.WithSelf.YF.decl [concrete] // CHECK:STDOUT: %W.type: type = facet_type <@W> [concrete] -// CHECK:STDOUT: %.Self.16f: type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] // CHECK:STDOUT: %type_where: type = facet_type [concrete] // CHECK:STDOUT: %pattern_type: type = pattern_type %type_where [concrete] // CHECK:STDOUT: %T: %type_where = symbolic_binding T, 0 [symbolic] @@ -221,11 +223,13 @@ fn F(T:! type where .Self impls W) { // CHECK:STDOUT: // CHECK:STDOUT: %.loc12_10: type = type_literal type [concrete = type] // CHECK:STDOUT: -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.16f] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %W.ref: type = name_ref W, file.%W.decl [concrete = constants.%W.type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc12_21: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc12_15.2: type = where_expr %.Self.2 [concrete = constants.%type_where] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %W.ref +// CHECK:STDOUT: requirement_impls %.loc12_21, %W.ref // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %T.loc12_7.2: %type_where = symbolic_binding T, 0 [symbolic = %T.loc12_7.1 (constants.%T)] diff --git a/toolchain/check/testdata/named_constraint/require.carbon b/toolchain/check/testdata/named_constraint/require.carbon index 1457251ae68a..0982332e5e0b 100644 --- a/toolchain/check/testdata/named_constraint/require.carbon +++ b/toolchain/check/testdata/named_constraint/require.carbon @@ -226,9 +226,7 @@ library "[[@TEST_NAME]]"; class C(T:! type); constraint Z { - // TODO: This should be a RequireImplsReferenceCycle error since `Z` is being - // used inside `Z`. - // CHECK:STDERR: fail_require_impls_incomplete_self_in_class_impls.carbon:[[@LINE+4]]:17: error: semantics TODO: `facet type has constraints that we don't handle yet` [SemanticsTodo] + // CHECK:STDERR: fail_require_impls_incomplete_self_in_class_impls.carbon:[[@LINE+4]]:17: error: facet type in `require` declaration refers to the named constraint `Z` from within its definition [RequireImplsReferenceCycle] // CHECK:STDERR: require impls type where C(.Self) impls Z; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: diff --git a/toolchain/check/testdata/where_expr/constraints.carbon b/toolchain/check/testdata/where_expr/constraints.carbon index 0f384d9d4e67..7ea76245f5cc 100644 --- a/toolchain/check/testdata/where_expr/constraints.carbon +++ b/toolchain/check/testdata/where_expr/constraints.carbon @@ -431,8 +431,8 @@ fn F() { // CHECK:STDOUT: %K.lookup_impl_witness: = lookup_impl_witness %.Self.2ca, @K [symbolic_self] // CHECK:STDOUT: %impl.elem0: %L.type = impl_witness_access %K.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem0 [symbolic_self] -// CHECK:STDOUT: %K_where.type: type = facet_type <@K where TODO> [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %K_where.type [concrete] +// CHECK:STDOUT: %K_where.type: type = facet_type <@K where %impl.elem0 impls @M> [symbolic_self] +// CHECK:STDOUT: %pattern_type: type = pattern_type %K_where.type [symbolic_self] // CHECK:STDOUT: %W: %K_where.type = symbolic_binding W, 0 [symbolic] // CHECK:STDOUT: %AssociatedTypeImpls.type: type = fn_type @AssociatedTypeImpls [concrete] // CHECK:STDOUT: %AssociatedTypeImpls: %AssociatedTypeImpls.type = struct_value () [concrete] @@ -442,7 +442,7 @@ fn F() { // CHECK:STDOUT: %AssociatedTypeImpls.decl: %AssociatedTypeImpls.type = fn_decl @AssociatedTypeImpls [concrete = constants.%AssociatedTypeImpls] { // CHECK:STDOUT: %W.patt: %pattern_type = symbolic_binding_pattern W, 0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %.loc12_30.1: type = splice_block %.loc12_30.2 [concrete = constants.%K_where.type] { +// CHECK:STDOUT: %.loc12_30.1: type = splice_block %.loc12_30.2 [symbolic_self = constants.%K_where.type] { // CHECK:STDOUT: // CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [concrete = constants.%K.type] // CHECK:STDOUT: @@ -454,7 +454,7 @@ fn F() { // CHECK:STDOUT: %M.ref: type = name_ref M, file.%M.decl [concrete = constants.%M.type] // CHECK:STDOUT: %as_type: type = facet_access_type %impl.elem0 [symbolic_self = constants.%as_type] // CHECK:STDOUT: %.loc12_36.2: type = converted %impl.elem0, %as_type [symbolic_self = constants.%as_type] -// CHECK:STDOUT: %.loc12_30.2: type = where_expr %.Self.2 [concrete = constants.%K_where.type] { +// CHECK:STDOUT: %.loc12_30.2: type = where_expr %.Self.2 [symbolic_self = constants.%K_where.type] { // CHECK:STDOUT: requirement_base_facet_type constants.%K.type // CHECK:STDOUT: requirement_impls %.loc12_36.2, %M.ref // CHECK:STDOUT: } @@ -476,7 +476,9 @@ fn F() { // CHECK:STDOUT: --- fail_error_in_constraint.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %.Self.16f: type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] // CHECK:STDOUT: %WithError.type: type = fn_type @WithError [concrete] // CHECK:STDOUT: %WithError: %WithError.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -489,11 +491,13 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: %.loc9_18: type = type_literal type [concrete = type] // CHECK:STDOUT: -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.16f] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] // CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc9_29: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] // CHECK:STDOUT: %.loc9_23.2: type = where_expr %.Self.2 [concrete = ] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, +// CHECK:STDOUT: requirement_impls %.loc9_29, // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %U: = symbolic_binding U, 0 [concrete = ] diff --git a/toolchain/check/testdata/where_expr/designator.carbon b/toolchain/check/testdata/where_expr/designator.carbon index cb593d5c2e4f..542b26b88246 100644 --- a/toolchain/check/testdata/where_expr/designator.carbon +++ b/toolchain/check/testdata/where_expr/designator.carbon @@ -145,6 +145,8 @@ fn G(unused T:! type where C(()) impls I(.Self)) {} // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.WithSelf.%Member [concrete] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self.c39: %type = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %.Self.1dc: %I.type = symbolic_binding .Self [symbolic_self] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] @@ -153,13 +155,13 @@ fn G(unused T:! type where C(()) impls I(.Self)) {} // CHECK:STDOUT: %T: %I_where.type = symbolic_binding T, 0 [symbolic] // CHECK:STDOUT: %PeriodSelf.type: type = fn_type @PeriodSelf [concrete] // CHECK:STDOUT: %PeriodSelf: %PeriodSelf.type = struct_value () [concrete] -// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self.1dc [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type.15d: type = symbolic_binding_type .Self, %.Self.1dc [symbolic_self] // CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self.1dc, @I [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %U: %I_where.type = symbolic_binding U, 0 [symbolic] // CHECK:STDOUT: %PeriodMember.type: type = fn_type @PeriodMember [concrete] // CHECK:STDOUT: %PeriodMember: %PeriodMember.type = struct_value () [concrete] -// CHECK:STDOUT: %.Self.16f: type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type.8db: type = symbolic_binding_type .Self, %.Self.c39 [symbolic_self] // CHECK:STDOUT: %type_where: type = facet_type [concrete] // CHECK:STDOUT: %pattern_type.17f: type = pattern_type %type_where [concrete] // CHECK:STDOUT: %V: %type_where = symbolic_binding V, 0 [symbolic] @@ -192,8 +194,8 @@ fn G(unused T:! type where C(()) impls I(.Self)) {} // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: // CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.1dc] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] -// CHECK:STDOUT: %.loc11_29: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type.15d] +// CHECK:STDOUT: %.loc11_29: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type.15d] // CHECK:STDOUT: %Member.ref: %I.assoc_type = name_ref Member, @Member.%assoc0 [concrete = constants.%assoc0] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access constants.%I.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0] // CHECK:STDOUT: %.loc11_41: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] @@ -211,11 +213,13 @@ fn G(unused T:! type where C(()) impls I(.Self)) {} // CHECK:STDOUT: // CHECK:STDOUT: %.loc13_22: type = type_literal type [concrete = type] // CHECK:STDOUT: -// CHECK:STDOUT: %.Self.ref: type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.16f] +// CHECK:STDOUT: %.Self.ref: %type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.c39] // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type.8db] +// CHECK:STDOUT: %.loc13_33: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type.8db] // CHECK:STDOUT: %.loc13_27.2: type = where_expr %.Self.2 [concrete = constants.%type_where] { // CHECK:STDOUT: requirement_base_facet_type type -// CHECK:STDOUT: requirement_impls %.Self.ref, %I.ref +// CHECK:STDOUT: requirement_impls %.loc13_33, %I.ref // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %V.loc13_19.2: %type_where = symbolic_binding V, 0 [symbolic = %V.loc13_19.1 (constants.%V)] diff --git a/toolchain/sem_ir/stringify.cpp b/toolchain/sem_ir/stringify.cpp index 695f33820f4a..518674d7c475 100644 --- a/toolchain/sem_ir/stringify.cpp +++ b/toolchain/sem_ir/stringify.cpp @@ -749,7 +749,7 @@ class Stringifier { if (some_where) { step_stack_->PushString(" and"); } - step_stack_->Push(type_impls.self_type, " impls ", + step_stack_->Push(" ", type_impls.self_type, " impls ", type_impls.specific_interface); some_where = true; } @@ -758,7 +758,7 @@ class Stringifier { if (some_where) { step_stack_->PushString(" and"); } - step_stack_->Push(type_impls.self_type, " impls ", + step_stack_->Push(" ", type_impls.self_type, " impls ", type_impls.specific_named_constraint); some_where = true; }