Skip to content

Commit

Permalink
Restrict the Cpp package name (#4618)
Browse files Browse the repository at this point in the history
We're looking at using this for imports, and it gets awkward if we allow
users to declare entries.
  • Loading branch information
jonmeow authored Dec 3, 2024
1 parent 7005f39 commit 48a84ca
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 111 deletions.
21 changes: 16 additions & 5 deletions toolchain/check/check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,11 +545,12 @@ static auto GetImportKey(UnitInfo& unit_info, IdentifierId file_package_id,
return {package_name, library_name};
}

static constexpr llvm::StringLiteral ExplicitMainName = "Main";
static constexpr llvm::StringLiteral CppPackageName = "Cpp";
static constexpr llvm::StringLiteral MainPackageName = "Main";

static auto RenderImportKey(ImportKey import_key) -> std::string {
if (import_key.first.empty()) {
import_key.first = ExplicitMainName;
import_key.first = MainPackageName;
}
if (import_key.second.empty()) {
return import_key.first.str();
Expand All @@ -573,7 +574,7 @@ static auto TrackImport(Map<ImportKey, UnitInfo*>& api_map,

// True if the import has `Main` as the package name, even if it comes from
// the file's packaging (diagnostics may differentiate).
bool is_explicit_main = import_key.first == ExplicitMainName;
bool is_explicit_main = import_key.first == MainPackageName;

// Explicit imports need more validation than implicit ones. We try to do
// these in an order of imports that should be removed, followed by imports
Expand Down Expand Up @@ -688,6 +689,11 @@ static auto TrackImport(Map<ImportKey, UnitInfo*>& api_map,
} else {
// The imported api is missing.
package_imports.has_load_error = true;
if (!explicit_import_map && import_key.first == CppPackageName) {
// Don't diagnose the implicit import in `impl package Cpp`, because we'll
// have diagnosed the use of `Cpp` in the declaration.
return;
}
CARBON_DIAGNOSTIC(LibraryApiNotFound, Error,
"corresponding API for '{0}' not found", std::string);
CARBON_DIAGNOSTIC(ImportNotFound, Error, "imported API '{0}' not found",
Expand All @@ -714,9 +720,9 @@ static auto BuildApiMapAndDiagnosePackaging(
// Construct a boring key for Main//default.
: ImportKey{"", ""};

// Diagnose explicit `Main` uses before they become marked as possible
// Diagnose restricted package names before they become marked as possible
// APIs.
if (import_key.first == ExplicitMainName) {
if (import_key.first == MainPackageName) {
CARBON_DIAGNOSTIC(ExplicitMainPackage, Error,
"`Main//default` must omit `package` declaration");
CARBON_DIAGNOSTIC(
Expand All @@ -726,6 +732,11 @@ static auto BuildApiMapAndDiagnosePackaging(
import_key.second.empty() ? ExplicitMainPackage
: ExplicitMainLibrary);
continue;
} else if (import_key.first == CppPackageName) {
CARBON_DIAGNOSTIC(CppPackageDeclaration, Error,
"`Cpp` cannot be used by a `package` declaration");
unit_info.emitter.Emit(packaging->names.node_id, CppPackageDeclaration);
continue;
}

bool is_impl = packaging && packaging->is_impl;
Expand Down
106 changes: 0 additions & 106 deletions toolchain/check/testdata/packages/fail_package_main.carbon

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// 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/no_prelude/restricted_package_names.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/packages/no_prelude/restricted_package_names.carbon

// --- lowercase_main.carbon

// The restriction is case-sensitive.
package main;

// --- fail_main.carbon

// CHECK:STDERR: fail_main.carbon:[[@LINE+4]]:1: error: `Main//default` must omit `package` declaration [ExplicitMainPackage]
// CHECK:STDERR: package Main;
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
package Main;

// --- fail_main_impl.carbon

// CHECK:STDERR: fail_main_impl.carbon:[[@LINE+4]]:6: error: `Main//default` must omit `package` declaration [ExplicitMainPackage]
// CHECK:STDERR: impl package Main;
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
impl package Main;

// --- fail_raw_main.carbon

// `Main` isn't a keyword, so this fails the same way.
// CHECK:STDERR: fail_raw_main.carbon:[[@LINE+4]]:1: error: `Main//default` must omit `package` declaration [ExplicitMainPackage]
// CHECK:STDERR: package r#Main;
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
package r#Main;

// --- fail_main_lib.carbon

// CHECK:STDERR: fail_main_lib.carbon:[[@LINE+4]]:1: error: use `library` declaration in `Main` package libraries [ExplicitMainLibrary]
// CHECK:STDERR: package Main library "main_lib";
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
package Main library "[[@TEST_NAME]]";

// --- lowercase_cpp.carbon

// The restriction is case-sensitive.
package cpp;

// --- fail_cpp.carbon

// CHECK:STDERR: fail_cpp.carbon:[[@LINE+4]]:1: error: `Cpp` cannot be used by a `package` declaration [CppPackageDeclaration]
// CHECK:STDERR: package Cpp;
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
package Cpp;

// --- fail_cpp.impl.carbon

// CHECK:STDERR: fail_cpp.impl.carbon:[[@LINE+4]]:6: error: `Cpp` cannot be used by a `package` declaration [CppPackageDeclaration]
// CHECK:STDERR: impl package Cpp;
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
impl package Cpp;

// --- fail_raw_cpp.carbon

// `cpp` isn't a keyword, so this fails the same way.
// CHECK:STDERR: fail_raw_cpp.carbon:[[@LINE+4]]:1: error: `Cpp` cannot be used by a `package` declaration [CppPackageDeclaration]
// CHECK:STDERR: package r#Cpp;
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
package r#Cpp;

// --- fail_cpp_lib.carbon

// CHECK:STDERR: fail_cpp_lib.carbon:[[@LINE+3]]:1: error: `Cpp` cannot be used by a `package` declaration [CppPackageDeclaration]
// CHECK:STDERR: package Cpp library "cpp_lib";
// CHECK:STDERR: ^~~~~~~
package Cpp library "[[@TEST_NAME]]";

// CHECK:STDOUT: --- lowercase_main.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_main.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_main_impl.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_raw_main.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_main_lib.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- lowercase_cpp.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_cpp.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_cpp.impl.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: has_error
// CHECK:STDOUT: }
// CHECK:STDOUT: %default.import = import <invalid>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_raw_cpp.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_cpp_lib.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
1 change: 1 addition & 0 deletions toolchain/diagnostics/diagnostic_kind.def
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ CARBON_DIAGNOSTIC_KIND(ImportNotFound)
CARBON_DIAGNOSTIC_KIND(ImportCycleDetected)
CARBON_DIAGNOSTIC_KIND(ExplicitMainPackage)
CARBON_DIAGNOSTIC_KIND(ExplicitMainLibrary)
CARBON_DIAGNOSTIC_KIND(CppPackageDeclaration)
CARBON_DIAGNOSTIC_KIND(ImportMainPackage)
CARBON_DIAGNOSTIC_KIND(ImportMainDefaultLibrary)
CARBON_DIAGNOSTIC_KIND(ImportCurrentPackageByName)
Expand Down

0 comments on commit 48a84ca

Please sign in to comment.