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.
This commit is contained in:
Dana Jansens
2026-04-10 18:05:22 +00:00
committed by GitHub
parent cc5a42691e
commit 12d7574636
4 changed files with 25 additions and 24 deletions
+1 -3
View File
@@ -45,9 +45,7 @@ auto HandleParseNode(Context& context, Parse::WhereOperandId node_id) -> bool {
if (auto facet_type =
context.types().TryGetAs<SemIR::FacetType>(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) {
@@ -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);
}
+5
View File
@@ -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);
+5
View File
@@ -42,6 +42,11 @@ struct FacetTypeInfo : Printable<FacetTypeInfo> {
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.