mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 09:34:42 +01:00
Properly diagnose ambiguous .Self in T impls X where... (#7132)
A `where` expression nested inside a `T impls X` constraint makes `.Self` ambiguous on the right-hand side of the `where` if `T` is anything other than `.Self`. After the `where`, the value of a `.Self` could be `T` or could be the value of `.Self` before the `impls` constraint: the so-called top-level value of `.Self`. Implicit use of `.Self` in designators is always allowed, and they are bound (and replaced by a reference) to the inner-most possible value of `.Self`. On the right-hand side of the nested `where` above, they have the value `T as X`. `.Self impls ...` is also always allowed, since it acts more as a keyword here, and it always refers to the inner-most possible value of `.Self`. Any other explicit use of `.Self` is diagnosed when ambiguous, in any kind of constraint. This is done in the handling of `WhereExpr` since it has enough context to allow `.Self impls` (which is an explicit use) while disallowing other explicit uses. And because it has non-canonical instructions to work with, so it is able to diagnose errors with precise locations. Since `.Self` is no longer going to be marked with depth modifiers, the eval of `WhereExpr` does not need an input facet value instruction representing `.Self` to compare with, as they are now going to all be equivalent. So revert it back to just looking for the `PeriodSelf` name id, through a shared helper being introduced as `IsPeriodSelf`. And drop the period self InstId from the `WhereExpr` instruction. This causes most of the formatted SemIR changes. Move helpers for working with and replacing `.Self` to their own file, out of the `facet_type.h` header/cpp files. These are working with `.Self` facet values more than facet types, though `.Self` is a name that only exists inside the scope of a facet type.
This commit is contained in:
@@ -163,8 +163,8 @@ impl {.a: bool} as type where .Self impls I {}
|
||||
// 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.as_type]
|
||||
// CHECK:STDOUT: %.loc8_24: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type]
|
||||
// CHECK:STDOUT: %.loc8_18: type = where_expr %.Self [concrete = constants.%type] {
|
||||
// CHECK:STDOUT: requirement_base_facet_type type
|
||||
// CHECK:STDOUT: %.loc8_18: type = where_expr [concrete = constants.%type] {
|
||||
// CHECK:STDOUT: requirement_base_facet_type %.loc8_13
|
||||
// CHECK:STDOUT: requirement_impls %.loc8_24, %.loc8_36
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
@@ -214,8 +214,8 @@ impl {.a: bool} as type where .Self impls I {}
|
||||
// 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.as_type]
|
||||
// CHECK:STDOUT: %.loc10_31: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.as_type]
|
||||
// CHECK:STDOUT: %.loc10_25: type = where_expr %.Self [concrete = constants.%type_where] {
|
||||
// CHECK:STDOUT: requirement_base_facet_type type
|
||||
// CHECK:STDOUT: %.loc10_25: type = where_expr [concrete = constants.%type_where] {
|
||||
// CHECK:STDOUT: requirement_base_facet_type %.loc10_20
|
||||
// CHECK:STDOUT: requirement_impls %.loc10_31, %I.ref
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
Reference in New Issue
Block a user