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 <jperkins@google.com>
This commit is contained in:
Richard Smith
2025-02-11 21:33:57 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 50b3c825e4
commit 8eb4e24cb6
62 changed files with 935 additions and 487 deletions
+16 -13
View File
@@ -27,13 +27,18 @@ using ImportKey = std::pair<llvm::StringRef, llvm::StringRef>;
// 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<ImportKey, UnitAndImports*>& 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<Unit> 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<Unit> 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);
}