Просмотр исходного кода

Include extended named constraints in the type of `.Self` for a where clause (#7048)

The `.Self` should see all extended constraints from the LHS of the
`where`, which is both interfaces and named constraints.
Dana Jansens 3 недель назад
Родитель
Сommit
12d7574636

+ 1 - 3
toolchain/check/handle_where.cpp

@@ -45,9 +45,7 @@ auto HandleParseNode(Context& context, Parse::WhereOperandId node_id) -> bool {
   if (auto facet_type =
   if (auto facet_type =
           context.types().TryGetAs<SemIR::FacetType>(period_self_type_id)) {
           context.types().TryGetAs<SemIR::FacetType>(period_self_type_id)) {
     const auto& info = context.facet_types().Get(facet_type->facet_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();
     stripped_info.Canonicalize();
     period_self_type_id = GetFacetType(context, stripped_info);
     period_self_type_id = GetFacetType(context, stripped_info);
   } else if (period_self_type_id == SemIR::TypeType::TypeId) {
   } else if (period_self_type_id == SemIR::TypeType::TypeId) {

+ 14 - 21
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`.
 // 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 F(_:! Z & N where .Self impls X(.Self)) {}
 
 
 fn G() {
 fn G() {
@@ -157,6 +150,13 @@ fn G() {
   impl C as Z {}
   impl C as Z {}
   impl C as Y {}
   impl C as Y {}
   impl C as X(C) {}
   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);
   F(C);
 }
 }
 
 
@@ -174,20 +174,6 @@ constraint N {
 class R(T:! Z & Y);
 class R(T:! Z & Y);
 
 
 // The RHS of `where` can see the extend constraints on the LHS of `where`.
 // 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 F(_:! Z & N where R(.Self) impls X(.Self)) {}
 
 
 fn G() {
 fn G() {
@@ -195,5 +181,12 @@ fn G() {
   impl C as Z {}
   impl C as Z {}
   impl C as Y {}
   impl C as Y {}
   impl R(C) as X(C) {}
   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);
   F(C);
 }
 }

+ 5 - 0
toolchain/sem_ir/facet_type_info.cpp

@@ -166,6 +166,11 @@ auto FacetTypeInfo::Combine(const FacetTypeInfo& lhs, const FacetTypeInfo& rhs)
   return info;
   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 {
 auto FacetTypeInfo::Canonicalize() -> void {
   SortAndDeduplicate(extend_constraints, InterfaceLess);
   SortAndDeduplicate(extend_constraints, InterfaceLess);
   SortAndDeduplicate(self_impls_constraints, InterfaceLess);
   SortAndDeduplicate(self_impls_constraints, InterfaceLess);

+ 5 - 0
toolchain/sem_ir/facet_type_info.h

@@ -42,6 +42,11 @@ struct FacetTypeInfo : Printable<FacetTypeInfo> {
   static auto Combine(const FacetTypeInfo& lhs, const FacetTypeInfo& rhs)
   static auto Combine(const FacetTypeInfo& lhs, const FacetTypeInfo& rhs)
       -> FacetTypeInfo;
       -> 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
   // TODO: Need to switch to a processed, canonical form, that can support facet
   // type equality as defined by
   // type equality as defined by
   // https://github.com/carbon-language/carbon-lang/issues/2409.
   // https://github.com/carbon-language/carbon-lang/issues/2409.