diff --git a/toolchain/check/handle_where.cpp b/toolchain/check/handle_where.cpp index 32d5267edb93..280733400453 100644 --- a/toolchain/check/handle_where.cpp +++ b/toolchain/check/handle_where.cpp @@ -45,9 +45,7 @@ auto HandleParseNode(Context& context, Parse::WhereOperandId node_id) -> bool { 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}; + auto stripped_info = SemIR::FacetTypeInfo::ExtendedOnly(info); stripped_info.Canonicalize(); period_self_type_id = GetFacetType(context, stripped_info); } else if (period_self_type_id == SemIR::TypeType::TypeId) { diff --git a/toolchain/check/testdata/facet/validate_impl_constraints.carbon b/toolchain/check/testdata/facet/validate_impl_constraints.carbon index ecce9108e3a6..f9eba34f24c6 100644 --- a/toolchain/check/testdata/facet/validate_impl_constraints.carbon +++ b/toolchain/check/testdata/facet/validate_impl_constraints.carbon @@ -143,13 +143,6 @@ constraint N { } // 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() { @@ -157,6 +150,13 @@ fn G() { impl C as Z {} impl C as Y {} impl C as X(C) {} + // CHECK:STDERR: fail_todo_where_period_self_rhs_sees_lhs.carbon:[[@LINE+7]]:3: error: cannot convert type `C` into type implementing `Z where .Self impls X(.Self as Z & Y)` [ConversionFailureTypeToFacet] + // CHECK:STDERR: F(C); + // CHECK:STDERR: ^~~~ + // CHECK:STDERR: fail_todo_where_period_self_rhs_sees_lhs.carbon:[[@LINE-10]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn F(_:! Z & N where .Self impls X(.Self)) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: F(C); } @@ -174,20 +174,6 @@ constraint N { 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() { @@ -195,5 +181,12 @@ fn G() { impl C as Z {} impl C as Y {} impl R(C) as X(C) {} + // CHECK:STDERR: fail_todo_where_type_rhs_sees_lhs.carbon:[[@LINE+7]]:3: error: cannot convert type `C` into type implementing `Z where R(.Self as Z & Y) impls X(.Self as Z & Y)` [ConversionFailureTypeToFacet] + // CHECK:STDERR: F(C); + // CHECK:STDERR: ^~~~ + // CHECK:STDERR: fail_todo_where_type_rhs_sees_lhs.carbon:[[@LINE-10]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere] + // CHECK:STDERR: fn F(_:! Z & N where R(.Self) impls X(.Self)) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: F(C); } diff --git a/toolchain/sem_ir/facet_type_info.cpp b/toolchain/sem_ir/facet_type_info.cpp index 8aa56cca98a5..824594ffd72c 100644 --- a/toolchain/sem_ir/facet_type_info.cpp +++ b/toolchain/sem_ir/facet_type_info.cpp @@ -166,6 +166,11 @@ auto FacetTypeInfo::Combine(const FacetTypeInfo& lhs, const FacetTypeInfo& rhs) return info; } +auto FacetTypeInfo::ExtendedOnly(const FacetTypeInfo& info) -> FacetTypeInfo { + return {.extend_constraints = info.extend_constraints, + .extend_named_constraints = info.extend_named_constraints}; +} + auto FacetTypeInfo::Canonicalize() -> void { SortAndDeduplicate(extend_constraints, InterfaceLess); SortAndDeduplicate(self_impls_constraints, InterfaceLess); diff --git a/toolchain/sem_ir/facet_type_info.h b/toolchain/sem_ir/facet_type_info.h index 44e6344cd6c3..58d86701305b 100644 --- a/toolchain/sem_ir/facet_type_info.h +++ b/toolchain/sem_ir/facet_type_info.h @@ -42,6 +42,11 @@ struct FacetTypeInfo : Printable { static auto Combine(const FacetTypeInfo& lhs, const FacetTypeInfo& rhs) -> FacetTypeInfo; + // Returns a FacetTypeInfo that only contains constraints that are extended by + // the facet type. It is not canonicalized, so that it can be further modified + // by the caller if desired. + static auto ExtendedOnly(const FacetTypeInfo& info) -> FacetTypeInfo; + // TODO: Need to switch to a processed, canonical form, that can support facet // type equality as defined by // https://github.com/carbon-language/carbon-lang/issues/2409.