Prechádzať zdrojové kódy

Remove support for disambiguating a stringified type as being a type. (#3456)

Most of the calls to `StringifyType` already passed `true` for
`in_type_context`. Checking the rest, I found that every one of them was
already sufficiently clear that they were printing a type, or could be
made so with a very small change to the diagnostic text.
Richard Smith 2 rokov pred
rodič
commit
22dff46ed2

+ 1 - 1
toolchain/check/convert.cpp

@@ -804,7 +804,7 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
             : target.kind == ConversionTarget::Value
                 ? IncompleteTypeInValueConversion
                 : IncompleteTypeInConversion,
-            context.sem_ir().StringifyType(target.type_id, true));
+            context.sem_ir().StringifyType(target.type_id));
       })) {
     return SemIR::InstId::BuiltinError;
   }

+ 1 - 2
toolchain/check/decl_name_stack.cpp

@@ -181,8 +181,7 @@ auto DeclNameStack::CanResolveQualifier(NameContext& name_context,
         auto builder = context_->emitter().Build(
             name_context.parse_node, QualifiedDeclInIncompleteClassScope,
             context_->sem_ir().StringifyType(
-                context_->classes().Get(class_decl->class_id).self_type_id,
-                true));
+                context_->classes().Get(class_decl->class_id).self_type_id));
         context_->NoteIncompleteClass(class_decl->class_id, builder);
         builder.Emit();
       } else {

+ 2 - 2
toolchain/check/handle_binding_pattern.cpp

@@ -73,7 +73,7 @@ auto HandleBindingPattern(Context& context, Parse::NodeId parse_node) -> bool {
                 type_node_copy, IncompleteTypeInVarDecl,
                 enclosing_class_decl ? llvm::StringLiteral("Field")
                                      : llvm::StringLiteral("Variable"),
-                context.sem_ir().StringifyType(cast_type_id, true));
+                context.sem_ir().StringifyType(cast_type_id));
           })) {
         cast_type_id = SemIR::TypeId::Error;
       }
@@ -130,7 +130,7 @@ auto HandleBindingPattern(Context& context, Parse::NodeId parse_node) -> bool {
                               std::string);
             return context.emitter().Build(
                 type_node_copy, IncompleteTypeInLetDecl,
-                context.sem_ir().StringifyType(cast_type_id, true));
+                context.sem_ir().StringifyType(cast_type_id));
           })) {
         cast_type_id = SemIR::TypeId::Error;
       }

+ 2 - 3
toolchain/check/handle_call_expr.cpp

@@ -25,9 +25,8 @@ auto HandleCallExpr(Context& context, Parse::NodeId parse_node) -> bool {
     if (callee_type_id != SemIR::TypeId::Error) {
       CARBON_DIAGNOSTIC(CallToNonCallable, Error,
                         "Value of type `{0}` is not callable.", std::string);
-      context.emitter().Emit(
-          call_expr_parse_node, CallToNonCallable,
-          context.sem_ir().StringifyType(callee_type_id, true));
+      context.emitter().Emit(call_expr_parse_node, CallToNonCallable,
+                             context.sem_ir().StringifyType(callee_type_id));
     }
     context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
     return true;

+ 3 - 4
toolchain/check/handle_class.cpp

@@ -209,7 +209,7 @@ auto HandleBaseDecl(Context& context, Parse::NodeId parse_node) -> bool {
                           "Base `{0}` is an incomplete type.", std::string);
         return context.emitter().Build(
             parse_node, IncompleteTypeInBaseDecl,
-            context.sem_ir().StringifyType(base_type_id, true));
+            context.sem_ir().StringifyType(base_type_id));
       })) {
     base_type_id = SemIR::TypeId::Error;
   }
@@ -230,9 +230,8 @@ auto HandleBaseDecl(Context& context, Parse::NodeId parse_node) -> bool {
                         "Deriving from final type `{0}`. Base type must be an "
                         "`abstract` or `base` class.",
                         std::string);
-      context.emitter().Emit(
-          parse_node, BaseIsFinal,
-          context.sem_ir().StringifyType(base_type_id, true));
+      context.emitter().Emit(parse_node, BaseIsFinal,
+                             context.sem_ir().StringifyType(base_type_id));
     }
   }
 

+ 2 - 2
toolchain/check/handle_function.cpp

@@ -37,7 +37,7 @@ static auto BuildFunctionDecl(Context& context, bool is_definition)
                             std::string);
           return context.emitter().Build(
               return_node_copy, IncompleteTypeInFunctionReturnType,
-              context.sem_ir().StringifyType(return_type_id, true));
+              context.sem_ir().StringifyType(return_type_id));
         })) {
       return_type_id = SemIR::TypeId::Error;
     } else if (!SemIR::GetInitializingRepresentation(context.sem_ir(),
@@ -202,7 +202,7 @@ auto HandleFunctionDefinitionStart(Context& context, Parse::NodeId parse_node)
           std::string);
       return context.emitter().Build(
           param.parse_node(), IncompleteTypeInFunctionParam,
-          context.sem_ir().StringifyType(param.type_id(), true));
+          context.sem_ir().StringifyType(param.type_id()));
     });
 
     if (auto fn_param = param.TryAs<SemIR::Param>()) {

+ 3 - 3
toolchain/check/handle_index.cpp

@@ -24,8 +24,8 @@ static auto ValidateIntLiteralBound(Context& context, Parse::NodeId parse_node,
   const auto& index_val = context.ints().Get(index_inst.int_id);
   if (index_val.uge(size)) {
     CARBON_DIAGNOSTIC(IndexOutOfBounds, Error,
-                      "Index `{0}` is past the end of `{1}`.", llvm::APSInt,
-                      std::string);
+                      "Index `{0}` is past the end of type `{1}`.",
+                      llvm::APSInt, std::string);
     context.emitter().Emit(
         parse_node, IndexOutOfBounds,
         llvm::APSInt(index_val, /*isUnsigned=*/true),
@@ -107,7 +107,7 @@ auto HandleIndexExpr(Context& context, Parse::NodeId parse_node) -> bool {
     default: {
       if (operand_type_id != SemIR::TypeId::Error) {
         CARBON_DIAGNOSTIC(TypeNotIndexable, Error,
-                          "`{0}` does not support indexing.", std::string);
+                          "Type `{0}` does not support indexing.", std::string);
         context.emitter().Emit(parse_node, TypeNotIndexable,
                                context.sem_ir().StringifyType(operand_type_id));
       }

+ 5 - 5
toolchain/check/handle_name.cpp

@@ -25,10 +25,10 @@ static auto GetAsNameScope(Context& context, SemIR::InstId base_id)
       CARBON_DIAGNOSTIC(QualifiedExprInIncompleteClassScope, Error,
                         "Member access into incomplete class `{0}`.",
                         std::string);
-      auto builder = context.emitter().Build(
-          context.insts().Get(base_id).parse_node(),
-          QualifiedExprInIncompleteClassScope,
-          context.sem_ir().StringifyTypeExpr(base_id, true));
+      auto builder =
+          context.emitter().Build(context.insts().Get(base_id).parse_node(),
+                                  QualifiedExprInIncompleteClassScope,
+                                  context.sem_ir().StringifyTypeExpr(base_id));
       context.NoteIncompleteClass(base_as_class->class_id, builder);
       builder.Emit();
     }
@@ -98,7 +98,7 @@ auto HandleMemberAccessExpr(Context& context, Parse::NodeId parse_node)
         return context.emitter().Build(
             context.insts().Get(base_id).parse_node(),
             IncompleteTypeInMemberAccess,
-            context.sem_ir().StringifyType(base_type_id, true));
+            context.sem_ir().StringifyType(base_type_id));
       })) {
     context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
     return true;

+ 4 - 6
toolchain/check/return.cpp

@@ -47,7 +47,7 @@ static auto NoteReturnType(Context& context, Context::DiagnosticBuilder& diag,
   CARBON_DIAGNOSTIC(ReturnTypeHereNote, Note,
                     "Return type of function is `{0}`.", std::string);
   diag.Note(type_parse_node, ReturnTypeHereNote,
-            context.sem_ir().StringifyType(function.return_type_id, true));
+            context.sem_ir().StringifyType(function.return_type_id));
 }
 
 // Produces a note pointing at the currently in scope `returned var`.
@@ -81,7 +81,7 @@ auto CheckReturnedVar(Context& context, Parse::NodeId returned_node,
                       std::string);
     auto diag =
         context.emitter().Build(type_node, ReturnedVarWrongType,
-                                context.sem_ir().StringifyType(type_id, true));
+                                context.sem_ir().StringifyType(type_id));
     NoteReturnType(context, diag, function);
     diag.Emit();
     return SemIR::InstId::BuiltinError;
@@ -113,10 +113,8 @@ auto BuildReturnWithNoExpr(Context& context, Parse::NodeId parse_node) -> void {
 
   if (function.return_type_id.is_valid()) {
     CARBON_DIAGNOSTIC(ReturnStatementMissingExpr, Error,
-                      "Missing return value.", std::string);
-    auto diag = context.emitter().Build(
-        parse_node, ReturnStatementMissingExpr,
-        context.sem_ir().StringifyType(function.return_type_id));
+                      "Missing return value.");
+    auto diag = context.emitter().Build(parse_node, ReturnStatementMissingExpr);
     NoteReturnType(context, diag, function);
     diag.Emit();
   }

+ 1 - 1
toolchain/check/testdata/as/fail_no_conversion.carbon

@@ -4,7 +4,7 @@
 //
 // AUTOUPDATE
 
-// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+3]]:23: ERROR: Cannot convert from `i32` to `(i32, i32) as type` with `as`.
+// CHECK:STDERR: fail_no_conversion.carbon:[[@LINE+3]]:23: ERROR: Cannot convert from `i32` to `(i32, i32)` with `as`.
 // CHECK:STDERR: let n: (i32, i32) = 1 as (i32, i32);
 // CHECK:STDERR:                       ^~
 let n: (i32, i32) = 1 as (i32, i32);

+ 1 - 1
toolchain/check/testdata/index/fail_array_large_index.carbon

@@ -5,7 +5,7 @@
 // AUTOUPDATE
 
 var a: [i32; 1] = (12,);
-// CHECK:STDERR: fail_array_large_index.carbon:[[@LINE+3]]:35: ERROR: Index `295147905179352825855` is past the end of `[i32; 1]`.
+// CHECK:STDERR: fail_array_large_index.carbon:[[@LINE+3]]:35: ERROR: Index `295147905179352825855` is past the end of type `[i32; 1]`.
 // CHECK:STDERR: var b: i32 = a[0xFFFFFFFFFFFFFFFFF];
 // CHECK:STDERR:                                   ^
 var b: i32 = a[0xFFFFFFFFFFFFFFFFF];

+ 1 - 1
toolchain/check/testdata/index/fail_array_out_of_bound_access.carbon

@@ -5,7 +5,7 @@
 // AUTOUPDATE
 
 var a: [i32; 1] = (12,);
-// CHECK:STDERR: fail_array_out_of_bound_access.carbon:[[@LINE+3]]:17: ERROR: Index `2` is past the end of `[i32; 1]`.
+// CHECK:STDERR: fail_array_out_of_bound_access.carbon:[[@LINE+3]]:17: ERROR: Index `2` is past the end of type `[i32; 1]`.
 // CHECK:STDERR: var b: i32 = a[2];
 // CHECK:STDERR:                 ^
 var b: i32 = a[2];

+ 1 - 1
toolchain/check/testdata/index/fail_empty_tuple_access.carbon

@@ -7,7 +7,7 @@
 fn F() {}
 
 fn Run() {
-  // CHECK:STDERR: fail_empty_tuple_access.carbon:[[@LINE+3]]:8: ERROR: Index `0` is past the end of `() as type`.
+  // CHECK:STDERR: fail_empty_tuple_access.carbon:[[@LINE+3]]:8: ERROR: Index `0` is past the end of type `()`.
   // CHECK:STDERR:   F()[0];
   // CHECK:STDERR:        ^
   F()[0];

+ 2 - 2
toolchain/check/testdata/index/fail_invalid_base.carbon

@@ -20,12 +20,12 @@ fn F();
 // CHECK:STDERR:              ^
 var b: i32 = F[1];
 
-// CHECK:STDERR: fail_invalid_base.carbon:[[@LINE+3]]:32: ERROR: `{.a: i32, .b: i32}` does not support indexing.
+// CHECK:STDERR: fail_invalid_base.carbon:[[@LINE+3]]:32: ERROR: Type `{.a: i32, .b: i32}` does not support indexing.
 // CHECK:STDERR: var c: i32 = {.a = 1, .b = 2}[0];
 // CHECK:STDERR:                                ^
 var c: i32 = {.a = 1, .b = 2}[0];
 
-// CHECK:STDERR: fail_invalid_base.carbon:[[@LINE+3]]:34: ERROR: `type` does not support indexing.
+// CHECK:STDERR: fail_invalid_base.carbon:[[@LINE+3]]:34: ERROR: Type `type` does not support indexing.
 // CHECK:STDERR: var d: i32 = {.a: i32, .b: i32}[0];
 // CHECK:STDERR:                                  ^
 var d: i32 = {.a: i32, .b: i32}[0];

+ 1 - 1
toolchain/check/testdata/index/fail_non_tuple_access.carbon

@@ -5,7 +5,7 @@
 // AUTOUPDATE
 
 fn Main() {
-  // CHECK:STDERR: fail_non_tuple_access.carbon:[[@LINE+3]]:6: ERROR: `i32` does not support indexing.
+  // CHECK:STDERR: fail_non_tuple_access.carbon:[[@LINE+3]]:6: ERROR: Type `i32` does not support indexing.
   // CHECK:STDERR:   0[1];
   // CHECK:STDERR:      ^
   0[1];

+ 1 - 1
toolchain/check/testdata/index/fail_tuple_large_index.carbon

@@ -6,7 +6,7 @@
 
 var a: (i32,) = (12,);
 var b: (i32,) = a;
-// CHECK:STDERR: fail_tuple_large_index.carbon:[[@LINE+3]]:35: ERROR: Index `295147905179352825855` is past the end of `(i32,) as type`.
+// CHECK:STDERR: fail_tuple_large_index.carbon:[[@LINE+3]]:35: ERROR: Index `295147905179352825855` is past the end of type `(i32,)`.
 // CHECK:STDERR: var c: i32 = b[0xFFFFFFFFFFFFFFFFF];
 // CHECK:STDERR:                                   ^
 var c: i32 = b[0xFFFFFFFFFFFFFFFFF];

+ 1 - 1
toolchain/check/testdata/index/fail_tuple_out_of_bound_access.carbon

@@ -5,7 +5,7 @@
 // AUTOUPDATE
 
 var a: (i32, i32) = (12, 6);
-// CHECK:STDERR: fail_tuple_out_of_bound_access.carbon:[[@LINE+3]]:17: ERROR: Index `2` is past the end of `(i32, i32) as type`.
+// CHECK:STDERR: fail_tuple_out_of_bound_access.carbon:[[@LINE+3]]:17: ERROR: Index `2` is past the end of type `(i32, i32)`.
 // CHECK:STDERR: var b: i32 = a[2];
 // CHECK:STDERR:                 ^
 var b: i32 = a[2];

+ 2 - 2
toolchain/check/testdata/pointer/fail_deref_not_pointer.carbon

@@ -9,11 +9,11 @@ fn Deref(n: i32) {
   // CHECK:STDERR:   *n;
   // CHECK:STDERR:   ^
   *n;
-  // CHECK:STDERR: fail_deref_not_pointer.carbon:[[@LINE+3]]:3: ERROR: Cannot dereference operand of non-pointer type `() as type`.
+  // CHECK:STDERR: fail_deref_not_pointer.carbon:[[@LINE+3]]:3: ERROR: Cannot dereference operand of non-pointer type `()`.
   // CHECK:STDERR:   *();
   // CHECK:STDERR:   ^
   *();
-  // CHECK:STDERR: fail_deref_not_pointer.carbon:[[@LINE+3]]:3: ERROR: Cannot dereference operand of non-pointer type `{} as type`.
+  // CHECK:STDERR: fail_deref_not_pointer.carbon:[[@LINE+3]]:3: ERROR: Cannot dereference operand of non-pointer type `{}`.
   // CHECK:STDERR:   *{};
   // CHECK:STDERR:   ^
   *{};

+ 1 - 1
toolchain/check/testdata/tuples/fail_assign_to_empty.carbon

@@ -4,7 +4,7 @@
 //
 // AUTOUPDATE
 
-// CHECK:STDERR: fail_assign_to_empty.carbon:[[@LINE+3]]:17: ERROR: Cannot implicitly convert from `i32` to `() as type`.
+// CHECK:STDERR: fail_assign_to_empty.carbon:[[@LINE+3]]:17: ERROR: Cannot implicitly convert from `i32` to `()`.
 // CHECK:STDERR: var x: () = (66);
 // CHECK:STDERR:                 ^
 var x: () = (66);

+ 3 - 16
toolchain/sem_ir/file.cpp

@@ -237,13 +237,11 @@ static auto GetTypePrecedence(InstKind kind) -> int {
   }
 }
 
-auto File::StringifyType(TypeId type_id, bool in_type_context) const
-    -> std::string {
-  return StringifyTypeExpr(GetTypeAllowBuiltinTypes(type_id), in_type_context);
+auto File::StringifyType(TypeId type_id) const -> std::string {
+  return StringifyTypeExpr(GetTypeAllowBuiltinTypes(type_id));
 }
 
-auto File::StringifyTypeExpr(InstId outer_inst_id, bool in_type_context) const
-    -> std::string {
+auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {
   std::string str;
   llvm::raw_string_ostream out(str);
 
@@ -445,17 +443,6 @@ auto File::StringifyTypeExpr(InstId outer_inst_id, bool in_type_context) const
     }
   }
 
-  // For `{}` or any tuple type, we've printed a non-type expression, so add a
-  // conversion to type `type` if it's not implied by the context.
-  if (!in_type_context) {
-    auto outer_inst = insts().Get(outer_inst_id);
-    if (outer_inst.Is<TupleType>() ||
-        (outer_inst.Is<StructType>() &&
-         inst_blocks().Get(outer_inst.As<StructType>().fields_id).empty())) {
-      out << " as type";
-    }
-  }
-
   return str;
 }
 

+ 3 - 8
toolchain/sem_ir/file.h

@@ -261,17 +261,12 @@ class File : public Printable<File> {
         .pointee_id;
   }
 
-  // Produces a string version of a type. If `in_type_context` is false, an
-  // explicit conversion to type `type` will be added in cases where the type
-  // expression would otherwise have a different type, such as a tuple or
-  // struct type.
-  auto StringifyType(TypeId type_id, bool in_type_context = false) const
-      -> std::string;
+  // Produces a string version of a type.
+  auto StringifyType(TypeId type_id) const -> std::string;
 
   // Same as `StringifyType`, but starting with an instruction representing a
   // type expression rather than a canonical type.
-  auto StringifyTypeExpr(InstId outer_inst_id,
-                         bool in_type_context = false) const -> std::string;
+  auto StringifyTypeExpr(InstId outer_inst_id) const -> std::string;
 
   // Directly expose SharedValueStores members.
   auto identifiers() -> StringStoreWrapper<IdentifierId>& {

+ 1 - 1
toolchain/sem_ir/formatter.cpp

@@ -966,7 +966,7 @@ class Formatter {
     if (!id.is_valid()) {
       out_ << "invalid";
     } else {
-      out_ << sem_ir_.StringifyType(id, /*in_type_context=*/true);
+      out_ << sem_ir_.StringifyType(id);
     }
   }