ソースを参照

Add `Self` to the name scope for a class. (#3736)

Rather than just adding `Self` to the lexical scope, add it to the
class's name scope so that it is visible in later lexical scopes for the
same class -- in particular, for out-of-line definitions of members.
Also switch some tests in `check/testdata/class` over to making
idiomatic use of `Self` both inside a class and out-of-line, now that it
works more consistently.

Note that this does not permit using `Class.Self`, but only because we
don't yet support keyword names after `.` at all. If that changed, one
could use `Class.Self` to redundantly refer to `Class`. Whether we allow
that is left to a future decision.
Richard Smith 2 年 前
コミット
67d5446b03
81 ファイル変更533 行追加191 行削除
  1. 4 2
      toolchain/check/handle_class.cpp
  2. 4 1
      toolchain/check/testdata/as/identity.carbon
  3. 4 1
      toolchain/check/testdata/as/tuple.carbon
  4. 2 0
      toolchain/check/testdata/class/base.carbon
  5. 2 0
      toolchain/check/testdata/class/base_field.carbon
  6. 2 0
      toolchain/check/testdata/class/base_function_unqualified.carbon
  7. 2 0
      toolchain/check/testdata/class/base_method.carbon
  8. 4 0
      toolchain/check/testdata/class/base_method_shadow.carbon
  9. 1 0
      toolchain/check/testdata/class/basic.carbon
  10. 3 0
      toolchain/check/testdata/class/derived_to_base.carbon
  11. 2 0
      toolchain/check/testdata/class/fail_abstract.carbon
  12. 1 0
      toolchain/check/testdata/class/fail_addr_not_self.carbon
  13. 1 0
      toolchain/check/testdata/class/fail_addr_self.carbon
  14. 12 1
      toolchain/check/testdata/class/fail_base_bad_type.carbon
  15. 3 0
      toolchain/check/testdata/class/fail_base_method_define.carbon
  16. 4 1
      toolchain/check/testdata/class/fail_base_misplaced.carbon
  17. 8 1
      toolchain/check/testdata/class/fail_base_modifiers.carbon
  18. 5 1
      toolchain/check/testdata/class/fail_base_no_extend.carbon
  19. 10 2
      toolchain/check/testdata/class/fail_base_repeated.carbon
  20. 5 1
      toolchain/check/testdata/class/fail_base_unbound.carbon
  21. 1 0
      toolchain/check/testdata/class/fail_convert_to_invalid.carbon
  22. 3 0
      toolchain/check/testdata/class/fail_derived_to_base.carbon
  23. 1 0
      toolchain/check/testdata/class/fail_field_modifiers.carbon
  24. 14 3
      toolchain/check/testdata/class/fail_import_misuses.carbon
  25. 1 0
      toolchain/check/testdata/class/fail_init.carbon
  26. 1 0
      toolchain/check/testdata/class/fail_init_as_inplace.carbon
  27. 2 0
      toolchain/check/testdata/class/fail_memaccess_category.carbon
  28. 1 0
      toolchain/check/testdata/class/fail_member_of_let.carbon
  29. 1 0
      toolchain/check/testdata/class/fail_method.carbon
  30. 3 0
      toolchain/check/testdata/class/fail_method_modifiers.carbon
  31. 12 3
      toolchain/check/testdata/class/fail_modifiers.carbon
  32. 1 0
      toolchain/check/testdata/class/fail_out_of_line_decl.carbon
  33. 28 7
      toolchain/check/testdata/class/fail_redeclaration_introducer.carbon
  34. 14 2
      toolchain/check/testdata/class/fail_redeclaration_scope.carbon
  35. 1 0
      toolchain/check/testdata/class/fail_redefinition.carbon
  36. 1 0
      toolchain/check/testdata/class/fail_reorder.carbon
  37. 1 0
      toolchain/check/testdata/class/fail_scope.carbon
  38. 20 18
      toolchain/check/testdata/class/fail_self.carbon
  39. 47 0
      toolchain/check/testdata/class/fail_self_type_member.carbon
  40. 1 0
      toolchain/check/testdata/class/fail_todo_generic_method.carbon
  41. 4 1
      toolchain/check/testdata/class/fail_todo_import_forward_decl.carbon
  42. 3 0
      toolchain/check/testdata/class/fail_todo_modifiers.carbon
  43. 1 0
      toolchain/check/testdata/class/fail_unbound_field.carbon
  44. 1 0
      toolchain/check/testdata/class/fail_unknown_member.carbon
  45. 1 0
      toolchain/check/testdata/class/field_access.carbon
  46. 1 0
      toolchain/check/testdata/class/field_access_in_value.carbon
  47. 24 10
      toolchain/check/testdata/class/import.carbon
  48. 14 8
      toolchain/check/testdata/class/import_base.carbon
  49. 5 2
      toolchain/check/testdata/class/import_member_cycle.carbon
  50. 5 2
      toolchain/check/testdata/class/import_struct_cyle.carbon
  51. 1 0
      toolchain/check/testdata/class/init.carbon
  52. 1 0
      toolchain/check/testdata/class/init_as.carbon
  53. 2 0
      toolchain/check/testdata/class/init_nested.carbon
  54. 8 7
      toolchain/check/testdata/class/method.carbon
  55. 47 47
      toolchain/check/testdata/class/nested.carbon
  56. 2 0
      toolchain/check/testdata/class/nested_name.carbon
  57. 27 26
      toolchain/check/testdata/class/raw_self.carbon
  58. 52 2
      toolchain/check/testdata/class/raw_self_type.carbon
  59. 20 5
      toolchain/check/testdata/class/redeclaration.carbon
  60. 12 3
      toolchain/check/testdata/class/redeclaration_introducer.carbon
  61. 10 5
      toolchain/check/testdata/class/reenter_scope.carbon
  62. 1 0
      toolchain/check/testdata/class/scope.carbon
  63. 11 10
      toolchain/check/testdata/class/self.carbon
  64. 2 0
      toolchain/check/testdata/class/self_conversion.carbon
  65. 14 16
      toolchain/check/testdata/class/self_type.carbon
  66. 1 0
      toolchain/check/testdata/class/static_method.carbon
  67. 4 1
      toolchain/check/testdata/global/class_obj.carbon
  68. 4 1
      toolchain/check/testdata/global/class_with_fun.carbon
  69. 1 0
      toolchain/check/testdata/if_expr/fail_not_in_function.carbon
  70. 1 0
      toolchain/check/testdata/impl/fail_extend_impl_forall.carbon
  71. 3 0
      toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon
  72. 1 0
      toolchain/check/testdata/impl/fail_extend_non_interface.carbon
  73. 1 0
      toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon
  74. 1 0
      toolchain/check/testdata/impl/fail_extend_undefined_interface.carbon
  75. 1 0
      toolchain/check/testdata/impl/fail_todo_extend_impl.carbon
  76. 3 0
      toolchain/check/testdata/impl/impl_as.carbon
  77. 3 0
      toolchain/check/testdata/impl/redeclaration.carbon
  78. 1 0
      toolchain/check/testdata/package_expr/syntax.carbon
  79. 1 0
      toolchain/check/testdata/return/fail_return_with_returned_var.carbon
  80. 1 0
      toolchain/check/testdata/return/returned_var.carbon
  81. 4 1
      toolchain/check/testdata/var/fail_not_copyable.carbon

+ 4 - 2
toolchain/check/handle_class.cpp

@@ -151,8 +151,10 @@ auto HandleClassDefinitionStart(Context& context,
   context.scope_stack().Push(class_decl_id, class_info.scope_id);
 
   // Introduce `Self`.
-  context.AddNameToLookup(SemIR::NameId::SelfType,
-                          context.types().GetInstId(class_info.self_type_id));
+  context.name_scopes()
+      .Get(class_info.scope_id)
+      .names.insert({SemIR::NameId::SelfType,
+                     context.types().GetInstId(class_info.self_type_id)});
 
   context.inst_block_stack().Push();
   context.node_stack().Push(parse_node, class_id);

+ 4 - 1
toolchain/check/testdata/as/identity.carbon

@@ -61,7 +61,10 @@ fn Initializing() {
 // CHECK:STDOUT:   %Initializing: <function> = fn_decl @Initializing {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @X {}
+// CHECK:STDOUT: class @X {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%X
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Value(%n: X) {
 // CHECK:STDOUT: !entry:

+ 4 - 1
toolchain/check/testdata/as/tuple.carbon

@@ -49,7 +49,10 @@ fn Var() {
 // CHECK:STDOUT:   %Var: <function> = fn_decl @Var {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @X {}
+// CHECK:STDOUT: class @X {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%X
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: X;
 // CHECK:STDOUT:

+ 2 - 0
toolchain/check/testdata/class/base.carbon

@@ -73,6 +73,7 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   %.loc8: <unbound element of class Base> = field_decl b, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Base
 // CHECK:STDOUT:   .b = %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -82,6 +83,7 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   %.loc14: <unbound element of class Derived> = field_decl d, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc12
 // CHECK:STDOUT:   .d = %.loc14
 // CHECK:STDOUT:   extend name_scope1

+ 2 - 0
toolchain/check/testdata/class/base_field.carbon

@@ -63,6 +63,7 @@ fn Access(p: Derived*) -> i32* {
 // CHECK:STDOUT:   %.loc10: <unbound element of class Base> = field_decl c, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Base
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT:   .b = %.loc9
 // CHECK:STDOUT:   .c = %.loc10
@@ -75,6 +76,7 @@ fn Access(p: Derived*) -> i32* {
 // CHECK:STDOUT:   %.loc17: <unbound element of class Derived> = field_decl e, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc14
 // CHECK:STDOUT:   .d = %.loc16
 // CHECK:STDOUT:   .e = %.loc17

+ 2 - 0
toolchain/check/testdata/class/base_function_unqualified.carbon

@@ -45,6 +45,7 @@ fn Derived.H() {
 // CHECK:STDOUT:   %F: <function> = fn_decl @F {} [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Base
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -55,6 +56,7 @@ fn Derived.H() {
 // CHECK:STDOUT:   %H: <function> = fn_decl @H {} [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc12
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT:   .H = %H

+ 2 - 0
toolchain/check/testdata/class/base_method.carbon

@@ -74,6 +74,7 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Base
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
@@ -83,6 +84,7 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   %.loc18: <unbound element of class Derived> = base_decl Base, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc18
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }

+ 4 - 0
toolchain/check/testdata/class/base_method_shadow.carbon

@@ -96,6 +96,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -111,6 +112,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT:   .base = %.loc12
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   extend name_scope1
@@ -128,6 +130,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .base = %.loc17
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   extend name_scope2
@@ -138,6 +141,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT:   %.loc22: <unbound element of class D> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%D
 // CHECK:STDOUT:   .base = %.loc22
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/class/basic.carbon

@@ -61,6 +61,7 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   %.loc14: <unbound element of class Class> = field_decl k, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT:   .k = %.loc14

+ 3 - 0
toolchain/check/testdata/class/derived_to_base.carbon

@@ -131,6 +131,7 @@ fn ConvertInit() {
 // CHECK:STDOUT:   %.loc8: <unbound element of class A> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -140,6 +141,7 @@ fn ConvertInit() {
 // CHECK:STDOUT:   %.loc13: <unbound element of class B> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT:   .base = %.loc12
 // CHECK:STDOUT:   .b = %.loc13
 // CHECK:STDOUT:   extend name_scope1
@@ -151,6 +153,7 @@ fn ConvertInit() {
 // CHECK:STDOUT:   %.loc18: <unbound element of class C> = field_decl c, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .base = %.loc17
 // CHECK:STDOUT:   .c = %.loc18
 // CHECK:STDOUT:   extend name_scope2

+ 2 - 0
toolchain/check/testdata/class/fail_abstract.carbon

@@ -75,6 +75,7 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   %.loc8: <unbound element of class Abstract> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Abstract
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -84,6 +85,7 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:   %.loc14: <unbound element of class Derived> = field_decl d, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc12
 // CHECK:STDOUT:   .d = %.loc14
 // CHECK:STDOUT:   extend name_scope1

+ 1 - 0
toolchain/check/testdata/class/fail_addr_not_self.carbon

@@ -46,6 +46,7 @@ class Class {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/class/fail_addr_self.carbon

@@ -81,6 +81,7 @@ fn F(c: Class, p: Class*) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT: }

+ 12 - 1
toolchain/check/testdata/class/fail_base_bad_type.carbon

@@ -299,12 +299,16 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Base {}
+// CHECK:STDOUT: class @Base {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Base
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Final {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Final> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Final
 // CHECK:STDOUT:   .a = %.loc9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -313,6 +317,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %.loc16: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%DeriveFromError
 // CHECK:STDOUT:   .base = %.loc16
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
@@ -322,6 +327,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %.loc26_18: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%DeriveFromNonType
 // CHECK:STDOUT:   .base = %.loc26_18
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
@@ -330,6 +336,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %.loc35: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%DeriveFromi32
 // CHECK:STDOUT:   .base = %.loc35
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
@@ -341,6 +348,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %.loc51_23: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%DeriveFromTuple
 // CHECK:STDOUT:   .base = %.loc51_23
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
@@ -350,6 +358,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %.loc67_34: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%DeriveFromStruct
 // CHECK:STDOUT:   .base = %.loc67_34
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
@@ -361,6 +370,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %.loc87: <error> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%DeriveFromIncomplete
 // CHECK:STDOUT:   .base = %.loc87
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
@@ -370,6 +380,7 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:   %.loc101: <unbound element of class DeriveFromFinal> = base_decl Final, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%DeriveFromFinal
 // CHECK:STDOUT:   .base = %.loc101
 // CHECK:STDOUT:   extend name_scope2
 // CHECK:STDOUT: }

+ 3 - 0
toolchain/check/testdata/class/fail_base_method_define.carbon

@@ -55,6 +55,7 @@ fn D.C.F() {}
 // CHECK:STDOUT:   %C.decl = class_decl @C {} [template = constants.%C]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .C = %C.decl
 // CHECK:STDOUT: }
@@ -63,6 +64,7 @@ fn D.C.F() {}
 // CHECK:STDOUT:   %F: <function> = fn_decl @F.2 {} [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -71,6 +73,7 @@ fn D.C.F() {}
 // CHECK:STDOUT:   %.loc16: <unbound element of class D> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%D
 // CHECK:STDOUT:   .base = %.loc16
 // CHECK:STDOUT:   .F = file.%F
 // CHECK:STDOUT:   extend name_scope1

+ 4 - 1
toolchain/check/testdata/class/fail_base_misplaced.carbon

@@ -30,7 +30,10 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B {}
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:

+ 8 - 1
toolchain/check/testdata/class/fail_base_modifiers.carbon

@@ -76,13 +76,17 @@ class C4 {
 // CHECK:STDOUT:   %C4.decl = class_decl @C4 {} [template = constants.%C4]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B {}
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C1 {
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc13: <unbound element of class C1> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C1
 // CHECK:STDOUT:   .base = %.loc13
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
@@ -92,6 +96,7 @@ class C4 {
 // CHECK:STDOUT:   %.loc23: <unbound element of class C2> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C2
 // CHECK:STDOUT:   .base = %.loc23
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -100,6 +105,7 @@ class C4 {
 // CHECK:STDOUT:   %.loc33: <unbound element of class C3> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C3
 // CHECK:STDOUT:   .base = %.loc33
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
@@ -109,6 +115,7 @@ class C4 {
 // CHECK:STDOUT:   %.loc43: <unbound element of class C4> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C4
 // CHECK:STDOUT:   .base = %.loc43
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }

+ 5 - 1
toolchain/check/testdata/class/fail_base_no_extend.carbon

@@ -34,13 +34,17 @@ class C {
 // CHECK:STDOUT:   %C.decl = class_decl @C {} [template = constants.%C]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B {}
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc13: <unbound element of class C> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .base = %.loc13
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 10 - 2
toolchain/check/testdata/class/fail_base_repeated.carbon

@@ -58,9 +58,15 @@ class D {
 // CHECK:STDOUT:   %D.decl = class_decl @D {} [template = constants.%D]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B1 {}
+// CHECK:STDOUT: class @B1 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B1
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B2 {}
+// CHECK:STDOUT: class @B2 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B2
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
 // CHECK:STDOUT:   %B1.ref: type = name_ref B1, file.%B1.decl [template = constants.%B1]
@@ -68,6 +74,7 @@ class D {
 // CHECK:STDOUT:   %B2.ref: type = name_ref B2, file.%B2.decl [template = constants.%B2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .base = %.loc11
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
@@ -78,6 +85,7 @@ class D {
 // CHECK:STDOUT:   %B1.ref.loc30: type = name_ref B1, file.%B1.decl [template = constants.%B1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%D
 // CHECK:STDOUT:   .base = %.loc23
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }

+ 5 - 1
toolchain/check/testdata/class/fail_base_unbound.carbon

@@ -40,13 +40,17 @@ let b: B = C.base;
 // CHECK:STDOUT:   %b: B = bind_name b, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B {}
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
 // CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B.decl [template = constants.%B]
 // CHECK:STDOUT:   %.loc10: <unbound element of class C> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .base = %.loc10
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/class/fail_convert_to_invalid.carbon

@@ -40,6 +40,7 @@ fn Make() -> C {
 // CHECK:STDOUT:   %.loc11: <error> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .a = %.loc11
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 0
toolchain/check/testdata/class/fail_derived_to_base.carbon

@@ -89,6 +89,7 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; }
 // CHECK:STDOUT:   %.loc8: <unbound element of class A1> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A1
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -96,6 +97,7 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; }
 // CHECK:STDOUT:   %.loc12: <unbound element of class A2> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A2
 // CHECK:STDOUT:   .a = %.loc12
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -105,6 +107,7 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; }
 // CHECK:STDOUT:   %.loc17: <unbound element of class B2> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B2
 // CHECK:STDOUT:   .base = %.loc16
 // CHECK:STDOUT:   .b = %.loc17
 // CHECK:STDOUT:   extend name_scope2

+ 1 - 0
toolchain/check/testdata/class/fail_field_modifiers.carbon

@@ -53,6 +53,7 @@ class Class {
 // CHECK:STDOUT:   %m: i32 = bind_name m, %.loc27
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .j = %.loc12
 // CHECK:STDOUT:   .k = %.loc17
 // CHECK:STDOUT: }

+ 14 - 3
toolchain/check/testdata/class/fail_import_misuses.carbon

@@ -51,7 +51,10 @@ var a: Incomplete;
 // CHECK:STDOUT:   %Incomplete.decl = class_decl @Incomplete {} [template = constants.%Incomplete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Empty {}
+// CHECK:STDOUT: class @Empty {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Empty
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Incomplete;
 // CHECK:STDOUT:
@@ -81,9 +84,17 @@ var a: Incomplete;
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Empty {}
+// CHECK:STDOUT: class @Empty {
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = %import_ref
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1 {}
+// CHECK:STDOUT: class @.1 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%.2
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Incomplete;
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/class/fail_init.carbon

@@ -53,6 +53,7 @@ fn F() {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Class> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT:   .b = %.loc9
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/class/fail_init_as_inplace.carbon

@@ -57,6 +57,7 @@ fn F() {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Class> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT:   .b = %.loc9
 // CHECK:STDOUT: }

+ 2 - 0
toolchain/check/testdata/class/fail_memaccess_category.carbon

@@ -77,6 +77,7 @@ fn F(s: {.a: A}, b: B) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -85,6 +86,7 @@ fn F(s: {.a: A}, b: B) {
 // CHECK:STDOUT:   %.loc12: <unbound element of class B> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
 // CHECK:STDOUT:   .a = %.loc12
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/class/fail_member_of_let.carbon

@@ -41,6 +41,7 @@ fn T.F() {}
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/class/fail_method.carbon

@@ -75,6 +75,7 @@ fn F(c: Class) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .NoSelf = %NoSelf
 // CHECK:STDOUT:   .WithSelf = %WithSelf
 // CHECK:STDOUT: }

+ 3 - 0
toolchain/check/testdata/class/fail_method_modifiers.carbon

@@ -80,6 +80,7 @@ base class BaseClass {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%FinalClass
 // CHECK:STDOUT:   .Abstract = %Abstract
 // CHECK:STDOUT:   .Virtual = %Virtual
 // CHECK:STDOUT: }
@@ -97,6 +98,7 @@ base class BaseClass {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%AbstractClass
 // CHECK:STDOUT:   .Default = %Default
 // CHECK:STDOUT:   .Final = %Final
 // CHECK:STDOUT: }
@@ -109,6 +111,7 @@ base class BaseClass {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%BaseClass
 // CHECK:STDOUT:   .Abstract = %Abstract
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 12 - 3
toolchain/check/testdata/class/fail_modifiers.carbon

@@ -95,13 +95,22 @@ abstract base class AbstractAndBase {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DuplicatePrivate;
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @TwoAccess {}
+// CHECK:STDOUT: class @TwoAccess {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%TwoAccess
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @TwoAbstract;
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Virtual {}
+// CHECK:STDOUT: class @Virtual {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Virtual
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @WrongOrder;
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @AbstractAndBase {}
+// CHECK:STDOUT: class @AbstractAndBase {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%AbstractAndBase
+// CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/class/fail_out_of_line_decl.carbon

@@ -28,6 +28,7 @@ fn C.F() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .F = file.%F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 28 - 7
toolchain/check/testdata/class/fail_redeclaration_introducer.carbon

@@ -114,17 +114,38 @@ base class G;
 // CHECK:STDOUT:   %G.decl.loc75 = class_decl @G {} [template = constants.%G]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @A {}
+// CHECK:STDOUT: class @A {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B {}
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @C {}
+// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @D {}
+// CHECK:STDOUT: class @D {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%D
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @E {}
+// CHECK:STDOUT: class @E {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%E
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @F {}
+// CHECK:STDOUT: class @F {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%F
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @G {}
+// CHECK:STDOUT: class @G {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%G
+// CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 14 - 2
toolchain/check/testdata/class/fail_redeclaration_scope.carbon

@@ -50,6 +50,7 @@ class Y {
 // CHECK:STDOUT:   %B.decl = class_decl @B.2 {} [template = constants.%B.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A.1
 // CHECK:STDOUT:   .B = %B.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -58,6 +59,7 @@ class Y {
 // CHECK:STDOUT:   %B.decl = class_decl @B.1 {} [template = constants.%B.1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%X
 // CHECK:STDOUT:   .A = %A.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -65,16 +67,26 @@ class Y {
 // CHECK:STDOUT:   %B.decl = class_decl @B.1 {} [template = constants.%B.1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A.2
 // CHECK:STDOUT:   .B = %B.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B.1 {}
+// CHECK:STDOUT: class @B.1 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B.1
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B.2;
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Y {
 // CHECK:STDOUT:   %.decl = class_decl @.1 {} [template = constants.%.2]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Y
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1 {}
+// CHECK:STDOUT: class @.1 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%.2
+// CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/class/fail_redefinition.carbon

@@ -47,6 +47,7 @@ fn Class.H() {}
 // CHECK:STDOUT:   %H: <function> = fn_decl @H {} [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = <unexpected instref inst+3>
 // CHECK:STDOUT:   .H = <unexpected instref inst+4>
 // CHECK:STDOUT:   .G = %G

+ 1 - 0
toolchain/check/testdata/class/fail_reorder.carbon

@@ -49,6 +49,7 @@ class Class {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/class/fail_scope.carbon

@@ -42,6 +42,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 20 - 18
toolchain/check/testdata/class/fail_self.carbon

@@ -6,30 +6,30 @@
 
 class Class {
   // CHECK:STDERR: fail_self.carbon:[[@LINE+3]]:8: ERROR: `self` can only be declared in an implicit parameter list.
-  // CHECK:STDERR:   fn F(self: Class);
-  // CHECK:STDERR:        ^~~~~~~~~~~
-  fn F(self: Class);
+  // CHECK:STDERR:   fn F(self: Self);
+  // CHECK:STDERR:        ^~~~~~~~~~
+  fn F(self: Self);
 
   // CHECK:STDERR: fail_self.carbon:[[@LINE+6]]:10: ERROR: Function returns incomplete type `Class`.
-  // CHECK:STDERR:   fn G() -> Class;
-  // CHECK:STDERR:          ^~~~~~~~
+  // CHECK:STDERR:   fn G() -> Self;
+  // CHECK:STDERR:          ^~~~~~~
   // CHECK:STDERR: fail_self.carbon:[[@LINE-9]]:1: Class is incomplete within its definition.
   // CHECK:STDERR: class Class {
   // CHECK:STDERR: ^~~~~~~~~~~~~
-  fn G() -> Class;
+  fn G() -> Self;
 }
 
 // CHECK:STDERR: fail_self.carbon:[[@LINE+3]]:12: ERROR: `self` can only be declared in an implicit parameter list.
-// CHECK:STDERR: fn Class.F(self: Class) {
-// CHECK:STDERR:            ^~~~~~~~~~~
-fn Class.F(self: Class) {
+// CHECK:STDERR: fn Class.F(self: Self) {
+// CHECK:STDERR:            ^~~~~~~~~~
+fn Class.F(self: Self) {
 }
 
-fn Class.G() -> Class {
+fn Class.G() -> Self {
   // CHECK:STDERR: fail_self.carbon:[[@LINE+3]]:7: ERROR: `self` can only be declared in an implicit parameter list.
-  // CHECK:STDERR:   var self: Class;
-  // CHECK:STDERR:       ^~~~~~~~~~~
-  var self: Class;
+  // CHECK:STDERR:   var self: Self;
+  // CHECK:STDERR:       ^~~~~~~~~~
+  var self: Self;
   // CHECK:STDERR: fail_self.carbon:[[@LINE+3]]:10: ERROR: Cannot copy value of type `Class`.
   // CHECK:STDERR:   return self;
   // CHECK:STDERR:          ^~~~
@@ -68,12 +68,12 @@ fn CallWrongSelf(ws: WrongSelf) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %Class.decl = class_decl @Class {} [template = constants.%Class]
 // CHECK:STDOUT:   %F: <function> = fn_decl @F.1 {
-// CHECK:STDOUT:     %Class.ref.loc25: type = name_ref Class, %Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc25: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc25_12.1: Class = param self
 // CHECK:STDOUT:     @F.1.%self: Class = bind_name self, %self.loc25_12.1
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %G: <function> = fn_decl @G {
-// CHECK:STDOUT:     %Class.ref.loc28: type = name_ref Class, %Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc28: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     @G.%return: ref Class = var <return slot>
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %WrongSelf.decl = class_decl @WrongSelf {} [template = constants.%WrongSelf]
@@ -86,16 +86,17 @@ fn CallWrongSelf(ws: WrongSelf) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
 // CHECK:STDOUT:   %F: <function> = fn_decl @F.1 {
-// CHECK:STDOUT:     %Class.ref.loc11: type = name_ref Class, file.%Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc11: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc11_8.1: Class = param self
 // CHECK:STDOUT:     %self.loc11_8.2: Class = bind_name self, %self.loc11_8.1
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %G: <function> = fn_decl @G {
-// CHECK:STDOUT:     %Class.ref.loc19: type = name_ref Class, file.%Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc19: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %return.var: ref Class = var <return slot>
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT: }
@@ -108,6 +109,7 @@ fn CallWrongSelf(ws: WrongSelf) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%WrongSelf
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -118,7 +120,7 @@ fn CallWrongSelf(ws: WrongSelf) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> %return: Class {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class.decl [template = constants.%Class]
+// CHECK:STDOUT:   %Self.ref: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:   %self.var: ref Class = var self
 // CHECK:STDOUT:   %self: ref Class = bind_name self, %self.var
 // CHECK:STDOUT:   %self.ref: ref Class = name_ref self, %self

+ 47 - 0
toolchain/check/testdata/class/fail_self_type_member.carbon

@@ -0,0 +1,47 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// AUTOUPDATE
+
+class Class {
+  var b: bool;
+}
+
+fn F() -> bool {
+  var c1: Class = {.b = true};
+  // CHECK:STDERR: fail_self_type_member.carbon:[[@LINE+6]]:17: ERROR: Expected identifier after `.`.
+  // CHECK:STDERR:   var c2: Class.Self = c1;
+  // CHECK:STDERR:                 ^~~~
+  // CHECK:STDERR: fail_self_type_member.carbon:[[@LINE+3]]:17: ERROR: Semantics TODO: `Error recovery from keyword name.`.
+  // CHECK:STDERR:   var c2: Class.Self = c1;
+  // CHECK:STDERR:                 ^~~~
+  var c2: Class.Self = c1;
+  return c2.b;
+}
+
+// CHECK:STDOUT: --- fail_self_type_member.carbon
+// CHECK:STDOUT:
+// CHECK:STDOUT: constants {
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %.1: type = unbound_element_type Class, bool [template]
+// CHECK:STDOUT:   %.2: type = struct_type {.b: bool} [template]
+// CHECK:STDOUT:   %.3: type = ptr_type {.b: bool} [template]
+// CHECK:STDOUT:   %.4: bool = bool_literal true [template]
+// CHECK:STDOUT:   %.5: Class = struct_value (%.4) [template]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: file {}
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @Class {
+// CHECK:STDOUT:   %.loc8: <unbound element of class Class> = field_decl b, element0 [template]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
+// CHECK:STDOUT:   .b = %.loc8
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @F() -> bool {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT: }
+// CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/class/fail_todo_generic_method.carbon

@@ -58,6 +58,7 @@ fn Class(T:! type).F[self: Self](n: T) {}
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .a = %.loc11
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }

+ 4 - 1
toolchain/check/testdata/class/fail_todo_import_forward_decl.carbon

@@ -61,5 +61,8 @@ class ForwardDecl {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @ForwardDecl;
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @.1 {}
+// CHECK:STDOUT: class @.1 {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%.1
+// CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 0
toolchain/check/testdata/class/fail_todo_modifiers.carbon

@@ -87,6 +87,7 @@ abstract class Abstract {
 // CHECK:STDOUT:   %.loc27: <unbound element of class Access> = field_decl l, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Access
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT:   .k = %.loc22
@@ -98,6 +99,7 @@ abstract class Abstract {
 // CHECK:STDOUT:   %I: <function> = fn_decl @I {} [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Base
 // CHECK:STDOUT:   .H = %H
 // CHECK:STDOUT:   .I = %I
 // CHECK:STDOUT: }
@@ -108,6 +110,7 @@ abstract class Abstract {
 // CHECK:STDOUT:   %L: <function> = fn_decl @L {} [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Abstract
 // CHECK:STDOUT:   .J = %J
 // CHECK:STDOUT:   .K = %K
 // CHECK:STDOUT:   .L = %L

+ 1 - 0
toolchain/check/testdata/class/fail_unbound_field.carbon

@@ -47,6 +47,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .field = %.loc8
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/class/fail_unknown_member.carbon

@@ -43,6 +43,7 @@ fn G(c: Class) -> i32 {
 // CHECK:STDOUT:   %.loc8: <unbound element of class Class> = field_decl n, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .n = %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/class/field_access.carbon

@@ -42,6 +42,7 @@ fn Run() {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Class> = field_decl k, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .j = %.loc8
 // CHECK:STDOUT:   .k = %.loc9
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/class/field_access_in_value.carbon

@@ -43,6 +43,7 @@ fn Test() {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Class> = field_decl k, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .j = %.loc8
 // CHECK:STDOUT:   .k = %.loc9
 // CHECK:STDOUT: }

+ 24 - 10
toolchain/check/testdata/class/import.carbon

@@ -72,12 +72,16 @@ fn Run() {
 // CHECK:STDOUT:   %Incomplete.decl = class_decl @Incomplete {} [template = constants.%Incomplete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Empty {}
+// CHECK:STDOUT: class @Empty {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Empty
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Field {
 // CHECK:STDOUT:   %.loc8: <unbound element of class Field> = field_decl x, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Field
 // CHECK:STDOUT:   .x = %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -96,6 +100,7 @@ fn Run() {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%ForwardDeclared
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT: }
@@ -143,22 +148,31 @@ fn Run() {
 // CHECK:STDOUT:   %Run: <function> = fn_decl @Run {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @Empty {}
+// CHECK:STDOUT: class @Empty {
+// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = %import_ref
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Field {
-// CHECK:STDOUT:   %import_ref: <unbound element of class Field> = import_ref ir1, inst+7, used [template = imports.%.1]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+5, unused
+// CHECK:STDOUT:   %import_ref.2: <unbound element of class Field> = import_ref ir1, inst+7, used [template = imports.%.1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .x = %import_ref
+// CHECK:STDOUT:   .Self = %import_ref.1
+// CHECK:STDOUT:   .x = %import_ref.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @ForwardDeclared {
-// CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+24, used [template = imports.%G]
-// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+17, used [template = imports.%F]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+12, unused
+// CHECK:STDOUT:   %import_ref.2: <function> = import_ref ir1, inst+24, used [template = imports.%G]
+// CHECK:STDOUT:   %import_ref.3: <function> = import_ref ir1, inst+17, used [template = imports.%F]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .G = %import_ref.1
-// CHECK:STDOUT:   .F = %import_ref.2
+// CHECK:STDOUT:   .Self = %import_ref.1
+// CHECK:STDOUT:   .G = %import_ref.2
+// CHECK:STDOUT:   .F = %import_ref.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Incomplete;
@@ -197,11 +211,11 @@ fn Run() {
 // CHECK:STDOUT:   %.loc12_29.3: init ForwardDeclared = converted %.loc12_29.1, %.loc12_29.2 [template = constants.%.11]
 // CHECK:STDOUT:   assign %c.var, %.loc12_29.3
 // CHECK:STDOUT:   %c.ref.loc13: ref ForwardDeclared = name_ref c, %c
-// CHECK:STDOUT:   %.loc13_4: <bound method> = bound_method %c.ref.loc13, @ForwardDeclared.%import_ref.2
+// CHECK:STDOUT:   %.loc13_4: <bound method> = bound_method %c.ref.loc13, @ForwardDeclared.%import_ref.3
 // CHECK:STDOUT:   %.loc13_3: ForwardDeclared = bind_value %c.ref.loc13
 // CHECK:STDOUT:   %.loc13_6: init () = call %.loc13_4(%.loc13_3)
 // CHECK:STDOUT:   %c.ref.loc14: ref ForwardDeclared = name_ref c, %c
-// CHECK:STDOUT:   %.loc14_4: <bound method> = bound_method %c.ref.loc14, @ForwardDeclared.%import_ref.1
+// CHECK:STDOUT:   %.loc14_4: <bound method> = bound_method %c.ref.loc14, @ForwardDeclared.%import_ref.2
 // CHECK:STDOUT:   %.loc14_3: ForwardDeclared* = addr_of %c.ref.loc14
 // CHECK:STDOUT:   %.loc14_6: init () = call %.loc14_4(%.loc14_3)
 // CHECK:STDOUT:   %ForwardDeclared.ref.loc16: type = name_ref ForwardDeclared, file.%import_ref.3 [template = constants.%ForwardDeclared]

+ 14 - 8
toolchain/check/testdata/class/import_base.carbon

@@ -68,6 +68,7 @@ fn Run() {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Base> = field_decl unused, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Base
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .Unused = %Unused
 // CHECK:STDOUT:   .x = %.loc8
@@ -79,6 +80,7 @@ fn Run() {
 // CHECK:STDOUT:   %.loc13: <unbound element of class Child> = base_decl Base, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Child
 // CHECK:STDOUT:   .base = %.loc13
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
@@ -120,24 +122,28 @@ fn Run() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Child {
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+24, unused
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+20, unused
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+24, unused
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .base = %import_ref
+// CHECK:STDOUT:   .Self = %import_ref.1
+// CHECK:STDOUT:   .base = %import_ref.2
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
 // CHECK:STDOUT:   %import_ref.1: <function> = import_ref ir1, inst+6, used [template = imports.%F]
-// CHECK:STDOUT:   %import_ref.2: <unbound element of class Base> = import_ref ir1, inst+12, used [template = imports.%.1]
-// CHECK:STDOUT:   %import_ref.3 = import_ref ir1, inst+10, unused
-// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+15, unused
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %import_ref.3: <unbound element of class Base> = import_ref ir1, inst+12, used [template = imports.%.1]
+// CHECK:STDOUT:   %import_ref.4 = import_ref ir1, inst+10, unused
+// CHECK:STDOUT:   %import_ref.5 = import_ref ir1, inst+15, unused
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %import_ref.1
-// CHECK:STDOUT:   .x = %import_ref.2
-// CHECK:STDOUT:   .Unused = %import_ref.3
-// CHECK:STDOUT:   .unused = %import_ref.4
+// CHECK:STDOUT:   .Self = %import_ref.2
+// CHECK:STDOUT:   .x = %import_ref.3
+// CHECK:STDOUT:   .Unused = %import_ref.4
+// CHECK:STDOUT:   .unused = %import_ref.5
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {

+ 5 - 2
toolchain/check/testdata/class/import_member_cycle.carbon

@@ -44,6 +44,7 @@ fn Run() {
 // CHECK:STDOUT:   %.loc5_8: <unbound element of class Cycle> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Cycle
 // CHECK:STDOUT:   .a = %.loc5_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -65,10 +66,12 @@ fn Run() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Cycle {
-// CHECK:STDOUT:   %import_ref = import_ref ir1, inst+7, unused
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+7, unused
+// CHECK:STDOUT:   %import_ref.2 = import_ref ir1, inst+2, unused
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .a = %import_ref
+// CHECK:STDOUT:   .a = %import_ref.1
+// CHECK:STDOUT:   .Self = %import_ref.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {

+ 5 - 2
toolchain/check/testdata/class/import_struct_cyle.carbon

@@ -58,6 +58,7 @@ fn Run() {
 // CHECK:STDOUT:   %.loc10_8: <unbound element of class Cycle> = field_decl c, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Cycle
 // CHECK:STDOUT:   .c = %.loc10_8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -84,10 +85,12 @@ fn Run() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Cycle {
-// CHECK:STDOUT:   %import_ref: <unbound element of class Cycle> = import_ref ir1, inst+18, used [template = imports.%.1]
+// CHECK:STDOUT:   %import_ref.1 = import_ref ir1, inst+2, unused
+// CHECK:STDOUT:   %import_ref.2: <unbound element of class Cycle> = import_ref ir1, inst+18, used [template = imports.%.1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
-// CHECK:STDOUT:   .c = %import_ref
+// CHECK:STDOUT:   .Self = %import_ref.1
+// CHECK:STDOUT:   .c = %import_ref.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {

+ 1 - 0
toolchain/check/testdata/class/init.carbon

@@ -65,6 +65,7 @@ fn MakeReorder(n: i32, next: Class*) -> Class {
 // CHECK:STDOUT:   %.loc9_11: <unbound element of class Class> = field_decl next, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .n = %.loc8
 // CHECK:STDOUT:   .next = %.loc9_11
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/class/init_as.carbon

@@ -41,6 +41,7 @@ fn F() -> i32 {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Class> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT:   .b = %.loc9
 // CHECK:STDOUT: }

+ 2 - 0
toolchain/check/testdata/class/init_nested.carbon

@@ -59,6 +59,7 @@ fn MakeOuter() -> Outer {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Inner> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Inner
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT:   .b = %.loc9
 // CHECK:STDOUT: }
@@ -70,6 +71,7 @@ fn MakeOuter() -> Outer {
 // CHECK:STDOUT:   %.loc16: <unbound element of class Outer> = field_decl d, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Outer
 // CHECK:STDOUT:   .c = %.loc15
 // CHECK:STDOUT:   .d = %.loc16
 // CHECK:STDOUT: }

+ 8 - 7
toolchain/check/testdata/class/method.carbon

@@ -5,15 +5,15 @@
 // AUTOUPDATE
 
 class Class {
-  fn F[self: Class]() -> i32;
-  fn G[addr self: Class*]() -> i32;
+  fn F[self: Self]() -> i32;
+  fn G[addr self: Self*]() -> i32;
 
   alias A = F;
 
   var k: i32;
 }
 
-fn Class.F[self: Class]() -> i32 {
+fn Class.F[self: Self]() -> i32 {
   return self.k;
 }
 
@@ -81,7 +81,7 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %Class.decl = class_decl @Class {} [template = constants.%Class]
 // CHECK:STDOUT:   %F: <function> = fn_decl @F {
-// CHECK:STDOUT:     %Class.ref.loc16: type = name_ref Class, %Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc16_12.1: Class = param self
 // CHECK:STDOUT:     @F.%self: Class = bind_name self, %self.loc16_12.1
 // CHECK:STDOUT:     %return.var.loc16: ref i32 = var <return slot>
@@ -132,14 +132,14 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
 // CHECK:STDOUT:   %F: <function> = fn_decl @F {
-// CHECK:STDOUT:     %Class.ref.loc8: type = name_ref Class, file.%Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc8: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc8_8.1: Class = param self
 // CHECK:STDOUT:     %self.loc8_8.2: Class = bind_name self, %self.loc8_8.1
 // CHECK:STDOUT:     %return.var.loc8: ref i32 = var <return slot>
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %G: <function> = fn_decl @G {
-// CHECK:STDOUT:     %Class.ref.loc9: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %.loc9_24: type = ptr_type Class [template = constants.%.1]
+// CHECK:STDOUT:     %Self.ref.loc9: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:     %.loc9_23: type = ptr_type Class [template = constants.%.1]
 // CHECK:STDOUT:     %self.loc9_13.1: Class* = param self
 // CHECK:STDOUT:     %self.loc9_13.3: Class* = bind_name self, %self.loc9_13.1
 // CHECK:STDOUT:     %.loc9_8: Class* = addr_pattern %self.loc9_13.3
@@ -150,6 +150,7 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:   %.loc13: <unbound element of class Class> = field_decl k, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT:   .A = %A

+ 47 - 47
toolchain/check/testdata/class/nested.carbon

@@ -17,15 +17,14 @@ class Outer {
 }
 
 fn F(a: Outer*) {
-  // TODO: Simplify this once `Outer.Inner` works.
-  // let b: Outer.Inner* = (*a).pi;
+  let b: Outer.Inner* = (*a).pi;
 
   (*a).po = a;
   (*a).qo = a;
   (*a).pi = (*a).pi;
-  (*(*a).pi).po = a;
-  (*(*a).pi).pi = (*a).pi;
-  (*(*a).pi).qi = (*a).pi;
+  (*b).po = a;
+  (*b).pi = (*a).pi;
+  (*b).qi = (*a).pi;
 }
 
 // CHECK:STDOUT: --- nested.carbon
@@ -72,6 +71,7 @@ fn F(a: Outer*) {
 // CHECK:STDOUT:   %.loc16_9: <unbound element of class Outer> = field_decl pi, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Outer
 // CHECK:STDOUT:   .Inner = %Inner.decl
 // CHECK:STDOUT:   .po = %.loc14_9
 // CHECK:STDOUT:   .qo = %.loc15_9
@@ -90,6 +90,7 @@ fn F(a: Outer*) {
 // CHECK:STDOUT:   %.loc11_11: <unbound element of class Inner> = field_decl qi, element2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Inner
 // CHECK:STDOUT:   .pi = %.loc9_11
 // CHECK:STDOUT:   .po = %.loc10_11
 // CHECK:STDOUT:   .qi = %.loc11_11
@@ -97,54 +98,53 @@ fn F(a: Outer*) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(%a: Outer*) {
 // CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   %Outer.ref: type = name_ref Outer, file.%Outer.decl [template = constants.%Outer]
+// CHECK:STDOUT:   %Inner.ref: type = name_ref Inner, @Outer.%Inner.decl [template = constants.%Inner]
+// CHECK:STDOUT:   %.loc20_21: type = ptr_type Inner [template = constants.%.1]
+// CHECK:STDOUT:   %a.ref.loc20: Outer* = name_ref a, %a
+// CHECK:STDOUT:   %.loc20_26: ref Outer = deref %a.ref.loc20
+// CHECK:STDOUT:   %.loc20_29.1: ref Inner* = class_element_access %.loc20_26, element2
+// CHECK:STDOUT:   %.loc20_29.2: Inner* = bind_value %.loc20_29.1
+// CHECK:STDOUT:   %b: Inner* = bind_name b, %.loc20_29.2
+// CHECK:STDOUT:   %a.ref.loc22_5: Outer* = name_ref a, %a
+// CHECK:STDOUT:   %.loc22_4: ref Outer = deref %a.ref.loc22_5
+// CHECK:STDOUT:   %.loc22_7: ref Outer* = class_element_access %.loc22_4, element0
+// CHECK:STDOUT:   %a.ref.loc22_13: Outer* = name_ref a, %a
+// CHECK:STDOUT:   assign %.loc22_7, %a.ref.loc22_13
 // CHECK:STDOUT:   %a.ref.loc23_5: Outer* = name_ref a, %a
 // CHECK:STDOUT:   %.loc23_4: ref Outer = deref %a.ref.loc23_5
-// CHECK:STDOUT:   %.loc23_7: ref Outer* = class_element_access %.loc23_4, element0
+// CHECK:STDOUT:   %.loc23_7: ref Outer* = class_element_access %.loc23_4, element1
 // CHECK:STDOUT:   %a.ref.loc23_13: Outer* = name_ref a, %a
 // CHECK:STDOUT:   assign %.loc23_7, %a.ref.loc23_13
 // CHECK:STDOUT:   %a.ref.loc24_5: Outer* = name_ref a, %a
 // CHECK:STDOUT:   %.loc24_4: ref Outer = deref %a.ref.loc24_5
-// CHECK:STDOUT:   %.loc24_7: ref Outer* = class_element_access %.loc24_4, element1
-// CHECK:STDOUT:   %a.ref.loc24_13: Outer* = name_ref a, %a
-// CHECK:STDOUT:   assign %.loc24_7, %a.ref.loc24_13
-// CHECK:STDOUT:   %a.ref.loc25_5: Outer* = name_ref a, %a
-// CHECK:STDOUT:   %.loc25_4: ref Outer = deref %a.ref.loc25_5
-// CHECK:STDOUT:   %.loc25_7: ref Inner* = class_element_access %.loc25_4, element2
-// CHECK:STDOUT:   %a.ref.loc25_15: Outer* = name_ref a, %a
-// CHECK:STDOUT:   %.loc25_14: ref Outer = deref %a.ref.loc25_15
-// CHECK:STDOUT:   %.loc25_17.1: ref Inner* = class_element_access %.loc25_14, element2
-// CHECK:STDOUT:   %.loc25_17.2: Inner* = bind_value %.loc25_17.1
-// CHECK:STDOUT:   assign %.loc25_7, %.loc25_17.2
-// CHECK:STDOUT:   %a.ref.loc26_7: Outer* = name_ref a, %a
-// CHECK:STDOUT:   %.loc26_6: ref Outer = deref %a.ref.loc26_7
-// CHECK:STDOUT:   %.loc26_9.1: ref Inner* = class_element_access %.loc26_6, element2
-// CHECK:STDOUT:   %.loc26_9.2: Inner* = bind_value %.loc26_9.1
-// CHECK:STDOUT:   %.loc26_4: ref Inner = deref %.loc26_9.2
-// CHECK:STDOUT:   %.loc26_13: ref Outer* = class_element_access %.loc26_4, element1
-// CHECK:STDOUT:   %a.ref.loc26_19: Outer* = name_ref a, %a
-// CHECK:STDOUT:   assign %.loc26_13, %a.ref.loc26_19
-// CHECK:STDOUT:   %a.ref.loc27_7: Outer* = name_ref a, %a
-// CHECK:STDOUT:   %.loc27_6: ref Outer = deref %a.ref.loc27_7
-// CHECK:STDOUT:   %.loc27_9.1: ref Inner* = class_element_access %.loc27_6, element2
-// CHECK:STDOUT:   %.loc27_9.2: Inner* = bind_value %.loc27_9.1
-// CHECK:STDOUT:   %.loc27_4: ref Inner = deref %.loc27_9.2
-// CHECK:STDOUT:   %.loc27_13: ref Inner* = class_element_access %.loc27_4, element0
-// CHECK:STDOUT:   %a.ref.loc27_21: Outer* = name_ref a, %a
-// CHECK:STDOUT:   %.loc27_20: ref Outer = deref %a.ref.loc27_21
-// CHECK:STDOUT:   %.loc27_23.1: ref Inner* = class_element_access %.loc27_20, element2
-// CHECK:STDOUT:   %.loc27_23.2: Inner* = bind_value %.loc27_23.1
-// CHECK:STDOUT:   assign %.loc27_13, %.loc27_23.2
-// CHECK:STDOUT:   %a.ref.loc28_7: Outer* = name_ref a, %a
-// CHECK:STDOUT:   %.loc28_6: ref Outer = deref %a.ref.loc28_7
-// CHECK:STDOUT:   %.loc28_9.1: ref Inner* = class_element_access %.loc28_6, element2
-// CHECK:STDOUT:   %.loc28_9.2: Inner* = bind_value %.loc28_9.1
-// CHECK:STDOUT:   %.loc28_4: ref Inner = deref %.loc28_9.2
-// CHECK:STDOUT:   %.loc28_13: ref Inner* = class_element_access %.loc28_4, element2
-// CHECK:STDOUT:   %a.ref.loc28_21: Outer* = name_ref a, %a
-// CHECK:STDOUT:   %.loc28_20: ref Outer = deref %a.ref.loc28_21
-// CHECK:STDOUT:   %.loc28_23.1: ref Inner* = class_element_access %.loc28_20, element2
-// CHECK:STDOUT:   %.loc28_23.2: Inner* = bind_value %.loc28_23.1
-// CHECK:STDOUT:   assign %.loc28_13, %.loc28_23.2
+// CHECK:STDOUT:   %.loc24_7: ref Inner* = class_element_access %.loc24_4, element2
+// CHECK:STDOUT:   %a.ref.loc24_15: Outer* = name_ref a, %a
+// CHECK:STDOUT:   %.loc24_14: ref Outer = deref %a.ref.loc24_15
+// CHECK:STDOUT:   %.loc24_17.1: ref Inner* = class_element_access %.loc24_14, element2
+// CHECK:STDOUT:   %.loc24_17.2: Inner* = bind_value %.loc24_17.1
+// CHECK:STDOUT:   assign %.loc24_7, %.loc24_17.2
+// CHECK:STDOUT:   %b.ref.loc25: Inner* = name_ref b, %b
+// CHECK:STDOUT:   %.loc25_4: ref Inner = deref %b.ref.loc25
+// CHECK:STDOUT:   %.loc25_7: ref Outer* = class_element_access %.loc25_4, element1
+// CHECK:STDOUT:   %a.ref.loc25: Outer* = name_ref a, %a
+// CHECK:STDOUT:   assign %.loc25_7, %a.ref.loc25
+// CHECK:STDOUT:   %b.ref.loc26: Inner* = name_ref b, %b
+// CHECK:STDOUT:   %.loc26_4: ref Inner = deref %b.ref.loc26
+// CHECK:STDOUT:   %.loc26_7: ref Inner* = class_element_access %.loc26_4, element0
+// CHECK:STDOUT:   %a.ref.loc26: Outer* = name_ref a, %a
+// CHECK:STDOUT:   %.loc26_14: ref Outer = deref %a.ref.loc26
+// CHECK:STDOUT:   %.loc26_17.1: ref Inner* = class_element_access %.loc26_14, element2
+// CHECK:STDOUT:   %.loc26_17.2: Inner* = bind_value %.loc26_17.1
+// CHECK:STDOUT:   assign %.loc26_7, %.loc26_17.2
+// CHECK:STDOUT:   %b.ref.loc27: Inner* = name_ref b, %b
+// CHECK:STDOUT:   %.loc27_4: ref Inner = deref %b.ref.loc27
+// CHECK:STDOUT:   %.loc27_7: ref Inner* = class_element_access %.loc27_4, element2
+// CHECK:STDOUT:   %a.ref.loc27: Outer* = name_ref a, %a
+// CHECK:STDOUT:   %.loc27_14: ref Outer = deref %a.ref.loc27
+// CHECK:STDOUT:   %.loc27_17.1: ref Inner* = class_element_access %.loc27_14, element2
+// CHECK:STDOUT:   %.loc27_17.2: Inner* = bind_value %.loc27_17.1
+// CHECK:STDOUT:   assign %.loc27_7, %.loc27_17.2
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 0
toolchain/check/testdata/class/nested_name.carbon

@@ -56,6 +56,7 @@ fn G(o: Outer) {
 // CHECK:STDOUT:   %Inner.decl = class_decl @Inner {} [template = constants.%Inner]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Outer
 // CHECK:STDOUT:   .Inner = %Inner.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -63,6 +64,7 @@ fn G(o: Outer) {
 // CHECK:STDOUT:   %.loc9: <unbound element of class Inner> = field_decl n, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Inner
 // CHECK:STDOUT:   .n = %.loc9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 27 - 26
toolchain/check/testdata/class/raw_self.carbon

@@ -5,16 +5,16 @@
 // AUTOUPDATE
 
 class Class {
-  fn F[addr self: Class*](r#self: i32);
-  fn G[self: Class](r#self: i32) -> (i32, i32);
+  fn F[addr self: Self*](r#self: i32);
+  fn G[self: Self](r#self: i32) -> (i32, i32);
   var n: i32;
 }
 
-fn Class.F[addr self: Class*](r#self: i32) {
+fn Class.F[addr self: Self*](r#self: i32) {
   (*self).n = r#self;
 }
 
-fn Class.G[self: Class](r#self: i32) -> (i32, i32) {
+fn Class.G[self: Self](r#self: i32) -> (i32, i32) {
   return (self.n, r#self);
 }
 
@@ -37,70 +37,71 @@ fn Class.G[self: Class](r#self: i32) -> (i32, i32) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %Class.decl = class_decl @Class {} [template = constants.%Class]
 // CHECK:STDOUT:   %F: <function> = fn_decl @F {
-// CHECK:STDOUT:     %Class.ref.loc13: type = name_ref Class, %Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %.loc13_28: type = ptr_type Class [template = constants.%.1]
+// CHECK:STDOUT:     %Self.ref.loc13: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:     %.loc13_27: type = ptr_type Class [template = constants.%.1]
 // CHECK:STDOUT:     %self.loc13_17.1: Class* = param self
 // CHECK:STDOUT:     @F.%self.loc13_17: Class* = bind_name self, %self.loc13_17.1
 // CHECK:STDOUT:     @F.%.loc13: Class* = addr_pattern @F.%self.loc13_17
-// CHECK:STDOUT:     %self.loc13_31.1: i32 = param r#self
-// CHECK:STDOUT:     @F.%self.loc13_31: i32 = bind_name r#self, %self.loc13_31.1
+// CHECK:STDOUT:     %self.loc13_30.1: i32 = param r#self
+// CHECK:STDOUT:     @F.%self.loc13_30: i32 = bind_name r#self, %self.loc13_30.1
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %G: <function> = fn_decl @G {
-// CHECK:STDOUT:     %Class.ref.loc17: type = name_ref Class, %Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc17: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc17_12.1: Class = param self
 // CHECK:STDOUT:     @G.%self.loc17_12: Class = bind_name self, %self.loc17_12.1
-// CHECK:STDOUT:     %self.loc17_25.1: i32 = param r#self
-// CHECK:STDOUT:     @G.%self.loc17_25: i32 = bind_name r#self, %self.loc17_25.1
-// CHECK:STDOUT:     %.loc17_50.1: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:     %.loc17_50.2: type = converted %.loc17_50.1, constants.%.3 [template = constants.%.3]
+// CHECK:STDOUT:     %self.loc17_24.1: i32 = param r#self
+// CHECK:STDOUT:     @G.%self.loc17_24: i32 = bind_name r#self, %self.loc17_24.1
+// CHECK:STDOUT:     %.loc17_49.1: (type, type) = tuple_literal (i32, i32)
+// CHECK:STDOUT:     %.loc17_49.2: type = converted %.loc17_49.1, constants.%.3 [template = constants.%.3]
 // CHECK:STDOUT:     @G.%return: ref (i32, i32) = var <return slot>
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
 // CHECK:STDOUT:   %F: <function> = fn_decl @F {
-// CHECK:STDOUT:     %Class.ref.loc8: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %.loc8_24: type = ptr_type Class [template = constants.%.1]
+// CHECK:STDOUT:     %Self.ref.loc8: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:     %.loc8_23: type = ptr_type Class [template = constants.%.1]
 // CHECK:STDOUT:     %self.loc8_13.1: Class* = param self
 // CHECK:STDOUT:     %self.loc8_13.3: Class* = bind_name self, %self.loc8_13.1
 // CHECK:STDOUT:     %.loc8_8: Class* = addr_pattern %self.loc8_13.3
-// CHECK:STDOUT:     %self.loc8_27.1: i32 = param r#self
-// CHECK:STDOUT:     %self.loc8_27.2: i32 = bind_name r#self, %self.loc8_27.1
+// CHECK:STDOUT:     %self.loc8_26.1: i32 = param r#self
+// CHECK:STDOUT:     %self.loc8_26.2: i32 = bind_name r#self, %self.loc8_26.1
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %G: <function> = fn_decl @G {
-// CHECK:STDOUT:     %Class.ref.loc9: type = name_ref Class, file.%Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc9: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc9_8.1: Class = param self
 // CHECK:STDOUT:     %self.loc9_8.2: Class = bind_name self, %self.loc9_8.1
-// CHECK:STDOUT:     %self.loc9_21.1: i32 = param r#self
-// CHECK:STDOUT:     %self.loc9_21.2: i32 = bind_name r#self, %self.loc9_21.1
-// CHECK:STDOUT:     %.loc9_46.1: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:     %.loc9_46.2: type = converted %.loc9_46.1, constants.%.3 [template = constants.%.3]
+// CHECK:STDOUT:     %self.loc9_20.1: i32 = param r#self
+// CHECK:STDOUT:     %self.loc9_20.2: i32 = bind_name r#self, %self.loc9_20.1
+// CHECK:STDOUT:     %.loc9_45.1: (type, type) = tuple_literal (i32, i32)
+// CHECK:STDOUT:     %.loc9_45.2: type = converted %.loc9_45.1, constants.%.3 [template = constants.%.3]
 // CHECK:STDOUT:     %return.var: ref (i32, i32) = var <return slot>
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %.loc10: <unbound element of class Class> = field_decl n, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT:   .n = %.loc10
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F[addr %self.loc13_17: Class*](%self.loc13_31: i32) {
+// CHECK:STDOUT: fn @F[addr %self.loc13_17: Class*](%self.loc13_30: i32) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %self.ref.loc14_5: Class* = name_ref self, %self.loc13_17
 // CHECK:STDOUT:   %.loc14_4: ref Class = deref %self.ref.loc14_5
 // CHECK:STDOUT:   %.loc14_10: ref i32 = class_element_access %.loc14_4, element0
-// CHECK:STDOUT:   %self.ref.loc14_15: i32 = name_ref r#self, %self.loc13_31
+// CHECK:STDOUT:   %self.ref.loc14_15: i32 = name_ref r#self, %self.loc13_30
 // CHECK:STDOUT:   assign %.loc14_10, %self.ref.loc14_15
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @G[%self.loc17_12: Class](%self.loc17_25: i32) -> %return: (i32, i32) {
+// CHECK:STDOUT: fn @G[%self.loc17_12: Class](%self.loc17_24: i32) -> %return: (i32, i32) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %self.ref.loc18_11: Class = name_ref self, %self.loc17_12
 // CHECK:STDOUT:   %.loc18_15.1: ref i32 = class_element_access %self.ref.loc18_11, element0
 // CHECK:STDOUT:   %.loc18_15.2: i32 = bind_value %.loc18_15.1
-// CHECK:STDOUT:   %self.ref.loc18_19: i32 = name_ref r#self, %self.loc17_25
+// CHECK:STDOUT:   %self.ref.loc18_19: i32 = name_ref r#self, %self.loc17_24
 // CHECK:STDOUT:   %.loc18_25.1: (i32, i32) = tuple_literal (%.loc18_15.2, %self.ref.loc18_19)
 // CHECK:STDOUT:   %.loc18_25.2: ref i32 = tuple_access %return, element0
 // CHECK:STDOUT:   %.loc18_25.3: init i32 = initialize_from %.loc18_15.2 to %.loc18_25.2

+ 52 - 2
toolchain/check/testdata/class/raw_self_type.carbon

@@ -11,29 +11,74 @@ class Class {
   }
 }
 
+class MemberNamedSelf {
+  class r#Self {}
+
+  fn F(x: Self, y: r#Self);
+}
+
+fn MemberNamedSelf.F(x: Self, y: r#Self) {}
+
 // CHECK:STDOUT: --- raw_self_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = ptr_type Class [template]
 // CHECK:STDOUT:   %.2: type = struct_type {} [template]
+// CHECK:STDOUT:   %MemberNamedSelf: type = class_type @MemberNamedSelf [template]
+// CHECK:STDOUT:   %Self: type = class_type @Self [template]
+// CHECK:STDOUT:   %.3: type = tuple_type () [template]
+// CHECK:STDOUT:   %.4: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace {
 // CHECK:STDOUT:     .Class = %Class.decl
+// CHECK:STDOUT:     .MemberNamedSelf = %MemberNamedSelf.decl
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %Class.decl = class_decl @Class {} [template = constants.%Class]
+// CHECK:STDOUT:   %MemberNamedSelf.decl = class_decl @MemberNamedSelf {} [template = constants.%MemberNamedSelf]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 {
+// CHECK:STDOUT:     %Self.ref.loc20_25: type = name_ref Self, constants.%MemberNamedSelf [template = constants.%MemberNamedSelf]
+// CHECK:STDOUT:     %x.loc20_22.1: MemberNamedSelf = param x
+// CHECK:STDOUT:     @F.2.%x: MemberNamedSelf = bind_name x, %x.loc20_22.1
+// CHECK:STDOUT:     %Self.ref.loc20_34: type = name_ref r#Self, @MemberNamedSelf.%Self.decl [template = constants.%Self]
+// CHECK:STDOUT:     %y.loc20_31.1: r#Self = param y
+// CHECK:STDOUT:     @F.2.%y: r#Self = bind_name y, %y.loc20_31.1
+// CHECK:STDOUT:   } [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F {} [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 {} [template]
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
+// CHECK:STDOUT:   .F = %F
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: class @MemberNamedSelf {
+// CHECK:STDOUT:   %Self.decl = class_decl @Self {} [template = constants.%Self]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 {
+// CHECK:STDOUT:     %Self.ref.loc17_11: type = name_ref Self, constants.%MemberNamedSelf [template = constants.%MemberNamedSelf]
+// CHECK:STDOUT:     %x.loc17_8.1: MemberNamedSelf = param x
+// CHECK:STDOUT:     %x.loc17_8.2: MemberNamedSelf = bind_name x, %x.loc17_8.1
+// CHECK:STDOUT:     %Self.ref.loc17_20: type = name_ref r#Self, %Self.decl [template = constants.%Self]
+// CHECK:STDOUT:     %y.loc17_17.1: r#Self = param y
+// CHECK:STDOUT:     %y.loc17_17.2: r#Self = bind_name y, %y.loc17_17.1
+// CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%MemberNamedSelf
+// CHECK:STDOUT:   .r#Self = %Self.decl
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F() {
+// CHECK:STDOUT: class @Self {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Self
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: fn @F.1() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %Self.ref.loc9: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:   %.loc9: type = ptr_type Class [template = constants.%.1]
@@ -49,3 +94,8 @@ class Class {
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: fn @F.2(%x: MemberNamedSelf, %y: r#Self) {
+// CHECK:STDOUT: !entry:
+// CHECK:STDOUT:   return
+// CHECK:STDOUT: }
+// CHECK:STDOUT:

+ 20 - 5
toolchain/check/testdata/class/redeclaration.carbon

@@ -7,16 +7,18 @@
 class Class;
 
 class Class {
-  fn F();
+  fn F[self: Self](b: bool);
 }
 
-fn Class.F() {}
+fn Class.F[self: Self](b: bool) {}
 
 // CHECK:STDOUT: --- redeclaration.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT:   %.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.3: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -25,17 +27,30 @@ fn Class.F() {}
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %Class.decl.loc7 = class_decl @Class {} [template = constants.%Class]
 // CHECK:STDOUT:   %Class.decl.loc9 = class_decl @Class {} [template = constants.%Class]
-// CHECK:STDOUT:   %F: <function> = fn_decl @F {} [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F {
+// CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:     %self.loc13_12.1: Class = param self
+// CHECK:STDOUT:     @F.%self: Class = bind_name self, %self.loc13_12.1
+// CHECK:STDOUT:     %b.loc13_24.1: bool = param b
+// CHECK:STDOUT:     @F.%b: bool = bind_name b, %b.loc13_24.1
+// CHECK:STDOUT:   } [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F {} [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F {
+// CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:     %self.loc10_8.1: Class = param self
+// CHECK:STDOUT:     %self.loc10_8.2: Class = bind_name self, %self.loc10_8.1
+// CHECK:STDOUT:     %b.loc10_20.1: bool = param b
+// CHECK:STDOUT:     %b.loc10_20.2: bool = bind_name b, %b.loc10_20.1
+// CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: fn @F() {
+// CHECK:STDOUT: fn @F[%self: Class](%b: bool) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 12 - 3
toolchain/check/testdata/class/redeclaration_introducer.carbon

@@ -35,9 +35,18 @@ abstract class C {}
 // CHECK:STDOUT:   %C.decl.loc13 = class_decl @C {} [template = constants.%C]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @A {}
+// CHECK:STDOUT: class @A {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @B {}
+// CHECK:STDOUT: class @B {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%B
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @C {}
+// CHECK:STDOUT: class @C {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
+// CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 10 - 5
toolchain/check/testdata/class/reenter_scope.carbon

@@ -10,6 +10,7 @@ class Class {
 }
 
 fn Class.F() -> i32 {
+  Self.G();
   return G();
 }
 
@@ -39,17 +40,21 @@ fn Class.F() -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %G.ref: <function> = name_ref G, @Class.%G [template = @Class.%G]
-// CHECK:STDOUT:   %.loc13_11.1: init i32 = call %G.ref()
-// CHECK:STDOUT:   %.loc13_13: i32 = value_of_initializer %.loc13_11.1
-// CHECK:STDOUT:   %.loc13_11.2: i32 = converted %.loc13_11.1, %.loc13_13
-// CHECK:STDOUT:   return %.loc13_11.2
+// CHECK:STDOUT:   %Self.ref: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:   %G.ref.loc13: <function> = name_ref G, @Class.%G [template = @Class.%G]
+// CHECK:STDOUT:   %.loc13: init i32 = call %G.ref.loc13()
+// CHECK:STDOUT:   %G.ref.loc14: <function> = name_ref G, @Class.%G [template = @Class.%G]
+// CHECK:STDOUT:   %.loc14_11.1: init i32 = call %G.ref.loc14()
+// CHECK:STDOUT:   %.loc14_13: i32 = value_of_initializer %.loc14_11.1
+// CHECK:STDOUT:   %.loc14_11.2: i32 = converted %.loc14_11.1, %.loc14_13
+// CHECK:STDOUT:   return %.loc14_11.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32;

+ 1 - 0
toolchain/check/testdata/class/scope.carbon

@@ -54,6 +54,7 @@ fn Run() {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT: }

+ 11 - 10
toolchain/check/testdata/class/self.carbon

@@ -5,17 +5,17 @@
 // AUTOUPDATE
 
 class Class {
-  fn F[self: Class]() -> i32;
-  fn G[addr self: Class*]() -> i32;
+  fn F[self: Self]() -> i32;
+  fn G[addr self: Self*]() -> i32;
 
   var n: i32;
 }
 
-fn Class.F[self: Class]() -> i32 {
+fn Class.F[self: Self]() -> i32 {
   return self.n;
 }
 
-fn Class.G[addr self: Class*]() -> i32 {
+fn Class.G[addr self: Self*]() -> i32 {
   return (*self).n;
 }
 
@@ -35,14 +35,14 @@ fn Class.G[addr self: Class*]() -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %Class.decl = class_decl @Class {} [template = constants.%Class]
 // CHECK:STDOUT:   %F: <function> = fn_decl @F {
-// CHECK:STDOUT:     %Class.ref.loc14: type = name_ref Class, %Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc14: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc14_12.1: Class = param self
 // CHECK:STDOUT:     @F.%self: Class = bind_name self, %self.loc14_12.1
 // CHECK:STDOUT:     %return.var.loc14: ref i32 = var <return slot>
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %G: <function> = fn_decl @G {
-// CHECK:STDOUT:     %Class.ref.loc18: type = name_ref Class, %Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %.loc18_28: type = ptr_type Class [template = constants.%.1]
+// CHECK:STDOUT:     %Self.ref.loc18: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:     %.loc18_27: type = ptr_type Class [template = constants.%.1]
 // CHECK:STDOUT:     %self.loc18_17.1: Class* = param self
 // CHECK:STDOUT:     @G.%self: Class* = bind_name self, %self.loc18_17.1
 // CHECK:STDOUT:     @G.%.loc18: Class* = addr_pattern @G.%self
@@ -52,14 +52,14 @@ fn Class.G[addr self: Class*]() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
 // CHECK:STDOUT:   %F: <function> = fn_decl @F {
-// CHECK:STDOUT:     %Class.ref.loc8: type = name_ref Class, file.%Class.decl [template = constants.%Class]
+// CHECK:STDOUT:     %Self.ref.loc8: type = name_ref Self, constants.%Class [template = constants.%Class]
 // CHECK:STDOUT:     %self.loc8_8.1: Class = param self
 // CHECK:STDOUT:     %self.loc8_8.2: Class = bind_name self, %self.loc8_8.1
 // CHECK:STDOUT:     %return.var.loc8: ref i32 = var <return slot>
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %G: <function> = fn_decl @G {
-// CHECK:STDOUT:     %Class.ref.loc9: type = name_ref Class, file.%Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %.loc9_24: type = ptr_type Class [template = constants.%.1]
+// CHECK:STDOUT:     %Self.ref.loc9: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:     %.loc9_23: type = ptr_type Class [template = constants.%.1]
 // CHECK:STDOUT:     %self.loc9_13.1: Class* = param self
 // CHECK:STDOUT:     %self.loc9_13.3: Class* = bind_name self, %self.loc9_13.1
 // CHECK:STDOUT:     %.loc9_8: Class* = addr_pattern %self.loc9_13.3
@@ -68,6 +68,7 @@ fn Class.G[addr self: Class*]() -> i32 {
 // CHECK:STDOUT:   %.loc11: <unbound element of class Class> = field_decl n, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .G = %G
 // CHECK:STDOUT:   .n = %.loc11

+ 2 - 0
toolchain/check/testdata/class/self_conversion.carbon

@@ -80,6 +80,7 @@ fn Call(p: Derived*) -> i32 {
 // CHECK:STDOUT:   %.loc8: <unbound element of class Base> = field_decl a, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Base
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -101,6 +102,7 @@ fn Call(p: Derived*) -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Derived
 // CHECK:STDOUT:   .base = %.loc12
 // CHECK:STDOUT:   .SelfBase = %SelfBase
 // CHECK:STDOUT:   .AddrSelfBase = %AddrSelfBase

+ 14 - 16
toolchain/check/testdata/class/self_type.carbon

@@ -9,10 +9,7 @@ class Class {
   var p: Self*;
 }
 
-// TODO: Reenter the class scope when defining methods, so that we can support
-// `Self` here too.
-// fn Class.F[self: Self]() -> i32 {
-fn Class.F[self: Class]() -> i32 {
+fn Class.F[self: Self]() -> i32 {
   return (*self.p).F();
 }
 
@@ -32,9 +29,9 @@ fn Class.F[self: Class]() -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:   %Class.decl = class_decl @Class {} [template = constants.%Class]
 // CHECK:STDOUT:   %F: <function> = fn_decl @F {
-// CHECK:STDOUT:     %Class.ref: type = name_ref Class, %Class.decl [template = constants.%Class]
-// CHECK:STDOUT:     %self.loc15_12.1: Class = param self
-// CHECK:STDOUT:     @F.%self: Class = bind_name self, %self.loc15_12.1
+// CHECK:STDOUT:     %Self.ref: type = name_ref Self, constants.%Class [template = constants.%Class]
+// CHECK:STDOUT:     %self.loc12_12.1: Class = param self
+// CHECK:STDOUT:     @F.%self: Class = bind_name self, %self.loc12_12.1
 // CHECK:STDOUT:     %return.var: ref i32 = var <return slot>
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT: }
@@ -51,6 +48,7 @@ fn Class.F[self: Class]() -> i32 {
 // CHECK:STDOUT:   %.loc9_8: <unbound element of class Class> = field_decl p, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT:   .p = %.loc9_8
 // CHECK:STDOUT: }
@@ -58,14 +56,14 @@ fn Class.F[self: Class]() -> i32 {
 // CHECK:STDOUT: fn @F[%self: Class]() -> i32 {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %self.ref: Class = name_ref self, %self
-// CHECK:STDOUT:   %.loc16_16.1: ref Class* = class_element_access %self.ref, element0
-// CHECK:STDOUT:   %.loc16_16.2: Class* = bind_value %.loc16_16.1
-// CHECK:STDOUT:   %.loc16_11.1: ref Class = deref %.loc16_16.2
-// CHECK:STDOUT:   %.loc16_19: <bound method> = bound_method %.loc16_11.1, @Class.%F
-// CHECK:STDOUT:   %.loc16_11.2: Class = bind_value %.loc16_11.1
-// CHECK:STDOUT:   %.loc16_21.1: init i32 = call %.loc16_19(%.loc16_11.2)
-// CHECK:STDOUT:   %.loc16_23: i32 = value_of_initializer %.loc16_21.1
-// CHECK:STDOUT:   %.loc16_21.2: i32 = converted %.loc16_21.1, %.loc16_23
-// CHECK:STDOUT:   return %.loc16_21.2
+// CHECK:STDOUT:   %.loc13_16.1: ref Class* = class_element_access %self.ref, element0
+// CHECK:STDOUT:   %.loc13_16.2: Class* = bind_value %.loc13_16.1
+// CHECK:STDOUT:   %.loc13_11.1: ref Class = deref %.loc13_16.2
+// CHECK:STDOUT:   %.loc13_19: <bound method> = bound_method %.loc13_11.1, @Class.%F
+// CHECK:STDOUT:   %.loc13_11.2: Class = bind_value %.loc13_11.1
+// CHECK:STDOUT:   %.loc13_21.1: init i32 = call %.loc13_19(%.loc13_11.2)
+// CHECK:STDOUT:   %.loc13_23: i32 = value_of_initializer %.loc13_21.1
+// CHECK:STDOUT:   %.loc13_21.2: i32 = converted %.loc13_21.1, %.loc13_23
+// CHECK:STDOUT:   return %.loc13_21.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/class/static_method.carbon

@@ -39,6 +39,7 @@ fn Run() -> i32 {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%Class
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 1
toolchain/check/testdata/global/class_obj.carbon

@@ -28,7 +28,10 @@ var a: A = {};
 // CHECK:STDOUT:   %a: ref A = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @A {}
+// CHECK:STDOUT: class @A {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:

+ 4 - 1
toolchain/check/testdata/global/class_with_fun.carbon

@@ -37,7 +37,10 @@ var a: A = {};
 // CHECK:STDOUT:   %a: ref A = bind_name a, %a.var
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @A {}
+// CHECK:STDOUT: class @A {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%A
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @ret_a() -> %return: A {
 // CHECK:STDOUT: !entry:

+ 1 - 0
toolchain/check/testdata/if_expr/fail_not_in_function.carbon

@@ -53,6 +53,7 @@ class C {
 // CHECK:STDOUT:   if %.loc33 br !if.expr.then else br !if.expr.else
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .n = <unexpected instref inst+21>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/impl/fail_extend_impl_forall.carbon

@@ -78,6 +78,7 @@ class C {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 0
toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon

@@ -73,6 +73,7 @@ class E {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -83,6 +84,7 @@ class E {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%D
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -93,6 +95,7 @@ class E {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%E
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/impl/fail_extend_non_interface.carbon

@@ -31,6 +31,7 @@ class C {
 // CHECK:STDOUT:   impl_decl @impl {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/impl/fail_extend_partially_defined_interface.carbon

@@ -47,6 +47,7 @@ interface I {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/impl/fail_extend_undefined_interface.carbon

@@ -43,6 +43,7 @@ class C {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   has_error
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/impl/fail_todo_extend_impl.carbon

@@ -76,6 +76,7 @@ fn G(c: C) {
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   extend name_scope1
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 0
toolchain/check/testdata/impl/impl_as.carbon

@@ -53,6 +53,9 @@ class C {
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %Simple.ref: type = name_ref Simple, file.%Simple.decl [template = constants.%.1]
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.1();

+ 3 - 0
toolchain/check/testdata/impl/redeclaration.carbon

@@ -48,5 +48,8 @@ impl i32 as I {}
 // CHECK:STDOUT:   impl_decl @impl {
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [template = constants.%.1]
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%X
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/package_expr/syntax.carbon

@@ -144,6 +144,7 @@ fn Main() {
 // CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo {} [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .Foo = %Foo
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 1 - 0
toolchain/check/testdata/return/fail_return_with_returned_var.carbon

@@ -61,6 +61,7 @@ fn G() -> C {
 // CHECK:STDOUT:   %.loc18_28: <unbound element of class C> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .a = %.loc18_16
 // CHECK:STDOUT:   .b = %.loc18_28
 // CHECK:STDOUT: }

+ 1 - 0
toolchain/check/testdata/return/returned_var.carbon

@@ -53,6 +53,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:   %.loc9: <unbound element of class C> = field_decl b, element1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%C
 // CHECK:STDOUT:   .a = %.loc8
 // CHECK:STDOUT:   .b = %.loc9
 // CHECK:STDOUT: }

+ 4 - 1
toolchain/check/testdata/var/fail_not_copyable.carbon

@@ -46,7 +46,10 @@ fn F(x: X) {
 // CHECK:STDOUT:   } [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: class @X {}
+// CHECK:STDOUT: class @X {
+// CHECK:STDOUT: !members:
+// CHECK:STDOUT:   .Self = constants.%X
+// CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(%x: X) {
 // CHECK:STDOUT: !entry: