From 8eb4e24cb69eb6d2d71e8167ccdba37763869911 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 11 Feb 2025 13:33:57 -0800 Subject: [PATCH] Implement #4864: `Core` is a keyword (#4909) Change representation of package names from `IdentifierId` to `PackageNameId`, and add a special value `PackageNameId::Core` for the Core package. Add a `Core` expression to name the Core package, and support for parsing the `Core` keyword in `package` and `import` declarations. For now, I've made no changes to instruction fingerprinting or name mangling. This means that fingerprints and mangled names will collide between names in the `Core` package and names in a `r#Core` package. See #4908. --------- Co-authored-by: Jon Ross-Perkins --- toolchain/base/value_ids.h | 38 ++ toolchain/check/check.cpp | 29 +- toolchain/check/check_unit.cpp | 28 +- toolchain/check/check_unit.h | 6 +- toolchain/check/context.cpp | 5 +- toolchain/check/handle_import_and_package.cpp | 7 +- toolchain/check/handle_name.cpp | 8 + toolchain/check/import.cpp | 4 +- toolchain/check/import.h | 2 +- toolchain/check/node_stack.h | 3 +- .../overloaded/no_prelude/index.carbon | 394 ++++++++++++------ .../no_prelude/core_name_poisoning.carbon | 10 +- .../no_prelude/missing_prelude.carbon | 213 ++-------- .../check/testdata/packages/raw_core.carbon | 275 ++++++++++++ toolchain/lex/token_kind.def | 1 + toolchain/lex/token_kind_test.cpp | 2 +- toolchain/lower/mangler.cpp | 12 +- toolchain/parse/handle_expr.cpp | 5 + toolchain/parse/handle_import_and_package.cpp | 43 +- toolchain/parse/node_ids.h | 1 + toolchain/parse/node_kind.def | 4 +- toolchain/parse/node_kind.h | 3 +- .../parse/testdata/package_expr/core.carbon | 29 ++ .../parse/testdata/packages/export.carbon | 24 +- .../packages/import/after_import.carbon | 4 +- .../packages/import/after_package.carbon | 4 +- .../testdata/packages/import/basic.carbon | 2 +- .../testdata/packages/import/core.carbon | 27 ++ .../testdata/packages/import/export.carbon | 12 +- .../packages/import/fail_extra_string.carbon | 2 +- .../import/fail_library_is_identifier.carbon | 2 +- .../packages/import/fail_no_semi.carbon | 2 +- .../import/fail_omit_library_keyword.carbon | 2 +- .../testdata/packages/import/fail_type.carbon | 2 +- .../testdata/packages/import/library.carbon | 2 +- .../testdata/packages/import/ordering.carbon | 10 +- .../packages/import/semi_before.carbon | 2 +- .../packages/library/fail_too_late.carbon | 2 +- .../testdata/packages/package/api.carbon | 2 +- .../packages/package/api_library.carbon | 2 +- .../testdata/packages/package/core.carbon | 36 ++ .../packages/package/fail_after_import.carbon | 2 +- .../package/fail_after_package.carbon | 2 +- .../packages/package/fail_extra_string.carbon | 2 +- .../package/fail_library_is_identifier.carbon | 2 +- .../packages/package/fail_no_semi.carbon | 2 +- .../package/fail_omit_library_keyword.carbon | 2 +- .../package/fail_trailing_impl.carbon | 2 +- .../testdata/packages/package/impl.carbon | 6 +- .../packages/package/impl_library.carbon | 2 +- .../packages/package/modifiers.carbon | 2 +- toolchain/parse/tree.h | 3 +- toolchain/parse/typed_nodes.h | 14 +- toolchain/sem_ir/file.cpp | 2 +- toolchain/sem_ir/file.h | 4 +- toolchain/sem_ir/formatter.cpp | 7 +- toolchain/sem_ir/ids.cpp | 33 +- toolchain/sem_ir/ids.h | 39 +- toolchain/sem_ir/inst_fingerprinter.cpp | 10 + toolchain/sem_ir/inst_namer.cpp | 7 +- toolchain/sem_ir/name.cpp | 14 +- toolchain/sem_ir/name_scope.cpp | 4 +- 62 files changed, 935 insertions(+), 487 deletions(-) create mode 100644 toolchain/check/testdata/packages/raw_core.carbon create mode 100644 toolchain/parse/testdata/package_expr/core.carbon create mode 100644 toolchain/parse/testdata/packages/import/core.carbon create mode 100644 toolchain/parse/testdata/packages/package/core.carbon diff --git a/toolchain/base/value_ids.h b/toolchain/base/value_ids.h index 3ea5cad118aa..950d4a3d5cd6 100644 --- a/toolchain/base/value_ids.h +++ b/toolchain/base/value_ids.h @@ -5,6 +5,7 @@ #ifndef CARBON_TOOLCHAIN_BASE_VALUE_IDS_H_ #define CARBON_TOOLCHAIN_BASE_VALUE_IDS_H_ +#include "common/check.h" #include "common/ostream.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" @@ -71,6 +72,43 @@ struct IdentifierId : public IdBase { }; constexpr IdentifierId IdentifierId::None(IdentifierId::NoneIndex); +// The name of a package, which is either an identifier or the special `Core` +// package name. +// +// TODO: Consider also treating `Main` and `Cpp` as special package names. +struct PackageNameId : public IdBase { + static constexpr llvm::StringLiteral Label = "package"; + static const PackageNameId None; + static const PackageNameId Core; + + // Returns the PackageNameId corresponding to a particular IdentifierId. + static auto ForIdentifier(IdentifierId id) -> PackageNameId { + return PackageNameId(id.index); + } + + using IdBase::IdBase; + + // Returns the IdentifierId corresponding to this PackageNameId, or `None` if + // this is a special package name. + auto AsIdentifierId() const -> IdentifierId { + return index >= 0 ? IdentifierId(index) : IdentifierId::None; + } + + // Returns the special package name corresponding to this PackageNameId. + // Requires that this name is not an identifier name. + auto AsSpecialName() const -> llvm::StringLiteral { + if (*this == None) { + return "Main"; + } + if (*this == Core) { + return "Core"; + } + CARBON_FATAL("Unknown special package name kind {0}", *this); + } +}; +constexpr PackageNameId PackageNameId::None(PackageNameId::NoneIndex); +constexpr PackageNameId PackageNameId::Core(PackageNameId::NoneIndex - 1); + // Corresponds to StringRefs for string literals. struct StringLiteralValueId : public IdBase { static constexpr llvm::StringLiteral Label = "string"; diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index 4501c3821b3e..39837f151992 100644 --- a/toolchain/check/check.cpp +++ b/toolchain/check/check.cpp @@ -27,13 +27,18 @@ using ImportKey = std::pair; // imports, not the main package declaration; as a consequence, it will be // `None` for the main package declaration. static auto GetImportKey(UnitAndImports& unit_info, - IdentifierId file_package_id, + PackageNameId file_package_id, Parse::Tree::PackagingNames names) -> ImportKey { auto* stores = unit_info.unit->value_stores; - llvm::StringRef package_name = - names.package_id.has_value() ? stores->identifiers().Get(names.package_id) - : file_package_id.has_value() ? stores->identifiers().Get(file_package_id) - : ""; + PackageNameId package_id = + names.package_id.has_value() ? names.package_id : file_package_id; + llvm::StringRef package_name; + if (package_id.has_value()) { + auto package_ident_id = package_id.AsIdentifierId(); + package_name = package_ident_id.has_value() + ? stores->identifiers().Get(package_ident_id) + : package_id.AsSpecialName(); + } llvm::StringRef library_name = names.library_id.has_value() ? stores->string_literal_values().Get(names.library_id) @@ -65,8 +70,8 @@ static auto TrackImport(Map& api_map, -> void { const auto& packaging = unit_info.parse_tree().packaging_decl(); - IdentifierId file_package_id = - packaging ? packaging->names.package_id : IdentifierId::None; + PackageNameId file_package_id = + packaging ? packaging->names.package_id : PackageNameId::None; const auto import_key = GetImportKey(unit_info, file_package_id, import); const auto& [import_package_name, import_library_name] = import_key; @@ -232,7 +237,7 @@ static auto BuildApiMapAndDiagnosePackaging( const auto& packaging = unit_info.parse_tree().packaging_decl(); // An import key formed from the `package` or `library` declaration. Or, for // Main//default, a placeholder key. - auto import_key = packaging ? GetImportKey(unit_info, IdentifierId::None, + auto import_key = packaging ? GetImportKey(unit_info, PackageNameId::None, packaging->names) // Construct a boring key for Main//default. : ImportKey{"", ""}; @@ -339,7 +344,7 @@ auto CheckParseTrees(llvm::MutableArrayRef units, bool prelude_import, if (packaging && packaging->is_impl) { // An `impl` has an implicit import of its `api`. auto implicit_names = packaging->names; - implicit_names.package_id = IdentifierId::None; + implicit_names.package_id = PackageNameId::None; TrackImport(api_map, nullptr, unit_info, implicit_names, fuzzing); } @@ -347,15 +352,13 @@ auto CheckParseTrees(llvm::MutableArrayRef units, bool prelude_import, // Add the prelude import. It's added to explicit_import_map so that it can // conflict with an explicit import of the prelude. - IdentifierId core_ident_id = - unit_info.unit->value_stores->identifiers().Add("Core"); if (prelude_import && - !(packaging && packaging->names.package_id == core_ident_id)) { + !(packaging && packaging->names.package_id == PackageNameId::Core)) { auto prelude_id = unit_info.unit->value_stores->string_literal_values().Add("prelude"); TrackImport(api_map, &explicit_import_map, unit_info, {.node_id = Parse::NoneNodeId(), - .package_id = core_ident_id, + .package_id = PackageNameId::Core, .library_id = prelude_id}, fuzzing); } diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index 8db88ac81bff..ac9bb4b0f4dc 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -113,7 +113,7 @@ auto CheckUnit::InitPackageScopeAndImports() -> void { const auto& names = context_.parse_tree().packaging_decl()->names; auto import_decl_id = context_.AddInst( names.node_id, - {.package_id = SemIR::NameId::ForIdentifier(names.package_id)}); + {.package_id = SemIR::NameId::ForPackageName(names.package_id)}); SetApiImportIR(context_, {.decl_id = import_decl_id, .is_export = false, @@ -128,7 +128,7 @@ auto CheckUnit::InitPackageScopeAndImports() -> void { for (auto& package_imports : unit_and_imports_->package_imports) { CARBON_CHECK(!package_imports.import_decl_id.has_value()); package_imports.import_decl_id = context_.AddInst( - package_imports.node_id, {.package_id = SemIR::NameId::ForIdentifier( + package_imports.node_id, {.package_id = SemIR::NameId::ForPackageName( package_imports.package_id)}); } @@ -223,7 +223,7 @@ auto CheckUnit::ImportCurrentPackage(SemIR::InstId package_inst_id, SemIR::TypeId namespace_type_id) -> void { // Add imports from the current package. auto import_map_lookup = - unit_and_imports_->package_imports_map.Lookup(IdentifierId::None); + unit_and_imports_->package_imports_map.Lookup(PackageNameId::None); if (!import_map_lookup) { // Push the scope; there are no names to add. context_.scope_stack().Push(package_inst_id, SemIR::NameScopeId::Package); @@ -252,12 +252,12 @@ auto CheckUnit::ImportOtherPackages(SemIR::TypeId namespace_type_id) -> void { // when processing an implementation file, in order to combine the API file // imports. // - // For packages imported by the API file, the IdentifierId is the package name - // and the index is into the API's import list. Otherwise, the initial + // For packages imported by the API file, the PackageNameId is the package + // name and the index is into the API's import list. Otherwise, the initial // {None, -1} state remains. - llvm::SmallVector> api_imports_list; + llvm::SmallVector> api_imports_list; api_imports_list.resize(unit_and_imports_->package_imports.size(), - {IdentifierId::None, -1}); + {PackageNameId::None, -1}); // When there's an API file, add the mapping to api_imports_list. if (unit_and_imports_->api_for_impl) { @@ -272,9 +272,15 @@ auto CheckUnit::ImportOtherPackages(SemIR::TypeId namespace_type_id) -> void { if (!api_imports.package_id.has_value()) { continue; } + // Translate the package ID from the API file to the implementation file. - auto impl_package_id = - impl_identifiers.Add(api_identifiers.Get(api_imports.package_id)); + auto impl_package_id = api_imports.package_id; + if (auto package_identifier_id = impl_package_id.AsIdentifierId(); + package_identifier_id.has_value()) { + impl_package_id = PackageNameId::ForIdentifier( + impl_identifiers.Add(api_identifiers.Get(package_identifier_id))); + } + if (auto lookup = unit_and_imports_->package_imports_map.Lookup(impl_package_id)) { // On a hit, replace the entry to unify the API and implementation @@ -290,7 +296,7 @@ auto CheckUnit::ImportOtherPackages(SemIR::TypeId namespace_type_id) -> void { for (auto [i, api_imports_entry] : llvm::enumerate(api_imports_list)) { // These variables are updated after figuring out which imports are present. auto import_decl_id = SemIR::InstId::None; - IdentifierId package_id = IdentifierId::None; + PackageNameId package_id = PackageNameId::None; bool has_load_error = false; // Identify the local package imports if present. @@ -321,7 +327,7 @@ auto CheckUnit::ImportOtherPackages(SemIR::TypeId namespace_type_id) -> void { .inst_id = api_imports->import_decl_id}); import_decl_id = context_.AddInst(context_.MakeImportedLocAndInst( - import_ir_inst_id, {.package_id = SemIR::NameId::ForIdentifier( + import_ir_inst_id, {.package_id = SemIR::NameId::ForPackageName( api_imports_entry.first)})); package_id = api_imports_entry.first; } diff --git a/toolchain/check/check_unit.h b/toolchain/check/check_unit.h index 52d456cd678e..05128c6a6c72 100644 --- a/toolchain/check/check_unit.h +++ b/toolchain/check/check_unit.h @@ -27,11 +27,11 @@ struct PackageImports { // Use the constructor so that the SmallVector is only constructed // as-needed. - explicit PackageImports(IdentifierId package_id, Parse::ImportDeclId node_id) + explicit PackageImports(PackageNameId package_id, Parse::ImportDeclId node_id) : package_id(package_id), node_id(node_id) {} // The identifier of the imported package. - IdentifierId package_id; + PackageNameId package_id; // The first `import` declaration in the file, which declared the package's // identifier (even if the import failed). Used for associating diagnostics // not specific to a single import. @@ -91,7 +91,7 @@ struct UnitAndImports { llvm::SmallVector package_imports; // A map of the package names to the outgoing imports above. - Map package_imports_map; + Map package_imports_map; // List of the `import Cpp` imports. llvm::SmallVector cpp_imports; diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index b38695c1b0e1..1780006b7e73 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -695,12 +695,11 @@ auto Context::LookupQualifiedName(SemIR::LocId loc_id, SemIR::NameId name_id, // name lookup to find it. static auto GetCorePackage(Context& context, SemIR::LocId loc_id, llvm::StringRef name) -> SemIR::NameScopeId { - auto core_ident_id = context.identifiers().Add("Core"); auto packaging = context.parse_tree().packaging_decl(); - if (packaging && packaging->names.package_id == core_ident_id) { + if (packaging && packaging->names.package_id == PackageNameId::Core) { return SemIR::NameScopeId::Package; } - auto core_name_id = SemIR::NameId::ForIdentifier(core_ident_id); + auto core_name_id = SemIR::NameId::Core; // Look up `package.Core`. auto core_scope_result = context.LookupNameInExactScope( diff --git a/toolchain/check/handle_import_and_package.cpp b/toolchain/check/handle_import_and_package.cpp index e52dc8900e34..98f55918c2d1 100644 --- a/toolchain/check/handle_import_and_package.cpp +++ b/toolchain/check/handle_import_and_package.cpp @@ -63,7 +63,12 @@ auto HandleParseNode(Context& context, Parse::LibrarySpecifierId /*node_id*/) return true; } -auto HandleParseNode(Context& /*context*/, Parse::PackageNameId /*node_id*/) +auto HandleParseNode(Context& /*context*/, + Parse::IdentifierPackageNameId /*node_id*/) -> bool { + return true; +} + +auto HandleParseNode(Context& /*context*/, Parse::CorePackageNameId /*node_id*/) -> bool { return true; } diff --git a/toolchain/check/handle_name.cpp b/toolchain/check/handle_name.cpp index 7b524bbe38e4..19eecd161b7e 100644 --- a/toolchain/check/handle_name.cpp +++ b/toolchain/check/handle_name.cpp @@ -244,4 +244,12 @@ auto HandleParseNode(Context& context, Parse::PackageExprId node_id) -> bool { return true; } +auto HandleParseNode(Context& context, Parse::CoreNameExprId node_id) -> bool { + // TODO: Unqualified lookup will never find anything; perform lookup directly + // into file scope. + context.node_stack().Push( + node_id, HandleNameAsExpr(context, node_id, SemIR::NameId::Core)); + return true; +} + } // namespace Carbon::Check diff --git a/toolchain/check/import.cpp b/toolchain/check/import.cpp index 314a4c49d6f8..e301531c45e0 100644 --- a/toolchain/check/import.cpp +++ b/toolchain/check/import.cpp @@ -450,13 +450,13 @@ auto ImportLibrariesFromCurrentPackage( auto ImportLibrariesFromOtherPackage(Context& context, SemIR::TypeId namespace_type_id, SemIR::InstId import_decl_id, - IdentifierId package_id, + PackageNameId package_id, llvm::ArrayRef import_irs, bool has_load_error) -> void { CARBON_CHECK(has_load_error || !import_irs.empty(), "There should be either a load error or at least one IR."); - auto name_id = SemIR::NameId::ForIdentifier(package_id); + auto name_id = SemIR::NameId::ForPackageName(package_id); NamespaceResult result = AddNamespace( context, namespace_type_id, name_id, SemIR::NameScopeId::Package, diff --git a/toolchain/check/import.h b/toolchain/check/import.h index 3c65c5f84f69..28cadb76f202 100644 --- a/toolchain/check/import.h +++ b/toolchain/check/import.h @@ -34,7 +34,7 @@ auto ImportLibrariesFromCurrentPackage( auto ImportLibrariesFromOtherPackage(Context& context, SemIR::TypeId namespace_type_id, SemIR::InstId import_decl_id, - IdentifierId package_id, + PackageNameId package_id, llvm::ArrayRef import_irs, bool has_load_error) -> void; diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index 94e138bce3e4..e1926cd36f46 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -463,12 +463,14 @@ class NodeStack { case Parse::NodeKind::ChoiceIntroducer: case Parse::NodeKind::CodeBlock: case Parse::NodeKind::ContinueStatementStart: + case Parse::NodeKind::CorePackageName: case Parse::NodeKind::ExportIntroducer: case Parse::NodeKind::FileEnd: case Parse::NodeKind::FileStart: case Parse::NodeKind::ForHeader: case Parse::NodeKind::ForHeaderStart: case Parse::NodeKind::ForIn: + case Parse::NodeKind::IdentifierPackageName: case Parse::NodeKind::IfConditionStart: case Parse::NodeKind::ImportIntroducer: case Parse::NodeKind::IndexExprStart: @@ -496,7 +498,6 @@ class NodeStack { case Parse::NodeKind::NameQualifierWithoutParams: case Parse::NodeKind::NamespaceStart: case Parse::NodeKind::PackageIntroducer: - case Parse::NodeKind::PackageName: case Parse::NodeKind::ParenExprStart: case Parse::NodeKind::PatternListComma: case Parse::NodeKind::Placeholder: diff --git a/toolchain/check/testdata/operators/overloaded/no_prelude/index.carbon b/toolchain/check/testdata/operators/overloaded/no_prelude/index.carbon index 338d6fb11a97..23cf06aab78e 100644 --- a/toolchain/check/testdata/operators/overloaded/no_prelude/index.carbon +++ b/toolchain/check/testdata/operators/overloaded/no_prelude/index.carbon @@ -8,12 +8,18 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/operators/overloaded/no_prelude/index.carbon +// --- core_wrong_index_with.carbon + +package Core library "[[@TEST_NAME]]"; + +class IndexWith {} + // --- fail_wrong_index_with.carbon library "[[@TEST_NAME]]"; -namespace Core; -class Core.IndexWith {} +import Core library "core_wrong_index_with"; + // CHECK:STDERR: fail_wrong_index_with.carbon:[[@LINE+4]]:10: error: type `Core.IntLiteral` does not support indexing [TypeNotIndexable] // CHECK:STDERR: fn F() { 0[1]; } // CHECK:STDERR: ^~~~ @@ -34,14 +40,19 @@ library "[[@TEST_NAME]]"; // CHECK:STDERR: fn F() { 0[1]; } +// --- core_wrong_arg_count.carbon + +package Core library "[[@TEST_NAME]]"; + +interface IndexWith(SubscriptType:! type) { + fn At[self: Self](subscript: SubscriptType) -> (); +} + // --- wrong_arg_count.carbon library "[[@TEST_NAME]]"; -namespace Core; -interface Core.IndexWith(SubscriptType:! type) { - fn At[self: Self](subscript: SubscriptType) -> (); -} +import Core library "core_wrong_arg_count"; impl () as Core.IndexWith(()) { fn At[self: Self](subscript: ()) -> () { @@ -51,28 +62,19 @@ impl () as Core.IndexWith(()) { fn F() { ()[()]; } -// CHECK:STDOUT: --- fail_wrong_index_with.carbon +// CHECK:STDOUT: --- core_wrong_index_with.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %IndexWith: type = class_type @IndexWith [template] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [template] -// CHECK:STDOUT: %F.type: type = fn_type @F [template] -// CHECK:STDOUT: %F: %F.type = struct_value () [template] -// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [template] -// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .Core = %Core -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core: = namespace [template] { // CHECK:STDOUT: .IndexWith = %IndexWith.decl // CHECK:STDOUT: } // CHECK:STDOUT: %IndexWith.decl: type = class_decl @IndexWith [template = constants.%IndexWith] {} {} -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @IndexWith { @@ -83,6 +85,42 @@ fn F() { ()[()]; } // CHECK:STDOUT: .Self = constants.%IndexWith // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- fail_wrong_index_with.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [template] +// CHECK:STDOUT: %F: %F.type = struct_value () [template] +// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [template] +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [template] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .IndexWith = %Core.IndexWith +// CHECK:STDOUT: import Core//core_wrong_index_with +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import_ref.8f2: = import_ref Core//core_wrong_index_with, loc4_18, loaded [template = constants.%complete_type] +// CHECK:STDOUT: %Core.import_ref.4c7 = import_ref Core//core_wrong_index_with, inst14 [no loc], unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @IndexWith [from "core_wrong_index_with.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Core.import_ref.8f2 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Core.import_ref.4c7 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [template = constants.%int_0] @@ -113,114 +151,196 @@ fn F() { ()[()]; } // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- wrong_arg_count.carbon +// CHECK:STDOUT: --- core_wrong_arg_count.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %SubscriptType: type = bind_symbolic_name SubscriptType, 0 [symbolic] // CHECK:STDOUT: %SubscriptType.patt: type = symbolic_binding_pattern SubscriptType, 0 [symbolic] -// CHECK:STDOUT: %IndexWith.type.232: type = generic_interface_type @IndexWith [template] +// CHECK:STDOUT: %IndexWith.type.68b: type = generic_interface_type @IndexWith [template] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template] -// CHECK:STDOUT: %IndexWith.generic: %IndexWith.type.232 = struct_value () [template] -// CHECK:STDOUT: %IndexWith.type.518: type = facet_type <@IndexWith, @IndexWith(%SubscriptType)> [symbolic] -// CHECK:STDOUT: %Self: %IndexWith.type.518 = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %IndexWith.generic: %IndexWith.type.68b = struct_value () [template] +// CHECK:STDOUT: %IndexWith.type.b94: type = facet_type <@IndexWith, @IndexWith(%SubscriptType)> [symbolic] +// CHECK:STDOUT: %Self: %IndexWith.type.b94 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] -// CHECK:STDOUT: %At.type.b28: type = fn_type @At.1, @IndexWith(%SubscriptType) [symbolic] -// CHECK:STDOUT: %At.921: %At.type.b28 = struct_value () [symbolic] -// CHECK:STDOUT: %IndexWith.assoc_type.c82: type = assoc_entity_type %IndexWith.type.518 [symbolic] -// CHECK:STDOUT: %assoc0.d63: %IndexWith.assoc_type.c82 = assoc_entity element0, @IndexWith.%At.decl [symbolic] -// CHECK:STDOUT: %IndexWith.type.4ab: type = facet_type <@IndexWith, @IndexWith(%empty_tuple.type)> [template] -// CHECK:STDOUT: %At.type.082: type = fn_type @At.1, @IndexWith(%empty_tuple.type) [template] -// CHECK:STDOUT: %At.d80: %At.type.082 = struct_value () [template] -// CHECK:STDOUT: %IndexWith.assoc_type.81e: type = assoc_entity_type %IndexWith.type.4ab [template] -// CHECK:STDOUT: %assoc0.5bc: %IndexWith.assoc_type.81e = assoc_entity element0, @IndexWith.%At.decl [template] -// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%At.decl) [template] -// CHECK:STDOUT: %At.type.8fc: type = fn_type @At.2 [template] -// CHECK:STDOUT: %At.8ba: %At.type.8fc = struct_value () [template] -// CHECK:STDOUT: %IndexWith.facet: %IndexWith.type.4ab = facet_value %empty_tuple.type, %impl_witness [template] -// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [template] -// CHECK:STDOUT: %F.type: type = fn_type @F [template] -// CHECK:STDOUT: %F: %F.type = struct_value () [template] -// CHECK:STDOUT: %.b91: type = fn_type_with_self_type %At.type.082, %IndexWith.facet [template] -// CHECK:STDOUT: %At.bound: = bound_method %empty_tuple, %At.8ba [template] +// CHECK:STDOUT: %At.type: type = fn_type @At, @IndexWith(%SubscriptType) [symbolic] +// CHECK:STDOUT: %At: %At.type = struct_value () [symbolic] +// CHECK:STDOUT: %IndexWith.assoc_type: type = assoc_entity_type %IndexWith.type.b94 [symbolic] +// CHECK:STDOUT: %assoc0: %IndexWith.assoc_type = assoc_entity element0, @IndexWith.%At.decl [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .Core = %Core -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core: = namespace [template] { // CHECK:STDOUT: .IndexWith = %IndexWith.decl // CHECK:STDOUT: } -// CHECK:STDOUT: %IndexWith.decl: %IndexWith.type.232 = interface_decl @IndexWith [template = constants.%IndexWith.generic] { -// CHECK:STDOUT: %SubscriptType.patt.loc5_26.1: type = symbolic_binding_pattern SubscriptType, 0 [symbolic = %SubscriptType.patt.loc5_26.2 (constants.%SubscriptType.patt)] -// CHECK:STDOUT: %SubscriptType.param_patt: type = value_param_pattern %SubscriptType.patt.loc5_26.1, runtime_param [symbolic = %SubscriptType.patt.loc5_26.2 (constants.%SubscriptType.patt)] +// CHECK:STDOUT: %IndexWith.decl: %IndexWith.type.68b = interface_decl @IndexWith [template = constants.%IndexWith.generic] { +// CHECK:STDOUT: %SubscriptType.patt.loc4_21.1: type = symbolic_binding_pattern SubscriptType, 0 [symbolic = %SubscriptType.patt.loc4_21.2 (constants.%SubscriptType.patt)] +// CHECK:STDOUT: %SubscriptType.param_patt: type = value_param_pattern %SubscriptType.patt.loc4_21.1, runtime_param [symbolic = %SubscriptType.patt.loc4_21.2 (constants.%SubscriptType.patt)] // CHECK:STDOUT: } { // CHECK:STDOUT: %SubscriptType.param: type = value_param runtime_param -// CHECK:STDOUT: %SubscriptType.loc5_26.1: type = bind_symbolic_name SubscriptType, 0, %SubscriptType.param [symbolic = %SubscriptType.loc5_26.2 (constants.%SubscriptType)] +// CHECK:STDOUT: %SubscriptType.loc4_21.1: type = bind_symbolic_name SubscriptType, 0, %SubscriptType.param [symbolic = %SubscriptType.loc4_21.2 (constants.%SubscriptType)] // CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @IndexWith(%SubscriptType.loc4_21.1: type) { +// CHECK:STDOUT: %SubscriptType.loc4_21.2: type = bind_symbolic_name SubscriptType, 0 [symbolic = %SubscriptType.loc4_21.2 (constants.%SubscriptType)] +// CHECK:STDOUT: %SubscriptType.patt.loc4_21.2: type = symbolic_binding_pattern SubscriptType, 0 [symbolic = %SubscriptType.patt.loc4_21.2 (constants.%SubscriptType.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(%SubscriptType.loc4_21.2)> [symbolic = %IndexWith.type (constants.%IndexWith.type.b94)] +// CHECK:STDOUT: %Self.2: %IndexWith.type.b94 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)] +// CHECK:STDOUT: %At.type: type = fn_type @At, @IndexWith(%SubscriptType.loc4_21.2) [symbolic = %At.type (constants.%At.type)] +// CHECK:STDOUT: %At: @IndexWith.%At.type (%At.type) = struct_value () [symbolic = %At (constants.%At)] +// CHECK:STDOUT: %IndexWith.assoc_type: type = assoc_entity_type @IndexWith.%IndexWith.type (%IndexWith.type.b94) [symbolic = %IndexWith.assoc_type (constants.%IndexWith.assoc_type)] +// CHECK:STDOUT: %assoc0.loc5_52.2: @IndexWith.%IndexWith.assoc_type (%IndexWith.assoc_type) = assoc_entity element0, %At.decl [symbolic = %assoc0.loc5_52.2 (constants.%assoc0)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.1: @IndexWith.%IndexWith.type (%IndexWith.type.b94) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)] +// CHECK:STDOUT: %At.decl: @IndexWith.%At.type (%At.type) = fn_decl @At [symbolic = @IndexWith.%At (constants.%At)] { +// CHECK:STDOUT: %self.patt: @At.%Self.as_type.loc5_15.1 (%Self.as_type) = binding_pattern self +// CHECK:STDOUT: %self.param_patt: @At.%Self.as_type.loc5_15.1 (%Self.as_type) = value_param_pattern %self.patt, runtime_param0 +// CHECK:STDOUT: %subscript.patt: @At.%SubscriptType (%SubscriptType) = binding_pattern subscript +// CHECK:STDOUT: %subscript.param_patt: @At.%SubscriptType (%SubscriptType) = value_param_pattern %subscript.patt, runtime_param1 +// CHECK:STDOUT: %return.patt: %empty_tuple.type = return_slot_pattern +// CHECK:STDOUT: %return.param_patt: %empty_tuple.type = out_param_pattern %return.patt, runtime_param2 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc5_51.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc5_51.2: type = converted %.loc5_51.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %self.param: @At.%Self.as_type.loc5_15.1 (%Self.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc5_15.1: type = splice_block %.loc5_15.3 [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %.loc5_15.2: @At.%IndexWith.type (%IndexWith.type.b94) = specific_constant @IndexWith.%Self.1, @IndexWith(constants.%SubscriptType) [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.ref: @At.%IndexWith.type (%IndexWith.type.b94) = name_ref Self, %.loc5_15.2 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type.loc5_15.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %.loc5_15.3: type = converted %Self.ref, %Self.as_type.loc5_15.2 [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @At.%Self.as_type.loc5_15.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %subscript.param: @At.%SubscriptType (%SubscriptType) = value_param runtime_param1 +// CHECK:STDOUT: %SubscriptType.ref: type = name_ref SubscriptType, @IndexWith.%SubscriptType.loc4_21.1 [symbolic = %SubscriptType (constants.%SubscriptType)] +// CHECK:STDOUT: %subscript: @At.%SubscriptType (%SubscriptType) = bind_name subscript, %subscript.param +// CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param runtime_param2 +// CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0.loc5_52.1: @IndexWith.%IndexWith.assoc_type (%IndexWith.assoc_type) = assoc_entity element0, %At.decl [symbolic = %assoc0.loc5_52.2 (constants.%assoc0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.1 +// CHECK:STDOUT: .At = %assoc0.loc5_52.1 +// CHECK:STDOUT: witness = (%At.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @At(@IndexWith.%SubscriptType.loc4_21.1: type, @IndexWith.%Self.1: @IndexWith.%IndexWith.type (%IndexWith.type.b94)) { +// CHECK:STDOUT: %SubscriptType: type = bind_symbolic_name SubscriptType, 0 [symbolic = %SubscriptType (constants.%SubscriptType)] +// CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(%SubscriptType)> [symbolic = %IndexWith.type (constants.%IndexWith.type.b94)] +// CHECK:STDOUT: %Self: %IndexWith.type.b94 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type.loc5_15.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%self.param_patt: @At.%Self.as_type.loc5_15.1 (%Self.as_type)](%subscript.param_patt: @At.%SubscriptType (%SubscriptType)) -> %empty_tuple.type; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @IndexWith(constants.%SubscriptType) { +// CHECK:STDOUT: %SubscriptType.loc4_21.2 => constants.%SubscriptType +// CHECK:STDOUT: %SubscriptType.patt.loc4_21.2 => constants.%SubscriptType +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @At(constants.%SubscriptType, constants.%Self) { +// CHECK:STDOUT: %SubscriptType => constants.%SubscriptType +// CHECK:STDOUT: %IndexWith.type => constants.%IndexWith.type.b94 +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.as_type.loc5_15.1 => constants.%Self.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @IndexWith(@At.%SubscriptType) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @IndexWith(%SubscriptType.loc4_21.2) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- wrong_arg_count.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template] +// CHECK:STDOUT: %IndexWith.type.504: type = generic_interface_type @IndexWith [template] +// CHECK:STDOUT: %IndexWith.generic: %IndexWith.type.504 = struct_value () [template] +// CHECK:STDOUT: %SubscriptType: type = bind_symbolic_name SubscriptType, 0 [symbolic] +// CHECK:STDOUT: %IndexWith.type.bd2: type = facet_type <@IndexWith, @IndexWith(%SubscriptType)> [symbolic] +// CHECK:STDOUT: %Self: %IndexWith.type.bd2 = bind_symbolic_name Self, 1 [symbolic] +// CHECK:STDOUT: %SubscriptType.patt: type = symbolic_binding_pattern SubscriptType, 0 [symbolic] +// CHECK:STDOUT: %At.type.cf4: type = fn_type @At.1, @IndexWith(%SubscriptType) [symbolic] +// CHECK:STDOUT: %At.281: %At.type.cf4 = struct_value () [symbolic] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] +// CHECK:STDOUT: %IndexWith.assoc_type.349: type = assoc_entity_type %IndexWith.type.bd2 [symbolic] +// CHECK:STDOUT: %assoc0.8c6: %IndexWith.assoc_type.349 = assoc_entity element0, imports.%Core.import_ref.e99 [symbolic] +// CHECK:STDOUT: %IndexWith.type.a51: type = facet_type <@IndexWith, @IndexWith(%empty_tuple.type)> [template] +// CHECK:STDOUT: %At.type.969: type = fn_type @At.1, @IndexWith(%empty_tuple.type) [template] +// CHECK:STDOUT: %At.9b9: %At.type.969 = struct_value () [template] +// CHECK:STDOUT: %IndexWith.assoc_type.614: type = assoc_entity_type %IndexWith.type.a51 [template] +// CHECK:STDOUT: %assoc0.64b: %IndexWith.assoc_type.614 = assoc_entity element0, imports.%Core.import_ref.e99 [template] +// CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%At.decl) [template] +// CHECK:STDOUT: %At.type.486: type = fn_type @At.2 [template] +// CHECK:STDOUT: %At.7c4: %At.type.486 = struct_value () [template] +// CHECK:STDOUT: %IndexWith.facet: %IndexWith.type.a51 = facet_value %empty_tuple.type, %impl_witness [template] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [template] +// CHECK:STDOUT: %F.type: type = fn_type @F [template] +// CHECK:STDOUT: %F: %F.type = struct_value () [template] +// CHECK:STDOUT: %assoc0.9bc: %IndexWith.assoc_type.349 = assoc_entity element0, imports.%Core.import_ref.981 [symbolic] +// CHECK:STDOUT: %.740: type = fn_type_with_self_type %At.type.969, %IndexWith.facet [template] +// CHECK:STDOUT: %At.bound: = bound_method %empty_tuple, %At.7c4 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .IndexWith = %Core.IndexWith +// CHECK:STDOUT: import Core//core_wrong_arg_count +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.IndexWith: %IndexWith.type.504 = import_ref Core//core_wrong_arg_count, IndexWith, loaded [template = constants.%IndexWith.generic] +// CHECK:STDOUT: %Core.import_ref.3b819a.1: type = import_ref Core//core_wrong_arg_count, loc4_21, loaded [symbolic = @IndexWith.%SubscriptType (constants.%SubscriptType)] +// CHECK:STDOUT: %Core.import_ref.68a = import_ref Core//core_wrong_arg_count, inst26 [no loc], unloaded +// CHECK:STDOUT: %Core.import_ref.25c: @IndexWith.%IndexWith.assoc_type (%IndexWith.assoc_type.349) = import_ref Core//core_wrong_arg_count, loc5_52, loaded [symbolic = @IndexWith.%assoc0 (constants.%assoc0.9bc)] +// CHECK:STDOUT: %Core.At: @IndexWith.%At.type (%At.type.cf4) = import_ref Core//core_wrong_arg_count, At, loaded [symbolic = @IndexWith.%At (constants.%At.281)] +// CHECK:STDOUT: %Core.import_ref.3b819a.2: type = import_ref Core//core_wrong_arg_count, loc4_21, loaded [symbolic = @IndexWith.%SubscriptType (constants.%SubscriptType)] +// CHECK:STDOUT: %Core.import_ref.fb5: @IndexWith.%IndexWith.type (%IndexWith.type.bd2) = import_ref Core//core_wrong_arg_count, inst26 [no loc], loaded [symbolic = @IndexWith.%Self (constants.%Self)] +// CHECK:STDOUT: %Core.import_ref.e99: @IndexWith.%At.type (%At.type.cf4) = import_ref Core//core_wrong_arg_count, loc5_52, loaded [symbolic = @IndexWith.%At (constants.%At.281)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %.loc9_7.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc9_7.2: type = converted %.loc9_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %Core.ref: = name_ref Core, file.%Core [template = file.%Core] -// CHECK:STDOUT: %IndexWith.ref: %IndexWith.type.232 = name_ref IndexWith, file.%IndexWith.decl [template = constants.%IndexWith.generic] -// CHECK:STDOUT: %.loc9_28: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc9_29: type = converted %.loc9_28, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(constants.%empty_tuple.type)> [template = constants.%IndexWith.type.4ab] +// CHECK:STDOUT: %.loc6_7.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc6_7.2: type = converted %.loc6_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [template = imports.%Core] +// CHECK:STDOUT: %IndexWith.ref: %IndexWith.type.504 = name_ref IndexWith, imports.%Core.IndexWith [template = constants.%IndexWith.generic] +// CHECK:STDOUT: %.loc6_28: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc6_29: type = converted %.loc6_28, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(constants.%empty_tuple.type)> [template = constants.%IndexWith.type.a51] // CHECK:STDOUT: } // CHECK:STDOUT: %impl_witness: = impl_witness (@impl.%At.decl) [template = constants.%impl_witness] // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic interface @IndexWith(%SubscriptType.loc5_26.1: type) { -// CHECK:STDOUT: %SubscriptType.loc5_26.2: type = bind_symbolic_name SubscriptType, 0 [symbolic = %SubscriptType.loc5_26.2 (constants.%SubscriptType)] -// CHECK:STDOUT: %SubscriptType.patt.loc5_26.2: type = symbolic_binding_pattern SubscriptType, 0 [symbolic = %SubscriptType.patt.loc5_26.2 (constants.%SubscriptType.patt)] +// CHECK:STDOUT: generic interface @IndexWith(imports.%Core.import_ref.3b819a.1: type) [from "core_wrong_arg_count.carbon"] { +// CHECK:STDOUT: %SubscriptType: type = bind_symbolic_name SubscriptType, 0 [symbolic = %SubscriptType (constants.%SubscriptType)] +// CHECK:STDOUT: %SubscriptType.patt: type = symbolic_binding_pattern SubscriptType, 0 [symbolic = %SubscriptType.patt (constants.%SubscriptType.patt)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(%SubscriptType.loc5_26.2)> [symbolic = %IndexWith.type (constants.%IndexWith.type.518)] -// CHECK:STDOUT: %Self.2: %IndexWith.type.518 = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)] -// CHECK:STDOUT: %At.type: type = fn_type @At.1, @IndexWith(%SubscriptType.loc5_26.2) [symbolic = %At.type (constants.%At.type.b28)] -// CHECK:STDOUT: %At: @IndexWith.%At.type (%At.type.b28) = struct_value () [symbolic = %At (constants.%At.921)] -// CHECK:STDOUT: %IndexWith.assoc_type: type = assoc_entity_type @IndexWith.%IndexWith.type (%IndexWith.type.518) [symbolic = %IndexWith.assoc_type (constants.%IndexWith.assoc_type.c82)] -// CHECK:STDOUT: %assoc0.loc6_52.2: @IndexWith.%IndexWith.assoc_type (%IndexWith.assoc_type.c82) = assoc_entity element0, %At.decl [symbolic = %assoc0.loc6_52.2 (constants.%assoc0.d63)] +// CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(%SubscriptType)> [symbolic = %IndexWith.type (constants.%IndexWith.type.bd2)] +// CHECK:STDOUT: %Self: %IndexWith.type.bd2 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %At.type: type = fn_type @At.1, @IndexWith(%SubscriptType) [symbolic = %At.type (constants.%At.type.cf4)] +// CHECK:STDOUT: %At: @IndexWith.%At.type (%At.type.cf4) = struct_value () [symbolic = %At (constants.%At.281)] +// CHECK:STDOUT: %IndexWith.assoc_type: type = assoc_entity_type @IndexWith.%IndexWith.type (%IndexWith.type.bd2) [symbolic = %IndexWith.assoc_type (constants.%IndexWith.assoc_type.349)] +// CHECK:STDOUT: %assoc0: @IndexWith.%IndexWith.assoc_type (%IndexWith.assoc_type.349) = assoc_entity element0, imports.%Core.import_ref.e99 [symbolic = %assoc0 (constants.%assoc0.8c6)] // CHECK:STDOUT: // CHECK:STDOUT: interface { -// CHECK:STDOUT: %Self.1: @IndexWith.%IndexWith.type (%IndexWith.type.518) = bind_symbolic_name Self, 1 [symbolic = %Self.2 (constants.%Self)] -// CHECK:STDOUT: %At.decl: @IndexWith.%At.type (%At.type.b28) = fn_decl @At.1 [symbolic = @IndexWith.%At (constants.%At.921)] { -// CHECK:STDOUT: %self.patt: @At.1.%Self.as_type.loc6_15.1 (%Self.as_type) = binding_pattern self -// CHECK:STDOUT: %self.param_patt: @At.1.%Self.as_type.loc6_15.1 (%Self.as_type) = value_param_pattern %self.patt, runtime_param0 -// CHECK:STDOUT: %subscript.patt: @At.1.%SubscriptType (%SubscriptType) = binding_pattern subscript -// CHECK:STDOUT: %subscript.param_patt: @At.1.%SubscriptType (%SubscriptType) = value_param_pattern %subscript.patt, runtime_param1 -// CHECK:STDOUT: %return.patt: %empty_tuple.type = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %empty_tuple.type = out_param_pattern %return.patt, runtime_param2 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %.loc6_51.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc6_51.2: type = converted %.loc6_51.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %self.param: @At.1.%Self.as_type.loc6_15.1 (%Self.as_type) = value_param runtime_param0 -// CHECK:STDOUT: %.loc6_15.1: type = splice_block %.loc6_15.3 [symbolic = %Self.as_type.loc6_15.1 (constants.%Self.as_type)] { -// CHECK:STDOUT: %.loc6_15.2: @At.1.%IndexWith.type (%IndexWith.type.518) = specific_constant @IndexWith.%Self.1, @IndexWith(constants.%SubscriptType) [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.ref: @At.1.%IndexWith.type (%IndexWith.type.518) = name_ref Self, %.loc6_15.2 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc6_15.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc6_15.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc6_15.3: type = converted %Self.ref, %Self.as_type.loc6_15.2 [symbolic = %Self.as_type.loc6_15.1 (constants.%Self.as_type)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self: @At.1.%Self.as_type.loc6_15.1 (%Self.as_type) = bind_name self, %self.param -// CHECK:STDOUT: %subscript.param: @At.1.%SubscriptType (%SubscriptType) = value_param runtime_param1 -// CHECK:STDOUT: %SubscriptType.ref: type = name_ref SubscriptType, @IndexWith.%SubscriptType.loc5_26.1 [symbolic = %SubscriptType (constants.%SubscriptType)] -// CHECK:STDOUT: %subscript: @At.1.%SubscriptType (%SubscriptType) = bind_name subscript, %subscript.param -// CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param runtime_param2 -// CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %assoc0.loc6_52.1: @IndexWith.%IndexWith.assoc_type (%IndexWith.assoc_type.c82) = assoc_entity element0, %At.decl [symbolic = %assoc0.loc6_52.2 (constants.%assoc0.d63)] -// CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self.1 -// CHECK:STDOUT: .At = %assoc0.loc6_52.1 -// CHECK:STDOUT: witness = (%At.decl) +// CHECK:STDOUT: .Self = imports.%Core.import_ref.68a +// CHECK:STDOUT: .At = imports.%Core.import_ref.25c +// CHECK:STDOUT: witness = (imports.%Core.At) // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %.loc9_7.2 as %IndexWith.type { -// CHECK:STDOUT: %At.decl: %At.type.8fc = fn_decl @At.2 [template = constants.%At.8ba] { +// CHECK:STDOUT: impl @impl: %.loc6_7.2 as %IndexWith.type { +// CHECK:STDOUT: %At.decl: %At.type.486 = fn_decl @At.2 [template = constants.%At.7c4] { // CHECK:STDOUT: %self.patt: %empty_tuple.type = binding_pattern self // CHECK:STDOUT: %self.param_patt: %empty_tuple.type = value_param_pattern %self.patt, runtime_param0 // CHECK:STDOUT: %subscript.patt: %empty_tuple.type = binding_pattern subscript @@ -228,15 +348,15 @@ fn F() { ()[()]; } // CHECK:STDOUT: %return.patt: %empty_tuple.type = return_slot_pattern // CHECK:STDOUT: %return.param_patt: %empty_tuple.type = out_param_pattern %return.patt, runtime_param2 // CHECK:STDOUT: } { -// CHECK:STDOUT: %.loc10_40.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc10_40.2: type = converted %.loc10_40.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc7_40.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc7_40.2: type = converted %.loc7_40.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] // CHECK:STDOUT: %self.param: %empty_tuple.type = value_param runtime_param0 -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.%.loc9_7.2 [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @impl.%.loc6_7.2 [template = constants.%empty_tuple.type] // CHECK:STDOUT: %self: %empty_tuple.type = bind_name self, %self.param // CHECK:STDOUT: %subscript.param: %empty_tuple.type = value_param runtime_param1 -// CHECK:STDOUT: %.loc10_33.1: type = splice_block %.loc10_33.3 [template = constants.%empty_tuple.type] { -// CHECK:STDOUT: %.loc10_33.2: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc10_33.3: type = converted %.loc10_33.2, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc7_33.1: type = splice_block %.loc7_33.3 [template = constants.%empty_tuple.type] { +// CHECK:STDOUT: %.loc7_33.2: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc7_33.3: type = converted %.loc7_33.2, constants.%empty_tuple.type [template = constants.%empty_tuple.type] // CHECK:STDOUT: } // CHECK:STDOUT: %subscript: %empty_tuple.type = bind_name subscript, %subscript.param // CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param runtime_param2 @@ -248,70 +368,70 @@ fn F() { ()[()]; } // CHECK:STDOUT: witness = file.%impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @At.1(@IndexWith.%SubscriptType.loc5_26.1: type, @IndexWith.%Self.1: @IndexWith.%IndexWith.type (%IndexWith.type.518)) { +// CHECK:STDOUT: generic fn @At.1(imports.%Core.import_ref.3b819a.2: type, imports.%Core.import_ref.fb5: @IndexWith.%IndexWith.type (%IndexWith.type.bd2)) [from "core_wrong_arg_count.carbon"] { // CHECK:STDOUT: %SubscriptType: type = bind_symbolic_name SubscriptType, 0 [symbolic = %SubscriptType (constants.%SubscriptType)] -// CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(%SubscriptType)> [symbolic = %IndexWith.type (constants.%IndexWith.type.518)] -// CHECK:STDOUT: %Self: %IndexWith.type.518 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc6_15.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc6_15.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %IndexWith.type: type = facet_type <@IndexWith, @IndexWith(%SubscriptType)> [symbolic = %IndexWith.type (constants.%IndexWith.type.bd2)] +// CHECK:STDOUT: %Self: %IndexWith.type.bd2 = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)] // CHECK:STDOUT: -// CHECK:STDOUT: fn[%self.param_patt: @At.1.%Self.as_type.loc6_15.1 (%Self.as_type)](%subscript.param_patt: @At.1.%SubscriptType (%SubscriptType)) -> %empty_tuple.type; +// CHECK:STDOUT: fn[%self.param_patt: @At.1.%Self.as_type (%Self.as_type)](%subscript.param_patt: @At.1.%SubscriptType (%SubscriptType)) -> %empty_tuple.type; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @At.2[%self.param_patt: %empty_tuple.type](%subscript.param_patt: %empty_tuple.type) -> %empty_tuple.type { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc11_13: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc8_13: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [template = constants.%empty_tuple] -// CHECK:STDOUT: %.loc11_14: %empty_tuple.type = converted %.loc11_13, %empty_tuple [template = constants.%empty_tuple] -// CHECK:STDOUT: return %.loc11_14 +// CHECK:STDOUT: %.loc8_14: %empty_tuple.type = converted %.loc8_13, %empty_tuple [template = constants.%empty_tuple] +// CHECK:STDOUT: return %.loc8_14 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc15_11.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc15_14: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %empty_tuple.loc15_11: %empty_tuple.type = tuple_value () [template = constants.%empty_tuple] -// CHECK:STDOUT: %.loc15_11.2: %empty_tuple.type = converted %.loc15_11.1, %empty_tuple.loc15_11 [template = constants.%empty_tuple] -// CHECK:STDOUT: %empty_tuple.loc15_14: %empty_tuple.type = tuple_value () [template = constants.%empty_tuple] -// CHECK:STDOUT: %.loc15_15: %empty_tuple.type = converted %.loc15_14, %empty_tuple.loc15_14 [template = constants.%empty_tuple] -// CHECK:STDOUT: %impl.elem0: %.b91 = impl_witness_access constants.%impl_witness, element0 [template = constants.%At.8ba] -// CHECK:STDOUT: %bound_method: = bound_method %.loc15_11.2, %impl.elem0 [template = constants.%At.bound] -// CHECK:STDOUT: %At.call: init %empty_tuple.type = call %bound_method(%.loc15_11.2, %.loc15_15) +// CHECK:STDOUT: %.loc12_11.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc12_14: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %empty_tuple.loc12_11: %empty_tuple.type = tuple_value () [template = constants.%empty_tuple] +// CHECK:STDOUT: %.loc12_11.2: %empty_tuple.type = converted %.loc12_11.1, %empty_tuple.loc12_11 [template = constants.%empty_tuple] +// CHECK:STDOUT: %empty_tuple.loc12_14: %empty_tuple.type = tuple_value () [template = constants.%empty_tuple] +// CHECK:STDOUT: %.loc12_15: %empty_tuple.type = converted %.loc12_14, %empty_tuple.loc12_14 [template = constants.%empty_tuple] +// CHECK:STDOUT: %impl.elem0: %.740 = impl_witness_access constants.%impl_witness, element0 [template = constants.%At.7c4] +// CHECK:STDOUT: %bound_method: = bound_method %.loc12_11.2, %impl.elem0 [template = constants.%At.bound] +// CHECK:STDOUT: %At.call: init %empty_tuple.type = call %bound_method(%.loc12_11.2, %.loc12_15) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @IndexWith(constants.%SubscriptType) { -// CHECK:STDOUT: %SubscriptType.loc5_26.2 => constants.%SubscriptType -// CHECK:STDOUT: %SubscriptType.patt.loc5_26.2 => constants.%SubscriptType +// CHECK:STDOUT: %SubscriptType => constants.%SubscriptType +// CHECK:STDOUT: %SubscriptType.patt => constants.%SubscriptType // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @At.1(constants.%SubscriptType, constants.%Self) { -// CHECK:STDOUT: %SubscriptType => constants.%SubscriptType -// CHECK:STDOUT: %IndexWith.type => constants.%IndexWith.type.518 -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Self.as_type.loc6_15.1 => constants.%Self.as_type -// CHECK:STDOUT: } +// CHECK:STDOUT: specific @IndexWith(%SubscriptType) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @IndexWith(@At.1.%SubscriptType) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @IndexWith(%SubscriptType.loc5_26.2) {} +// CHECK:STDOUT: specific @At.1(constants.%SubscriptType, constants.%Self) { +// CHECK:STDOUT: %SubscriptType => constants.%SubscriptType +// CHECK:STDOUT: %IndexWith.type => constants.%IndexWith.type.bd2 +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.as_type => constants.%Self.as_type +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @IndexWith(constants.%empty_tuple.type) { -// CHECK:STDOUT: %SubscriptType.loc5_26.2 => constants.%empty_tuple.type -// CHECK:STDOUT: %SubscriptType.patt.loc5_26.2 => constants.%empty_tuple.type +// CHECK:STDOUT: %SubscriptType => constants.%empty_tuple.type +// CHECK:STDOUT: %SubscriptType.patt => constants.%empty_tuple.type // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %IndexWith.type => constants.%IndexWith.type.4ab -// CHECK:STDOUT: %Self.2 => constants.%Self -// CHECK:STDOUT: %At.type => constants.%At.type.082 -// CHECK:STDOUT: %At => constants.%At.d80 -// CHECK:STDOUT: %IndexWith.assoc_type => constants.%IndexWith.assoc_type.81e -// CHECK:STDOUT: %assoc0.loc6_52.2 => constants.%assoc0.5bc +// CHECK:STDOUT: %IndexWith.type => constants.%IndexWith.type.a51 +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %At.type => constants.%At.type.969 +// CHECK:STDOUT: %At => constants.%At.9b9 +// CHECK:STDOUT: %IndexWith.assoc_type => constants.%IndexWith.assoc_type.614 +// CHECK:STDOUT: %assoc0 => constants.%assoc0.64b // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @At.1(constants.%empty_tuple.type, constants.%IndexWith.facet) { // CHECK:STDOUT: %SubscriptType => constants.%empty_tuple.type -// CHECK:STDOUT: %IndexWith.type => constants.%IndexWith.type.4ab +// CHECK:STDOUT: %IndexWith.type => constants.%IndexWith.type.a51 // CHECK:STDOUT: %Self => constants.%IndexWith.facet -// CHECK:STDOUT: %Self.as_type.loc6_15.1 => constants.%empty_tuple.type +// CHECK:STDOUT: %Self.as_type => constants.%empty_tuple.type // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon b/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon index c9e5dd74f3c7..435ee793fbcb 100644 --- a/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon +++ b/toolchain/check/testdata/packages/no_prelude/core_name_poisoning.carbon @@ -10,19 +10,12 @@ // --- fail_implicitly_poison_core.carbon -// CHECK:STDERR: fail_implicitly_poison_core.carbon:[[@LINE+7]]:9: error: `Core.Bool` implicitly referenced here, but package `Core` not found [CoreNotFound] +// CHECK:STDERR: fail_implicitly_poison_core.carbon:[[@LINE+4]]:9: error: `Core.Bool` implicitly referenced here, but package `Core` not found [CoreNotFound] // CHECK:STDERR: fn F(x: bool); // CHECK:STDERR: ^~~~ // CHECK:STDERR: -// CHECK:STDERR: fail_implicitly_poison_core.carbon:[[@LINE+3]]:9: error: name used before it was declared [NameUseBeforeDecl] -// CHECK:STDERR: fn F(x: bool); -// CHECK:STDERR: ^~~~ fn F(x: bool); -// CHECK:STDERR: fail_implicitly_poison_core.carbon:[[@LINE+4]]:1: note: declared here [NameUseBeforeDeclNote] -// CHECK:STDERR: class r#Core {} -// CHECK:STDERR: ^~~~~~~~~~~~~~ -// CHECK:STDERR: class r#Core {} // CHECK:STDOUT: --- fail_implicitly_poison_core.carbon @@ -38,6 +31,7 @@ class r#Core {} // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [template] { // CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: .r#Core = %Core.decl // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] { // CHECK:STDOUT: %x.patt: = binding_pattern x diff --git a/toolchain/check/testdata/packages/no_prelude/missing_prelude.carbon b/toolchain/check/testdata/packages/no_prelude/missing_prelude.carbon index a627aa5b1e5e..677ca88b3c40 100644 --- a/toolchain/check/testdata/packages/no_prelude/missing_prelude.carbon +++ b/toolchain/check/testdata/packages/no_prelude/missing_prelude.carbon @@ -60,13 +60,24 @@ fn Int[T:! type](N:! T) -> () { return (); } var n: () = i32; -// --- prelude_as_namespace.carbon +// --- fail_prelude_as_namespace.carbon library "[[@TEST_NAME]]"; -// TODO: Decide whether we want to accept this. +// CHECK:STDERR: fail_prelude_as_namespace.carbon:[[@LINE+8]]:11: error: `namespace` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: namespace Core; +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_prelude_as_namespace.carbon:[[@LINE+4]]:11: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] +// CHECK:STDERR: namespace Core; +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: namespace Core; +// CHECK:STDERR: fail_prelude_as_namespace.carbon:[[@LINE+4]]:4: error: `fn` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: fn Core.Int[T:! type](N:! T) -> {} { return {}; } +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: fn Core.Int[T:! type](N:! T) -> {} { return {}; } var n: {} = i32; @@ -75,15 +86,18 @@ var n: {} = i32; library "[[@TEST_NAME]]"; -// TODO: Decide whether we want to accept this. +// CHECK:STDERR: fail_prelude_as_class.carbon:[[@LINE+8]]:7: error: `class` introducer should be followed by a name [ExpectedDeclName] +// CHECK:STDERR: class Core { +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_prelude_as_class.carbon:[[@LINE+4]]:7: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] +// CHECK:STDERR: class Core { +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: class Core { fn Int[T:! type](N:! T) -> {} { return {}; } } -// CHECK:STDERR: fail_prelude_as_class.carbon:[[@LINE+4]]:13: error: `Core.Int` implicitly referenced here, but package `Core` not found [CoreNotFound] -// CHECK:STDERR: var n: {} = i32; -// CHECK:STDERR: ^~~ -// CHECK:STDERR: var n: {} = i32; // CHECK:STDOUT: --- fail_missing_prelude.carbon @@ -368,190 +382,11 @@ var n: {} = i32; // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- prelude_as_namespace.carbon +// CHECK:STDOUT: --- fail_prelude_as_namespace.carbon // CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] -// CHECK:STDOUT: %N: %T = bind_symbolic_name N, 1 [symbolic] -// CHECK:STDOUT: %N.patt: %T = symbolic_binding_pattern N, 1 [symbolic] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template] -// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] -// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [template] -// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template] -// CHECK:STDOUT: %Int.specific_fn: = specific_function %Int, @Int(Core.IntLiteral, %int_32) [template] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .Core = %Core -// CHECK:STDOUT: .n = %n -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core: = namespace [template] { -// CHECK:STDOUT: .Int = %Int.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Int.decl: %Int.type = fn_decl @Int [template = constants.%Int] { -// CHECK:STDOUT: %T.patt.loc7_13.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc7_13.2 (constants.%T.patt)] -// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc7_13.1, runtime_param [symbolic = %T.patt.loc7_13.2 (constants.%T.patt)] -// CHECK:STDOUT: %N.patt.loc7_23.1: @Int.%T.loc7_13.2 (%T) = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc7_23.2 (constants.%N.patt)] -// CHECK:STDOUT: %N.param_patt: @Int.%T.loc7_13.2 (%T) = value_param_pattern %N.patt.loc7_23.1, runtime_param [symbolic = %N.patt.loc7_23.2 (constants.%N.patt)] -// CHECK:STDOUT: %return.patt: %empty_struct_type = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %empty_struct_type = out_param_pattern %return.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %.loc7_34.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc7_34.2: type = converted %.loc7_34.1, constants.%empty_struct_type [template = constants.%empty_struct_type] -// CHECK:STDOUT: %T.param: type = value_param runtime_param -// CHECK:STDOUT: %T.loc7_13.1: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc7_13.2 (constants.%T)] -// CHECK:STDOUT: %N.param: @Int.%T.loc7_13.2 (%T) = value_param runtime_param -// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc7_13.1 [symbolic = %T.loc7_13.2 (constants.%T)] -// CHECK:STDOUT: %N.loc7_23.1: @Int.%T.loc7_13.2 (%T) = bind_symbolic_name N, 1, %N.param [symbolic = %N.loc7_23.2 (constants.%N)] -// CHECK:STDOUT: %return.param: ref %empty_struct_type = out_param runtime_param0 -// CHECK:STDOUT: %return: ref %empty_struct_type = return_slot %return.param -// CHECK:STDOUT: } -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %n.patt: %empty_struct_type = binding_pattern n -// CHECK:STDOUT: %.loc9_1: %empty_struct_type = var_pattern %n.patt -// CHECK:STDOUT: } -// CHECK:STDOUT: %n.var: ref %empty_struct_type = var n -// CHECK:STDOUT: %.loc9_9.1: type = splice_block %.loc9_9.3 [template = constants.%empty_struct_type] { -// CHECK:STDOUT: %.loc9_9.2: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc9_9.3: type = converted %.loc9_9.2, constants.%empty_struct_type [template = constants.%empty_struct_type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %n: ref %empty_struct_type = bind_name n, %n.var -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Int(%T.loc7_13.1: type, %N.loc7_23.1: @Int.%T.loc7_13.2 (%T)) { -// CHECK:STDOUT: %T.loc7_13.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_13.2 (constants.%T)] -// CHECK:STDOUT: %T.patt.loc7_13.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc7_13.2 (constants.%T.patt)] -// CHECK:STDOUT: %N.loc7_23.2: %T = bind_symbolic_name N, 1 [symbolic = %N.loc7_23.2 (constants.%N)] -// CHECK:STDOUT: %N.patt.loc7_23.2: %T = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc7_23.2 (constants.%N.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn[%T.param_patt: type](%N.param_patt: @Int.%T.loc7_13.2 (%T)) -> %empty_struct_type { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc7_46: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [template = constants.%empty_struct] -// CHECK:STDOUT: %.loc7_47: %empty_struct_type = converted %.loc7_46, %empty_struct [template = constants.%empty_struct] -// CHECK:STDOUT: return %.loc7_47 -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @__global_init() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32] -// CHECK:STDOUT: %Int.specific_fn: = specific_function constants.%Int, @Int(Core.IntLiteral, constants.%int_32) [template = constants.%Int.specific_fn] -// CHECK:STDOUT: %Int.call: init %empty_struct_type = call %Int.specific_fn() -// CHECK:STDOUT: assign file.%n.var, %Int.call -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Int(constants.%T, constants.%N) { -// CHECK:STDOUT: %T.loc7_13.2 => constants.%T -// CHECK:STDOUT: %T.patt.loc7_13.2 => constants.%T -// CHECK:STDOUT: %N.loc7_23.2 => constants.%N -// CHECK:STDOUT: %N.patt.loc7_23.2 => constants.%N -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Int(Core.IntLiteral, constants.%int_32) { -// CHECK:STDOUT: %T.loc7_13.2 => Core.IntLiteral -// CHECK:STDOUT: %T.patt.loc7_13.2 => Core.IntLiteral -// CHECK:STDOUT: %N.loc7_23.2 => constants.%int_32 -// CHECK:STDOUT: %N.patt.loc7_23.2 => constants.%int_32 -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: } +// CHECK:STDOUT: file {} // CHECK:STDOUT: // CHECK:STDOUT: --- fail_prelude_as_class.carbon // CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %Core: type = class_type @Core [template] -// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic] -// CHECK:STDOUT: %N: %T = bind_symbolic_name N, 1 [symbolic] -// CHECK:STDOUT: %N.patt: %T = symbolic_binding_pattern N, 1 [symbolic] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template] -// CHECK:STDOUT: %Int.type: type = fn_type @Int [template] -// CHECK:STDOUT: %Int: %Int.type = struct_value () [template] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [template] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [template] -// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .Core = %Core.decl -// CHECK:STDOUT: .n = %n -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.decl: type = class_decl @Core [template = constants.%Core] {} {} -// CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %n.patt: %empty_struct_type = binding_pattern n -// CHECK:STDOUT: %.loc13_1: %empty_struct_type = var_pattern %n.patt -// CHECK:STDOUT: } -// CHECK:STDOUT: %n.var: ref %empty_struct_type = var n -// CHECK:STDOUT: %.loc13_9.1: type = splice_block %.loc13_9.3 [template = constants.%empty_struct_type] { -// CHECK:STDOUT: %.loc13_9.2: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc13_9.3: type = converted %.loc13_9.2, constants.%empty_struct_type [template = constants.%empty_struct_type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %n: ref %empty_struct_type = bind_name n, %n.var -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @Core { -// CHECK:STDOUT: %Int.decl: %Int.type = fn_decl @Int [template = constants.%Int] { -// CHECK:STDOUT: %T.patt.loc6_10.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_10.1 (constants.%T.patt)] -// CHECK:STDOUT: %T.param_patt: type = value_param_pattern %T.patt.loc6_10.2, runtime_param [symbolic = %T.patt.loc6_10.1 (constants.%T.patt)] -// CHECK:STDOUT: %N.patt.loc6_20.2: @Int.%T.loc6_10.1 (%T) = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc6_20.1 (constants.%N.patt)] -// CHECK:STDOUT: %N.param_patt: @Int.%T.loc6_10.1 (%T) = value_param_pattern %N.patt.loc6_20.2, runtime_param [symbolic = %N.patt.loc6_20.1 (constants.%N.patt)] -// CHECK:STDOUT: %return.patt: %empty_struct_type = return_slot_pattern -// CHECK:STDOUT: %return.param_patt: %empty_struct_type = out_param_pattern %return.patt, runtime_param0 -// CHECK:STDOUT: } { -// CHECK:STDOUT: %.loc6_31.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc6_31.2: type = converted %.loc6_31.1, constants.%empty_struct_type [template = constants.%empty_struct_type] -// CHECK:STDOUT: %T.param: type = value_param runtime_param -// CHECK:STDOUT: %T.loc6_10.2: type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc6_10.1 (constants.%T)] -// CHECK:STDOUT: %N.param: @Int.%T.loc6_10.1 (%T) = value_param runtime_param -// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc6_10.2 [symbolic = %T.loc6_10.1 (constants.%T)] -// CHECK:STDOUT: %N.loc6_20.2: @Int.%T.loc6_10.1 (%T) = bind_symbolic_name N, 1, %N.param [symbolic = %N.loc6_20.1 (constants.%N)] -// CHECK:STDOUT: %return.param: ref %empty_struct_type = out_param runtime_param0 -// CHECK:STDOUT: %return: ref %empty_struct_type = return_slot %return.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [template = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%Core -// CHECK:STDOUT: .Int = %Int.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Int(%T.loc6_10.2: type, %N.loc6_20.2: @Int.%T.loc6_10.1 (%T)) { -// CHECK:STDOUT: %T.loc6_10.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_10.1 (constants.%T)] -// CHECK:STDOUT: %T.patt.loc6_10.1: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc6_10.1 (constants.%T.patt)] -// CHECK:STDOUT: %N.loc6_20.1: %T = bind_symbolic_name N, 1 [symbolic = %N.loc6_20.1 (constants.%N)] -// CHECK:STDOUT: %N.patt.loc6_20.1: %T = symbolic_binding_pattern N, 1 [symbolic = %N.patt.loc6_20.1 (constants.%N.patt)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn[%T.param_patt: type](%N.param_patt: @Int.%T.loc6_10.1 (%T)) -> %empty_struct_type { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc6_43: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [template = constants.%empty_struct] -// CHECK:STDOUT: %.loc6_44: %empty_struct_type = converted %.loc6_43, %empty_struct [template = constants.%empty_struct] -// CHECK:STDOUT: return %.loc6_44 -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @__global_init() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32] -// CHECK:STDOUT: assign file.%n.var, -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Int(constants.%T, constants.%N) { -// CHECK:STDOUT: %T.loc6_10.1 => constants.%T -// CHECK:STDOUT: %T.patt.loc6_10.1 => constants.%T -// CHECK:STDOUT: %N.loc6_20.1 => constants.%N -// CHECK:STDOUT: %N.patt.loc6_20.1 => constants.%N -// CHECK:STDOUT: } +// CHECK:STDOUT: file {} // CHECK:STDOUT: diff --git a/toolchain/check/testdata/packages/raw_core.carbon b/toolchain/check/testdata/packages/raw_core.carbon new file mode 100644 index 000000000000..d3890dbe38b8 --- /dev/null +++ b/toolchain/check/testdata/packages/raw_core.carbon @@ -0,0 +1,275 @@ +// 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 +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/packages/raw_core.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/packages/raw_core.carbon + +// --- package_raw_core.carbon + +package r#Core; + +fn F(); + +// --- import_raw_core.carbon + +library "[[@TEST_NAME]]"; + +import r#Core; + +fn G() { r#Core.F(); } + +fn H() { Core.Int(32); } + +// --- fail_raw_core_not_core.carbon + +library "[[@TEST_NAME]]"; + +import r#Core; + +// CHECK:STDERR: fail_raw_core_not_core.carbon:[[@LINE+4]]:10: error: member name `F` not found in `Core` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn G() { Core.F(); } +// CHECK:STDERR: ^~~~~~ +// CHECK:STDERR: +fn G() { Core.F(); } + +// CHECK:STDERR: fail_raw_core_not_core.carbon:[[@LINE+4]]:10: error: member name `Int` not found in `r#Core` [MemberNameNotFoundInScope] +// CHECK:STDERR: fn H() { r#Core.Int(32); } +// CHECK:STDERR: ^~~~~~~~~~ +// CHECK:STDERR: +fn H() { r#Core.Int(32); } + +// --- class_raw_core.carbon + +class r#Core { + var n: Core.Int(32); +} + +var c: r#Core = {.n = 0 as Core.Int(32)}; + +// CHECK:STDOUT: --- package_raw_core.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [template] +// CHECK:STDOUT: %F: %F.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(); +// CHECK:STDOUT: +// CHECK:STDOUT: --- import_raw_core.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %G.type: type = fn_type @G [template] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template] +// CHECK:STDOUT: %G: %G.type = struct_value () [template] +// CHECK:STDOUT: %F.type: type = fn_type @F [template] +// CHECK:STDOUT: %F: %F.type = struct_value () [template] +// CHECK:STDOUT: %H.type: type = fn_type @H [template] +// CHECK:STDOUT: %H: %H.type = struct_value () [template] +// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [template] +// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [template] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core.eced1c.1: = namespace file.%Core.import.1, [template] { +// CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.eced1c.2: = namespace file.%Core.import.loc4, [template] { +// CHECK:STDOUT: .F = %Core.F +// CHECK:STDOUT: import Core//default +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.F: %F.type = import_ref Core//default, F, loaded [template = constants.%F] +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [template = constants.%Int.generic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core.eced1c.1 +// CHECK:STDOUT: .r#Core = imports.%Core.eced1c.2 +// CHECK:STDOUT: .G = %G.decl +// CHECK:STDOUT: .H = %H.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import.1 = import Core +// CHECK:STDOUT: %Core.import.loc4 = import r#Core +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {} {} +// CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [template = constants.%H] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @G() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Core.ref: = name_ref r#Core, imports.%Core.eced1c.2 [template = imports.%Core.eced1c.2] +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, imports.%Core.F [template = constants.%F] +// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() [from "package_raw_core.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @H() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core.eced1c.1 [template = imports.%Core.eced1c.1] +// CHECK:STDOUT: %Int.ref: %Int.type = name_ref Int, imports.%Core.Int [template = constants.%Int.generic] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_raw_core_not_core.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %G.type: type = fn_type @G [template] +// CHECK:STDOUT: %G: %G.type = struct_value () [template] +// CHECK:STDOUT: %H.type: type = fn_type @H [template] +// CHECK:STDOUT: %H: %H.type = struct_value () [template] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core.eced1c.1: = namespace file.%Core.import.1, [template] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.eced1c.2: = namespace file.%Core.import.loc4, [template] { +// CHECK:STDOUT: import Core//default +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core.eced1c.1 +// CHECK:STDOUT: .r#Core = imports.%Core.eced1c.2 +// CHECK:STDOUT: .G = %G.decl +// CHECK:STDOUT: .H = %H.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import.1 = import Core +// CHECK:STDOUT: %Core.import.loc4 = import r#Core +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [template = constants.%G] {} {} +// CHECK:STDOUT: %H.decl: %H.type = fn_decl @H [template = constants.%H] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @G() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core.eced1c.1 [template = imports.%Core.eced1c.1] +// CHECK:STDOUT: %F.ref: = name_ref F, [template = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @H() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Core.ref: = name_ref r#Core, imports.%Core.eced1c.2 [template = imports.%Core.eced1c.2] +// CHECK:STDOUT: %Int.ref: = name_ref Int, [template = ] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- class_raw_core.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Core: type = class_type @Core [template] +// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [template] +// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [template] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [template] +// CHECK:STDOUT: %Core.elem: type = unbound_element_type %Core, %i32 [template] +// CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [template] +// CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [template] +// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [template] +// CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [template] +// CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [template] +// CHECK:STDOUT: %impl_witness.882: = impl_witness (imports.%Core.import_ref.78a), @impl.3(%int_32) [template] +// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.3(%int_32) [template] +// CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [template] +// CHECK:STDOUT: %As.facet: %As.type.fd4 = facet_value Core.IntLiteral, %impl_witness.882 [template] +// CHECK:STDOUT: %.214: type = fn_type_with_self_type %Convert.type.99b, %As.facet [template] +// CHECK:STDOUT: %Convert.bound: = bound_method %int_0.5c6, %Convert.197 [template] +// CHECK:STDOUT: %Convert.specific_fn: = specific_function %Convert.bound, @Convert.5(%int_32) [template] +// CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [template] +// CHECK:STDOUT: %Core.val: %Core = struct_value (%int_0.6a9) [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { +// CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .As = %Core.As +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [template = constants.%Int.generic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .r#Core = %Core.decl +// CHECK:STDOUT: .c = %c +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Core.decl: type = class_decl @Core [template = constants.%Core] {} {} +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %Core = binding_pattern c +// CHECK:STDOUT: %.loc6: %Core = var_pattern %c.patt +// CHECK:STDOUT: } +// CHECK:STDOUT: %c.var: ref %Core = var c +// CHECK:STDOUT: %Core.ref: type = name_ref r#Core, %Core.decl [template = constants.%Core] +// CHECK:STDOUT: %c: ref %Core = bind_name c, %c.var +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Core { +// CHECK:STDOUT: %.loc3_8: %Core.elem = field_decl n, element0 [template] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %.loc3_3: %Core.elem = var_pattern %.loc3_8 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.var: ref %Core.elem = var +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [template = constants.%complete_type.54b] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Core +// CHECK:STDOUT: .n = %.loc3_8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @__global_init() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [template = constants.%int_0.5c6] +// CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [template = imports.%Core] +// CHECK:STDOUT: %Int.ref: %Int.type = name_ref Int, imports.%Core.Int [template = constants.%Int.generic] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32] +// CHECK:STDOUT: %impl.elem0: %.214 = impl_witness_access constants.%impl_witness.882, element0 [template = constants.%Convert.197] +// CHECK:STDOUT: %bound_method: = bound_method %int_0, %impl.elem0 [template = constants.%Convert.bound] +// CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Convert.5(constants.%int_32) [template = constants.%Convert.specific_fn] +// CHECK:STDOUT: %int.convert_checked: init %i32 = call %specific_fn(%int_0) [template = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc6_25.1: %i32 = value_of_initializer %int.convert_checked [template = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc6_25.2: %i32 = converted %int_0, %.loc6_25.1 [template = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc6_40.1: %struct_type.n = struct_literal (%.loc6_25.2) +// CHECK:STDOUT: %.loc6_40.2: ref %i32 = class_element_access file.%c.var, element0 +// CHECK:STDOUT: %.loc6_40.3: init %i32 = initialize_from %.loc6_25.2 to %.loc6_40.2 [template = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc6_40.4: init %Core = class_init (%.loc6_40.3), file.%c.var [template = constants.%Core.val] +// CHECK:STDOUT: %.loc6_1: init %Core = converted %.loc6_40.1, %.loc6_40.4 [template = constants.%Core.val] +// CHECK:STDOUT: assign file.%c.var, %.loc6_1 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/lex/token_kind.def b/toolchain/lex/token_kind.def index a67b3a755a92..de6affdb280c 100644 --- a/toolchain/lex/token_kind.def +++ b/toolchain/lex/token_kind.def @@ -176,6 +176,7 @@ CARBON_KEYWORD_TOKEN(Case, "case") CARBON_KEYWORD_TOKEN(Choice, "choice") CARBON_KEYWORD_TOKEN(Const, "const") CARBON_KEYWORD_TOKEN(Continue, "continue") +CARBON_KEYWORD_TOKEN(Core, "Core") CARBON_KEYWORD_TOKEN(Default, "default") CARBON_KEYWORD_TOKEN(Destructor, "destructor") CARBON_KEYWORD_TOKEN(Else, "else") diff --git a/toolchain/lex/token_kind_test.cpp b/toolchain/lex/token_kind_test.cpp index 5054590f9910..92a89368c3d0 100644 --- a/toolchain/lex/token_kind_test.cpp +++ b/toolchain/lex/token_kind_test.cpp @@ -21,7 +21,7 @@ constexpr llvm::StringLiteral SymbolRegex = // We restrict keywords to be lowercase ASCII letters and underscores with a few // specific exceptions. -constexpr llvm::StringLiteral KeywordRegex = "[a-z_]+|Self|String"; +constexpr llvm::StringLiteral KeywordRegex = "[a-z_]+|Core|Self|String"; #define CARBON_TOKEN(TokenName) \ TEST(TokenKindTest, TokenName) { \ diff --git a/toolchain/lower/mangler.cpp b/toolchain/lower/mangler.cpp index 3562d4307366..89c8f75e42a9 100644 --- a/toolchain/lower/mangler.cpp +++ b/toolchain/lower/mangler.cpp @@ -32,10 +32,14 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os, os << prefix; } if (name_scope_id == SemIR::NameScopeId::Package) { - if (auto package_id = sem_ir().package_id(); package_id.has_value()) { - os << sem_ir().identifiers().Get(package_id); + auto package_id = sem_ir().package_id(); + if (auto ident_id = package_id.AsIdentifierId(); ident_id.has_value()) { + os << sem_ir().identifiers().Get(ident_id); } else { - os << "Main"; + // TODO: Handle name conflicts between special package names and raw + // identifier package names. Note that any change here will also require + // a change to namespace mangling for imported packages. + os << package_id.AsSpecialName(); } continue; } @@ -111,7 +115,7 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os, break; } case SemIR::Namespace::Kind: { - os << names().GetAsStringIfIdentifier(name_scope.name_id()); + os << names().GetIRBaseName(name_scope.name_id()); break; } default: diff --git a/toolchain/parse/handle_expr.cpp b/toolchain/parse/handle_expr.cpp index 558162d95c5e..5b7ff7c74e98 100644 --- a/toolchain/parse/handle_expr.cpp +++ b/toolchain/parse/handle_expr.cpp @@ -165,6 +165,11 @@ auto HandleExprInPostfix(Context& context) -> void { context.PushState(state); break; } + case Lex::TokenKind::Core: { + context.AddLeafNode(NodeKind::CoreNameExpr, context.Consume()); + context.PushState(state); + break; + } case Lex::TokenKind::SelfValueIdentifier: { context.AddLeafNode(NodeKind::SelfValueNameExpr, context.Consume()); context.PushState(state); diff --git a/toolchain/parse/handle_import_and_package.cpp b/toolchain/parse/handle_import_and_package.cpp index 5112a5189488..108ab422777c 100644 --- a/toolchain/parse/handle_import_and_package.cpp +++ b/toolchain/parse/handle_import_and_package.cpp @@ -42,32 +42,45 @@ static auto HandleDeclContent(Context& context, Context::StateStackEntry state, Tree::PackagingNames names{ .node_id = ImportDeclId(NodeId(state.subtree_start)), .is_export = is_export}; - if (declaration != NodeKind::LibraryDecl) { - if (auto package_name_token = - context.ConsumeIf(Lex::TokenKind::Identifier)) { - if (names.is_export) { - names.is_export = false; - state.has_error = true; - CARBON_DIAGNOSTIC(ExportImportPackage, Error, - "`export` cannot be used when importing a package"); - context.emitter().Emit(*package_name_token, ExportImportPackage); - } - names.package_id = context.tokens().GetIdentifier(*package_name_token); - context.AddLeafNode(NodeKind::PackageName, *package_name_token); - } else if (declaration == NodeKind::PackageDecl || - !context.PositionIs(Lex::TokenKind::Library)) { + // Parse the package name. + if (declaration == NodeKind::LibraryDecl || + (declaration == NodeKind::ImportDecl && + context.PositionIs(Lex::TokenKind::Library))) { + // This is either `library ...` or `import library ...`, so no package name + // is expected. + } else { + // We require a package name. This is either an identifier or the `Core` + // keyword. + auto package_name_position = *context.position(); + if (auto ident = context.ConsumeIf(Lex::TokenKind::Identifier)) { + names.package_id = + PackageNameId::ForIdentifier(context.tokens().GetIdentifier(*ident)); + context.AddLeafNode(NodeKind::IdentifierPackageName, *ident); + } else if (auto core = context.ConsumeIf(Lex::TokenKind::Core)) { + names.package_id = PackageNameId::Core; + context.AddLeafNode(NodeKind::CorePackageName, *core); + } else { CARBON_DIAGNOSTIC(ExpectedIdentifierAfterPackage, Error, "expected identifier after `package`"); CARBON_DIAGNOSTIC(ExpectedIdentifierAfterImport, Error, "expected identifier or `library` after `import`"); - context.emitter().Emit(*context.position(), + context.emitter().Emit(package_name_position, declaration == NodeKind::PackageDecl ? ExpectedIdentifierAfterPackage : ExpectedIdentifierAfterImport); on_parse_error(); return; } + + if (names.is_export) { + names.is_export = false; + state.has_error = true; + + CARBON_DIAGNOSTIC(ExportImportPackage, Error, + "`export` cannot be used when importing a package"); + context.emitter().Emit(package_name_position, ExportImportPackage); + } } // Parse the optional library keyword. diff --git a/toolchain/parse/node_ids.h b/toolchain/parse/node_ids.h index fc83727f5a8d..1ff35cc14b99 100644 --- a/toolchain/parse/node_ids.h +++ b/toolchain/parse/node_ids.h @@ -81,6 +81,7 @@ using AnyStatementId = using AnyRequirementId = NodeIdInCategory; using AnyNonExprIdentifierNameId = NodeIdInCategory; +using AnyPackageNameId = NodeIdInCategory; // NodeId with kind that matches one of the `T::Kind`s. template diff --git a/toolchain/parse/node_kind.def b/toolchain/parse/node_kind.def index 5380e2317511..7096a5371736 100644 --- a/toolchain/parse/node_kind.def +++ b/toolchain/parse/node_kind.def @@ -105,7 +105,9 @@ CARBON_PARSE_NODE_KIND(SelfTypeNameExpr) CARBON_PARSE_NODE_KIND(BaseName) CARBON_PARSE_NODE_KIND(PackageExpr) -CARBON_PARSE_NODE_KIND(PackageName) +CARBON_PARSE_NODE_KIND(CoreNameExpr) +CARBON_PARSE_NODE_KIND(IdentifierPackageName) +CARBON_PARSE_NODE_KIND(CorePackageName) CARBON_PARSE_NODE_KIND(LibraryName) CARBON_PARSE_NODE_KIND(PackageIntroducer) diff --git a/toolchain/parse/node_kind.h b/toolchain/parse/node_kind.h index 17dc019ca3db..49398fa36430 100644 --- a/toolchain/parse/node_kind.h +++ b/toolchain/parse/node_kind.h @@ -36,9 +36,10 @@ class NodeCategory : public Printable { IntConst = 1 << 8, Requirement = 1 << 9, NonExprIdentifierName = 1 << 10, + PackageName = 1 << 11, None = 0, - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/NonExprIdentifierName) + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/PackageName) }; // Support implicit conversion so that the difference with the member enum is diff --git a/toolchain/parse/testdata/package_expr/core.carbon b/toolchain/parse/testdata/package_expr/core.carbon new file mode 100644 index 000000000000..b5a87b01af59 --- /dev/null +++ b/toolchain/parse/testdata/package_expr/core.carbon @@ -0,0 +1,29 @@ +// 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 +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/package_expr/core.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/package_expr/core.carbon + +var x: Core.Foo = Core.Bar; + +// CHECK:STDOUT: - filename: core.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, +// CHECK:STDOUT: {kind: 'CoreNameExpr', text: 'Core'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'MemberAccessExpr', text: '.', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'CoreNameExpr', text: 'Core'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'MemberAccessExpr', text: '.', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 12}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/export.carbon b/toolchain/parse/testdata/packages/export.carbon index 4afd5791573b..c3f712a31117 100644 --- a/toolchain/parse/testdata/packages/export.carbon +++ b/toolchain/parse/testdata/packages/export.carbon @@ -147,7 +147,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, @@ -158,7 +158,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, @@ -171,7 +171,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'InvalidParse', text: '(', has_error: yes}, @@ -182,7 +182,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'InvalidParse', text: 'package', has_error: yes}, @@ -193,7 +193,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'InvalidParse', text: '', has_error: yes}, @@ -204,7 +204,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes}, @@ -215,7 +215,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, @@ -226,7 +226,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, @@ -239,7 +239,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'InvalidParse', text: '.', has_error: yes}, @@ -250,7 +250,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'C'}, @@ -264,7 +264,7 @@ export Foo; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, @@ -286,7 +286,7 @@ export Foo; // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ExportIntroducer', text: 'export'}, // CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Foo'}, diff --git a/toolchain/parse/testdata/packages/import/after_import.carbon b/toolchain/parse/testdata/packages/import/after_import.carbon index 2634c852fd8c..6a78be5fa57d 100644 --- a/toolchain/parse/testdata/packages/import/after_import.carbon +++ b/toolchain/parse/testdata/packages/import/after_import.carbon @@ -15,10 +15,10 @@ import B; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'A'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'A'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'B'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'B'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/import/after_package.carbon b/toolchain/parse/testdata/packages/import/after_package.carbon index bc1e58ad2520..c88fba4e0ebf 100644 --- a/toolchain/parse/testdata/packages/import/after_package.carbon +++ b/toolchain/parse/testdata/packages/import/after_package.carbon @@ -16,10 +16,10 @@ import B; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'A'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'A'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'B'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'B'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/import/basic.carbon b/toolchain/parse/testdata/packages/import/basic.carbon index 7395c03b4454..552ed1f5f995 100644 --- a/toolchain/parse/testdata/packages/import/basic.carbon +++ b/toolchain/parse/testdata/packages/import/basic.carbon @@ -14,7 +14,7 @@ import Geometry; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/import/core.carbon b/toolchain/parse/testdata/packages/import/core.carbon new file mode 100644 index 000000000000..1927b4f8ef9f --- /dev/null +++ b/toolchain/parse/testdata/packages/import/core.carbon @@ -0,0 +1,27 @@ +// 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 +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/packages/import/core.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/packages/import/core.carbon + +import Core; + +import Core library "prelude"; + +// CHECK:STDOUT: - filename: core.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, +// CHECK:STDOUT: {kind: 'CorePackageName', text: 'Core'}, +// CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, +// CHECK:STDOUT: {kind: 'CorePackageName', text: 'Core'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"prelude"'}, +// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/import/export.carbon b/toolchain/parse/testdata/packages/import/export.carbon index 8f368bd6908e..6608b71a981f 100644 --- a/toolchain/parse/testdata/packages/import/export.carbon +++ b/toolchain/parse/testdata/packages/import/export.carbon @@ -69,11 +69,11 @@ export import library "lib"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, // CHECK:STDOUT: {kind: 'ExportModifier', text: 'export'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Bar'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', has_error: yes, subtree_size: 4}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] @@ -81,7 +81,7 @@ export import library "lib"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, // CHECK:STDOUT: {kind: 'ExportModifier', text: 'export'}, @@ -94,7 +94,7 @@ export import library "lib"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, // CHECK:STDOUT: {kind: 'ExportModifier', text: 'export'}, @@ -107,7 +107,7 @@ export import library "lib"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, // CHECK:STDOUT: {kind: 'ExportModifier', text: 'export'}, @@ -137,7 +137,7 @@ export import library "lib"; // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Pkg'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Pkg'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, // CHECK:STDOUT: {kind: 'ExportModifier', text: 'export'}, diff --git a/toolchain/parse/testdata/packages/import/fail_extra_string.carbon b/toolchain/parse/testdata/packages/import/fail_extra_string.carbon index a7d0a0edb928..b4b8c6d2b129 100644 --- a/toolchain/parse/testdata/packages/import/fail_extra_string.carbon +++ b/toolchain/parse/testdata/packages/import/fail_extra_string.carbon @@ -18,7 +18,7 @@ import Foo library "bar" "baz"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Foo'}, // CHECK:STDOUT: {kind: 'LibraryName', text: '"bar"'}, // CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', has_error: yes, subtree_size: 5}, diff --git a/toolchain/parse/testdata/packages/import/fail_library_is_identifier.carbon b/toolchain/parse/testdata/packages/import/fail_library_is_identifier.carbon index 78013661d2d0..84a78be82a89 100644 --- a/toolchain/parse/testdata/packages/import/fail_library_is_identifier.carbon +++ b/toolchain/parse/testdata/packages/import/fail_library_is_identifier.carbon @@ -18,7 +18,7 @@ import Geometry library Shapes; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'LibraryName', text: 'Shapes', has_error: yes}, // CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', has_error: yes, subtree_size: 5}, diff --git a/toolchain/parse/testdata/packages/import/fail_no_semi.carbon b/toolchain/parse/testdata/packages/import/fail_no_semi.carbon index 591b6e38f13f..9f554b7dd628 100644 --- a/toolchain/parse/testdata/packages/import/fail_no_semi.carbon +++ b/toolchain/parse/testdata/packages/import/fail_no_semi.carbon @@ -18,7 +18,7 @@ import Geometry // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: 'Geometry', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/import/fail_omit_library_keyword.carbon b/toolchain/parse/testdata/packages/import/fail_omit_library_keyword.carbon index e3ce4963d20b..ec0518fa90b4 100644 --- a/toolchain/parse/testdata/packages/import/fail_omit_library_keyword.carbon +++ b/toolchain/parse/testdata/packages/import/fail_omit_library_keyword.carbon @@ -18,7 +18,7 @@ import Geometry "Shapes"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/import/fail_type.carbon b/toolchain/parse/testdata/packages/import/fail_type.carbon index 9f0bec87d514..ac6929c3af95 100644 --- a/toolchain/parse/testdata/packages/import/fail_type.carbon +++ b/toolchain/parse/testdata/packages/import/fail_type.carbon @@ -18,7 +18,7 @@ import Geometry api; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/import/library.carbon b/toolchain/parse/testdata/packages/import/library.carbon index 4dabaeec2b74..1eda27166286 100644 --- a/toolchain/parse/testdata/packages/import/library.carbon +++ b/toolchain/parse/testdata/packages/import/library.carbon @@ -14,7 +14,7 @@ import Geometry library "Shapes"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'LibraryName', text: '"Shapes"'}, // CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 5}, diff --git a/toolchain/parse/testdata/packages/import/ordering.carbon b/toolchain/parse/testdata/packages/import/ordering.carbon index fc8522ed3973..63ade14bb73c 100644 --- a/toolchain/parse/testdata/packages/import/ordering.carbon +++ b/toolchain/parse/testdata/packages/import/ordering.carbon @@ -29,10 +29,10 @@ import B; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'A'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'A'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'B'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'B'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] @@ -43,7 +43,7 @@ import B; // CHECK:STDOUT: {kind: 'LibraryName', text: '"after_library"'}, // CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'B'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'B'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] @@ -51,10 +51,10 @@ import B; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'A'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'A'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'B'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'B'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/import/semi_before.carbon b/toolchain/parse/testdata/packages/import/semi_before.carbon index 52b3f24e2d58..4a7bf64e83e7 100644 --- a/toolchain/parse/testdata/packages/import/semi_before.carbon +++ b/toolchain/parse/testdata/packages/import/semi_before.carbon @@ -29,7 +29,7 @@ import Bar; // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 4}, // CHECK:STDOUT: {kind: 'EmptyDecl', text: ';'}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Bar'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'EmptyDecl', text: ';'}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, diff --git a/toolchain/parse/testdata/packages/library/fail_too_late.carbon b/toolchain/parse/testdata/packages/library/fail_too_late.carbon index 1aac94ca691f..975cf4c32b19 100644 --- a/toolchain/parse/testdata/packages/library/fail_too_late.carbon +++ b/toolchain/parse/testdata/packages/library/fail_too_late.carbon @@ -23,7 +23,7 @@ library "[[@TEST_NAME]]"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'LibraryIntroducer', text: 'library'}, // CHECK:STDOUT: {kind: 'LibraryDecl', text: ';', has_error: yes, subtree_size: 2}, diff --git a/toolchain/parse/testdata/packages/package/api.carbon b/toolchain/parse/testdata/packages/package/api.carbon index 417448174d8c..b4b147bd2fd9 100644 --- a/toolchain/parse/testdata/packages/package/api.carbon +++ b/toolchain/parse/testdata/packages/package/api.carbon @@ -14,7 +14,7 @@ package Geometry; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/package/api_library.carbon b/toolchain/parse/testdata/packages/package/api_library.carbon index c4bd9f1feb2f..bb316eddc2e7 100644 --- a/toolchain/parse/testdata/packages/package/api_library.carbon +++ b/toolchain/parse/testdata/packages/package/api_library.carbon @@ -14,7 +14,7 @@ package Geometry library "[[@TEST_NAME]]"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'LibraryName', text: '"api_library"'}, // CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 5}, diff --git a/toolchain/parse/testdata/packages/package/core.carbon b/toolchain/parse/testdata/packages/package/core.carbon new file mode 100644 index 000000000000..86c5c7f3c117 --- /dev/null +++ b/toolchain/parse/testdata/packages/package/core.carbon @@ -0,0 +1,36 @@ +// 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 +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/packages/package/core.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/packages/package/core.carbon + +// --- core.carbon + +package Core; + +// --- core_with_library.carbon + +package Core library "prelude"; + +// CHECK:STDOUT: - filename: core.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, +// CHECK:STDOUT: {kind: 'CorePackageName', text: 'Core'}, +// CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] +// CHECK:STDOUT: - filename: core_with_library.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, +// CHECK:STDOUT: {kind: 'CorePackageName', text: 'Core'}, +// CHECK:STDOUT: {kind: 'LibraryName', text: '"prelude"'}, +// CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/package/fail_after_import.carbon b/toolchain/parse/testdata/packages/package/fail_after_import.carbon index 038f992956ef..664a586d9cac 100644 --- a/toolchain/parse/testdata/packages/package/fail_after_import.carbon +++ b/toolchain/parse/testdata/packages/package/fail_after_import.carbon @@ -23,7 +23,7 @@ package B; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'ImportIntroducer', text: 'import'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'A'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'A'}, // CHECK:STDOUT: {kind: 'ImportDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', has_error: yes, subtree_size: 2}, diff --git a/toolchain/parse/testdata/packages/package/fail_after_package.carbon b/toolchain/parse/testdata/packages/package/fail_after_package.carbon index ecc4cdf3cde2..5818fe5425fa 100644 --- a/toolchain/parse/testdata/packages/package/fail_after_package.carbon +++ b/toolchain/parse/testdata/packages/package/fail_after_package.carbon @@ -22,7 +22,7 @@ package B; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'A'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'A'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 3}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', has_error: yes, subtree_size: 2}, diff --git a/toolchain/parse/testdata/packages/package/fail_extra_string.carbon b/toolchain/parse/testdata/packages/package/fail_extra_string.carbon index b7db4cb3c3f5..7cddc5feaf58 100644 --- a/toolchain/parse/testdata/packages/package/fail_extra_string.carbon +++ b/toolchain/parse/testdata/packages/package/fail_extra_string.carbon @@ -18,7 +18,7 @@ package Foo library "bar" "baz"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Foo'}, // CHECK:STDOUT: {kind: 'LibraryName', text: '"bar"'}, // CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', has_error: yes, subtree_size: 5}, diff --git a/toolchain/parse/testdata/packages/package/fail_library_is_identifier.carbon b/toolchain/parse/testdata/packages/package/fail_library_is_identifier.carbon index fc9ca38b1b2b..f24f51f5ec8e 100644 --- a/toolchain/parse/testdata/packages/package/fail_library_is_identifier.carbon +++ b/toolchain/parse/testdata/packages/package/fail_library_is_identifier.carbon @@ -18,7 +18,7 @@ package Geometry library Shapes; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'LibraryName', text: 'Shapes', has_error: yes}, // CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', has_error: yes, subtree_size: 5}, diff --git a/toolchain/parse/testdata/packages/package/fail_no_semi.carbon b/toolchain/parse/testdata/packages/package/fail_no_semi.carbon index 3ea7c1e1408a..30751a11b78a 100644 --- a/toolchain/parse/testdata/packages/package/fail_no_semi.carbon +++ b/toolchain/parse/testdata/packages/package/fail_no_semi.carbon @@ -18,7 +18,7 @@ package Geometry // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: 'Geometry', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/package/fail_omit_library_keyword.carbon b/toolchain/parse/testdata/packages/package/fail_omit_library_keyword.carbon index 6d6ae2b48bb2..0bd109c75ac7 100644 --- a/toolchain/parse/testdata/packages/package/fail_omit_library_keyword.carbon +++ b/toolchain/parse/testdata/packages/package/fail_omit_library_keyword.carbon @@ -18,7 +18,7 @@ package Geometry "Shapes"; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/package/fail_trailing_impl.carbon b/toolchain/parse/testdata/packages/package/fail_trailing_impl.carbon index 1c13eb19fa8c..7a15eb67d78a 100644 --- a/toolchain/parse/testdata/packages/package/fail_trailing_impl.carbon +++ b/toolchain/parse/testdata/packages/package/fail_trailing_impl.carbon @@ -18,7 +18,7 @@ package Geometry impl; // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/packages/package/impl.carbon b/toolchain/parse/testdata/packages/package/impl.carbon index 00b3d6dcd5b3..d0a3e3da6dcf 100644 --- a/toolchain/parse/testdata/packages/package/impl.carbon +++ b/toolchain/parse/testdata/packages/package/impl.carbon @@ -29,7 +29,7 @@ impl package.Name as package.Interface {} // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 4}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] @@ -38,7 +38,7 @@ impl package.Name as package.Interface {} // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'DisambiguateImpl'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'DisambiguateImpl'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'}, // CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, @@ -53,7 +53,7 @@ impl package.Name as package.Interface {} // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'DisambiguateImplPackage'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'DisambiguateImplPackage'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'}, // CHECK:STDOUT: {kind: 'PackageExpr', text: 'package'}, diff --git a/toolchain/parse/testdata/packages/package/impl_library.carbon b/toolchain/parse/testdata/packages/package/impl_library.carbon index 32a360b3f8e5..d957155c2ee2 100644 --- a/toolchain/parse/testdata/packages/package/impl_library.carbon +++ b/toolchain/parse/testdata/packages/package/impl_library.carbon @@ -15,7 +15,7 @@ impl package Geometry library "[[@TEST_NAME]]"; // CHECK:STDOUT: {kind: 'FileStart', text: ''}, // CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'ImplModifier', text: 'impl'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'LibraryName', text: '"impl_library"'}, // CHECK:STDOUT: {kind: 'LibrarySpecifier', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 6}, diff --git a/toolchain/parse/testdata/packages/package/modifiers.carbon b/toolchain/parse/testdata/packages/package/modifiers.carbon index 80526d063ab0..0efef1fc541e 100644 --- a/toolchain/parse/testdata/packages/package/modifiers.carbon +++ b/toolchain/parse/testdata/packages/package/modifiers.carbon @@ -18,7 +18,7 @@ extend virtual base package Geometry; // CHECK:STDOUT: {kind: 'ExtendModifier', text: 'extend'}, // CHECK:STDOUT: {kind: 'VirtualModifier', text: 'virtual'}, // CHECK:STDOUT: {kind: 'BaseModifier', text: 'base'}, -// CHECK:STDOUT: {kind: 'PackageName', text: 'Geometry'}, +// CHECK:STDOUT: {kind: 'IdentifierPackageName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 6}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parse/tree.h b/toolchain/parse/tree.h index 3090ad6aa2b5..dfc94fc606db 100644 --- a/toolchain/parse/tree.h +++ b/toolchain/parse/tree.h @@ -84,7 +84,8 @@ class Tree : public Printable { // to the node for diagnostics. struct PackagingNames { ImportDeclId node_id; - IdentifierId package_id = IdentifierId::None; + PackageNameId package_id = PackageNameId::None; + // TODO: Move LibraryNameId to Base and use it here. StringLiteralValueId library_id = StringLiteralValueId::None; // Whether an import is exported. This is on the file's packaging // declaration even though it doesn't apply, for consistency in structure. diff --git a/toolchain/parse/typed_nodes.h b/toolchain/parse/typed_nodes.h index 07907af331ab..a948fc9aaba2 100644 --- a/toolchain/parse/typed_nodes.h +++ b/toolchain/parse/typed_nodes.h @@ -200,8 +200,16 @@ struct DeclName { using PackageExpr = LeafNode; +// The `Core` keyword in an expression. +using CoreNameExpr = + LeafNode; + // The name of a package or library for `package`, `import`, and `library`. -using PackageName = LeafNode; +using IdentifierPackageName = + LeafNode; +using CorePackageName = LeafNode; using LibraryName = LeafNode; using DefaultLibrary = @@ -228,7 +236,7 @@ struct PackageDecl { PackageIntroducerId introducer; llvm::SmallVector modifiers; - std::optional name; + std::optional name; std::optional library; Lex::SemiTokenIndex token; }; @@ -242,7 +250,7 @@ struct ImportDecl { ImportIntroducerId introducer; llvm::SmallVector modifiers; - std::optional name; + std::optional name; std::optional library; Lex::SemiTokenIndex token; }; diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 6018d06352a4..ff3d5092b733 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -24,7 +24,7 @@ File::File(const Parse::Tree* parse_tree, CheckIRId check_ir_id, : parse_tree_(parse_tree), check_ir_id_(check_ir_id), package_id_(packaging_decl ? packaging_decl->names.package_id - : IdentifierId::None), + : PackageNameId::None), library_id_(packaging_decl ? LibraryNameId::ForStringLiteralValueId( packaging_decl->names.library_id) : LibraryNameId::Default), diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index d0eb3dfde749..083b60207d11 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -94,7 +94,7 @@ class File : public Printable { } auto check_ir_id() const -> CheckIRId { return check_ir_id_; } - auto package_id() const -> IdentifierId { return package_id_; } + auto package_id() const -> PackageNameId { return package_id_; } auto library_id() const -> SemIR::LibraryNameId { return library_id_; } // Directly expose SharedValueStores members. @@ -226,7 +226,7 @@ class File : public Printable { CheckIRId check_ir_id_; // The file's package. - IdentifierId package_id_ = IdentifierId::None; + PackageNameId package_id_ = PackageNameId::None; // The file's library. LibraryNameId library_id_ = LibraryNameId::None; diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index b5fad570e4da..4d0ab3e55a03 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -1365,10 +1365,11 @@ class FormatterImpl { const auto& import_ir = *sem_ir_->import_irs().Get(id).sem_ir; CARBON_CHECK(import_ir.library_id().has_value()); + auto package_id = import_ir.package_id(); llvm::StringRef package_name = - import_ir.package_id().has_value() - ? import_ir.identifiers().Get(import_ir.package_id()) - : "Main"; + package_id.AsIdentifierId().has_value() + ? import_ir.identifiers().Get(package_id.AsIdentifierId()) + : package_id.AsSpecialName(); llvm::StringRef library_name = (import_ir.library_id() != LibraryNameId::Default) ? import_ir.string_literal_values().Get( diff --git a/toolchain/sem_ir/ids.cpp b/toolchain/sem_ir/ids.cpp index cc07791dab58..dddc6b17fa9f 100644 --- a/toolchain/sem_ir/ids.cpp +++ b/toolchain/sem_ir/ids.cpp @@ -4,6 +4,7 @@ #include "toolchain/sem_ir/ids.h" +#include "toolchain/base/value_ids.h" #include "toolchain/sem_ir/singleton_insts.h" #include "toolchain/sem_ir/typed_insts.h" @@ -86,24 +87,40 @@ auto NameId::ForIdentifier(IdentifierId id) -> NameId { } } +auto NameId::ForPackageName(PackageNameId id) -> NameId { + if (auto identifier_id = id.AsIdentifierId(); identifier_id.has_value()) { + return ForIdentifier(identifier_id); + } else if (id == PackageNameId::Core) { + return NameId::Core; + } else if (!id.has_value()) { + return NameId::None; + } else { + CARBON_FATAL("Unexpected package ID {0}", id); + } +} + auto NameId::Print(llvm::raw_ostream& out) const -> void { if (!has_value() || index >= 0) { IdBase::Print(out); return; } out << Label << "("; - if (*this == SelfValue) { - out << "SelfValue"; - } else if (*this == SelfType) { - out << "SelfType"; + if (*this == Base) { + out << "Base"; + } else if (*this == Core) { + out << "Core"; + } else if (*this == PackageNamespace) { + out << "PackageNamespace"; } else if (*this == PeriodSelf) { out << "PeriodSelf"; } else if (*this == ReturnSlot) { out << "ReturnSlot"; - } else if (*this == PackageNamespace) { - out << "PackageNamespace"; - } else if (*this == Base) { - out << "Base"; + } else if (*this == SelfType) { + out << "SelfType"; + } else if (*this == SelfValue) { + out << "SelfValue"; + } else if (*this == Vptr) { + out << "Vptr"; } else { CARBON_FATAL("Unknown index {0}", index); IdBase::Print(out); diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index fad7f7b719f6..4d93690d56ba 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -463,18 +463,20 @@ struct NameId : public IdBase { // An ID with no value. static const NameId None; - // The name of `self`. - static const NameId SelfValue; - // The name of `Self`. - static const NameId SelfType; + // The name of `base`. + static const NameId Base; + // The name of the package `Core`. + static const NameId Core; + // The name of `package`. + static const NameId PackageNamespace; // The name of `.Self`. static const NameId PeriodSelf; // The name of the return slot in a function. static const NameId ReturnSlot; - // The name of `package`. - static const NameId PackageNamespace; - // The name of `base`. - static const NameId Base; + // The name of `Self`. + static const NameId SelfType; + // The name of `self`. + static const NameId SelfValue; // The name of `vptr`. static const NameId Vptr; @@ -485,6 +487,10 @@ struct NameId : public IdBase { // Returns the NameId corresponding to a particular IdentifierId. static auto ForIdentifier(IdentifierId id) -> NameId; + // Returns the NameId corresponding to a particular PackageNameId. This is the + // name that is declared when the package is imported. + static auto ForPackageName(PackageNameId id) -> NameId; + using IdBase::IdBase; // Returns the IdentifierId corresponding to this NameId, or `None` if this is @@ -497,14 +503,15 @@ struct NameId : public IdBase { }; constexpr NameId NameId::None = NameId(NoneIndex); -constexpr NameId NameId::SelfValue = NameId(NoneIndex - 1); -constexpr NameId NameId::SelfType = NameId(NoneIndex - 2); -constexpr NameId NameId::PeriodSelf = NameId(NoneIndex - 3); -constexpr NameId NameId::ReturnSlot = NameId(NoneIndex - 4); -constexpr NameId NameId::PackageNamespace = NameId(NoneIndex - 5); -constexpr NameId NameId::Base = NameId(NoneIndex - 6); -constexpr NameId NameId::Vptr = NameId(NoneIndex - 7); -constexpr int NameId::NonIndexValueCount = 8; +constexpr NameId NameId::Base = NameId(NoneIndex - 1); +constexpr NameId NameId::Core = NameId(NoneIndex - 2); +constexpr NameId NameId::PackageNamespace = NameId(NoneIndex - 3); +constexpr NameId NameId::PeriodSelf = NameId(NoneIndex - 4); +constexpr NameId NameId::ReturnSlot = NameId(NoneIndex - 5); +constexpr NameId NameId::SelfType = NameId(NoneIndex - 6); +constexpr NameId NameId::SelfValue = NameId(NoneIndex - 7); +constexpr NameId NameId::Vptr = NameId(NoneIndex - 8); +constexpr int NameId::NonIndexValueCount = 9; // Enforce the link between SpecialValueCount and the last special value. static_assert(NameId::NonIndexValueCount == -NameId::Vptr.index); diff --git a/toolchain/sem_ir/inst_fingerprinter.cpp b/toolchain/sem_ir/inst_fingerprinter.cpp index 11dfaf8edd07..1508afc4e7e8 100644 --- a/toolchain/sem_ir/inst_fingerprinter.cpp +++ b/toolchain/sem_ir/inst_fingerprinter.cpp @@ -250,6 +250,16 @@ struct Worklist { Add(sem_ir->floats().Get(float_id).bitcastToAPInt()); } + auto Add(PackageNameId package_id) -> void { + if (auto ident_id = package_id.AsIdentifierId(); ident_id.has_value()) { + AddString(sem_ir->identifiers().Get(ident_id)); + } else { + // TODO: May collide with a user package of the same name. Consider using + // a different value. + AddString(package_id.AsSpecialName()); + } + } + auto Add(LibraryNameId lib_name_id) -> void { if (lib_name_id == LibraryNameId::Default) { AddString(""); diff --git a/toolchain/sem_ir/inst_namer.cpp b/toolchain/sem_ir/inst_namer.cpp index d162630db4bc..4f8250c2bb5f 100644 --- a/toolchain/sem_ir/inst_namer.cpp +++ b/toolchain/sem_ir/inst_namer.cpp @@ -723,10 +723,11 @@ auto InstNamer::CollectNamesInBlock(ScopeId top_scope_id, sem_ir_->import_ir_insts().Get(inst.import_ir_inst_id); const auto& import_ir = *sem_ir_->import_irs().Get(import_ir_inst.ir_id).sem_ir; - if (import_ir.package_id().has_value()) { - out << import_ir.identifiers().Get(import_ir.package_id()); + auto package_id = import_ir.package_id(); + if (auto ident_id = package_id.AsIdentifierId(); ident_id.has_value()) { + out << import_ir.identifiers().Get(ident_id); } else { - out << "Main"; + out << package_id.AsSpecialName(); } out << "."; diff --git a/toolchain/sem_ir/name.cpp b/toolchain/sem_ir/name.cpp index 97000ef29fd7..497c7aec85ef 100644 --- a/toolchain/sem_ir/name.cpp +++ b/toolchain/sem_ir/name.cpp @@ -13,18 +13,20 @@ static auto GetSpecialName(NameId name_id, bool for_ir) -> llvm::StringRef { switch (name_id.index) { case NameId::None.index: return for_ir ? "" : ""; - case NameId::SelfValue.index: - return "self"; - case NameId::SelfType.index: - return "Self"; + case NameId::Base.index: + return "base"; + case NameId::Core.index: + return "Core"; case NameId::PeriodSelf.index: return ".Self"; case NameId::ReturnSlot.index: return for_ir ? "return" : ""; case NameId::PackageNamespace.index: return "package"; - case NameId::Base.index: - return "base"; + case NameId::SelfType.index: + return "Self"; + case NameId::SelfValue.index: + return "self"; case NameId::Vptr.index: return for_ir ? "vptr" : ""; default: diff --git a/toolchain/sem_ir/name_scope.cpp b/toolchain/sem_ir/name_scope.cpp index 32ca2ba945b5..c2b277a941d7 100644 --- a/toolchain/sem_ir/name_scope.cpp +++ b/toolchain/sem_ir/name_scope.cpp @@ -91,9 +91,7 @@ auto NameScopeStore::IsCorePackage(NameScopeId scope_id) const -> bool { if (!IsPackage(scope_id)) { return false; } - auto scope_name = - file_->names().GetAsStringIfIdentifier(Get(scope_id).name_id()); - return scope_name == "Core"; + return Get(scope_id).name_id() == NameId::Core; } } // namespace Carbon::SemIR