From 4850e6c468aff6f5810d66747be18ddbc5af0799 Mon Sep 17 00:00:00 2001 From: Christoph Burgdorf Date: Wed, 16 Nov 2022 10:23:53 +0100 Subject: [PATCH] Disallow importing private type via `use` --- crates/analyzer/src/db/queries/module.rs | 8 +++ .../snapshots/analysis__basic_ingot.snap | 4 +- .../snapshots/errors__bad_visibility.snap | 66 ++++++++++++++++--- .../errors__emittable_not_implementable.snap | 6 ++ .../compile_errors/bad_ingot/src/biz/bad.fe | 4 +- .../compile_errors/bad_visibility/src/foo.fe | 5 ++ .../compile_errors/bad_visibility/src/main.fe | 4 ++ .../ingots/basic_ingot/src/ding/dang.fe | 2 +- .../ingots/visibility_ingot/src/foo.fe | 2 +- newsfragments/815.bugfix.md | 5 ++ 10 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 newsfragments/815.bugfix.md diff --git a/crates/analyzer/src/db/queries/module.rs b/crates/analyzer/src/db/queries/module.rs index 3e35f45027..723d516195 100644 --- a/crates/analyzer/src/db/queries/module.rs +++ b/crates/analyzer/src/db/queries/module.rs @@ -443,6 +443,14 @@ pub fn module_used_item_map( diagnostics.extend(items.diagnostics.iter().cloned()); for (name, (name_span, item)) in items.value.iter() { + if !item.is_public(db) { + diagnostics.push(errors::error( + &format!("{} {} is private", item.item_kind_display_name(), name,), + *name_span, + name.as_str(), + )); + } + if let Some((other_name_span, other_item)) = accum.insert(name.clone(), (*name_span, *item)) { diff --git a/crates/analyzer/tests/snapshots/analysis__basic_ingot.snap b/crates/analyzer/tests/snapshots/analysis__basic_ingot.snap index ef2b7b4085..b19ea7d909 100644 --- a/crates/analyzer/tests/snapshots/analysis__basic_ingot.snap +++ b/crates/analyzer/tests/snapshots/analysis__basic_ingot.snap @@ -313,8 +313,8 @@ note: note: ┌─ ingots/basic_ingot/src/ding/dang.fe:1:1 │ -1 │ type Dang = Array - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Array +1 │ pub type Dang = Array + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Array note: diff --git a/crates/analyzer/tests/snapshots/errors__bad_visibility.snap b/crates/analyzer/tests/snapshots/errors__bad_visibility.snap index 25663d9fe7..91343304c1 100644 --- a/crates/analyzer/tests/snapshots/errors__bad_visibility.snap +++ b/crates/analyzer/tests/snapshots/errors__bad_visibility.snap @@ -3,11 +3,47 @@ source: crates/analyzer/tests/errors.rs expression: error_string_ingot(&path) --- -error: unresolved path item +error: type MyInt is private + ┌─ compile_errors/bad_visibility/src/main.fe:1:11 + │ +1 │ use foo::{MyInt, MY_CONST, MyStruct, MyTrait, my_func, MyContract, MyEnum } + │ ^^^^^ MyInt + +error: constant MY_CONST is private + ┌─ compile_errors/bad_visibility/src/main.fe:1:18 + │ +1 │ use foo::{MyInt, MY_CONST, MyStruct, MyTrait, my_func, MyContract, MyEnum } + │ ^^^^^^^^ MY_CONST + +error: struct MyStruct is private + ┌─ compile_errors/bad_visibility/src/main.fe:1:28 + │ +1 │ use foo::{MyInt, MY_CONST, MyStruct, MyTrait, my_func, MyContract, MyEnum } + │ ^^^^^^^^ MyStruct + +error: trait MyTrait is private + ┌─ compile_errors/bad_visibility/src/main.fe:1:38 + │ +1 │ use foo::{MyInt, MY_CONST, MyStruct, MyTrait, my_func, MyContract, MyEnum } + │ ^^^^^^^ MyTrait + +error: function my_func is private + ┌─ compile_errors/bad_visibility/src/main.fe:1:47 + │ +1 │ use foo::{MyInt, MY_CONST, MyStruct, MyTrait, my_func, MyContract, MyEnum } + │ ^^^^^^^ my_func + +error: type MyContract is private + ┌─ compile_errors/bad_visibility/src/main.fe:1:56 + │ +1 │ use foo::{MyInt, MY_CONST, MyStruct, MyTrait, my_func, MyContract, MyEnum } + │ ^^^^^^^^^^ MyContract + +error: type MyEnum is private ┌─ compile_errors/bad_visibility/src/main.fe:1:68 │ 1 │ use foo::{MyInt, MY_CONST, MyStruct, MyTrait, my_func, MyContract, MyEnum } - │ ^^^^^^ not found + │ ^^^^^^ MyEnum error: the type `MyInt` is private ┌─ compile_errors/bad_visibility/src/main.fe:7:33 @@ -101,10 +137,24 @@ error: the function `my_func` is private = `my_func` can only be used within `foo` = Hint: use `pub` to make `my_func` visible from outside of `foo` -error: the type `MyContract` is private +error: the type `MyEnum` is private ┌─ compile_errors/bad_visibility/src/main.fe:25:16 │ -25 │ let _: MyContract = MyContract(addr) +25 │ let e: MyEnum = MyEnum::Some + │ ^^^^^^ this type is not `pub` + │ + ┌─ compile_errors/bad_visibility/src/foo.fe:17:6 + │ +17 │ enum MyEnum { + │ ------ `MyEnum` is defined here + │ + = `MyEnum` can only be used within `foo` + = Hint: use `pub` to make `MyEnum` visible from outside of `foo` + +error: the type `MyContract` is private + ┌─ compile_errors/bad_visibility/src/main.fe:29:16 + │ +29 │ let _: MyContract = MyContract(addr) │ ^^^^^^^^^^ this type is not `pub` │ ┌─ compile_errors/bad_visibility/src/foo.fe:13:10 @@ -116,9 +166,9 @@ error: the type `MyContract` is private = Hint: use `pub` to make `MyContract` visible from outside of `foo` error: the type `MyContract` is private - ┌─ compile_errors/bad_visibility/src/main.fe:25:29 + ┌─ compile_errors/bad_visibility/src/main.fe:29:29 │ -25 │ let _: MyContract = MyContract(addr) +29 │ let _: MyContract = MyContract(addr) │ ^^^^^^^^^^ this type is not `pub` │ ┌─ compile_errors/bad_visibility/src/foo.fe:13:10 @@ -130,9 +180,9 @@ error: the type `MyContract` is private = Hint: use `pub` to make `MyContract` visible from outside of `foo` error: the type `MyContract` is private - ┌─ compile_errors/bad_visibility/src/main.fe:26:9 + ┌─ compile_errors/bad_visibility/src/main.fe:30:9 │ -26 │ MyContract.create(ctx, 1) +30 │ MyContract.create(ctx, 1) │ ^^^^^^^^^^ this type is not `pub` │ ┌─ compile_errors/bad_visibility/src/foo.fe:13:10 diff --git a/crates/analyzer/tests/snapshots/errors__emittable_not_implementable.snap b/crates/analyzer/tests/snapshots/errors__emittable_not_implementable.snap index 44f3cee7b5..2e1b9f098d 100644 --- a/crates/analyzer/tests/snapshots/errors__emittable_not_implementable.snap +++ b/crates/analyzer/tests/snapshots/errors__emittable_not_implementable.snap @@ -3,6 +3,12 @@ source: crates/analyzer/tests/errors.rs expression: "error_string(&path, test_files::fixture(path))" --- +error: struct OutOfReachMarker is private + ┌─ compile_errors/emittable_not_implementable.fe:1:31 + │ +1 │ use std::context::{Emittable, OutOfReachMarker} + │ ^^^^^^^^^^^^^^^^ OutOfReachMarker + error: the struct `OutOfReachMarker` is private ┌─ compile_errors/emittable_not_implementable.fe:6:24 │ diff --git a/crates/test-files/fixtures/compile_errors/bad_ingot/src/biz/bad.fe b/crates/test-files/fixtures/compile_errors/bad_ingot/src/biz/bad.fe index 0eb4b24e59..f9563fce44 100644 --- a/crates/test-files/fixtures/compile_errors/bad_ingot/src/biz/bad.fe +++ b/crates/test-files/fixtures/compile_errors/bad_ingot/src/biz/bad.fe @@ -1,3 +1,3 @@ -struct Bur {} +pub struct Bur {} -struct Bud {} +pub struct Bud {} diff --git a/crates/test-files/fixtures/compile_errors/bad_visibility/src/foo.fe b/crates/test-files/fixtures/compile_errors/bad_visibility/src/foo.fe index ba7a7d21b3..7b7d85f843 100644 --- a/crates/test-files/fixtures/compile_errors/bad_visibility/src/foo.fe +++ b/crates/test-files/fixtures/compile_errors/bad_visibility/src/foo.fe @@ -12,4 +12,9 @@ fn my_func() {} contract MyContract { x: i32 +} + +enum MyEnum { + Some + Thing } \ No newline at end of file diff --git a/crates/test-files/fixtures/compile_errors/bad_visibility/src/main.fe b/crates/test-files/fixtures/compile_errors/bad_visibility/src/main.fe index 44dafa5941..449571d6d1 100644 --- a/crates/test-files/fixtures/compile_errors/bad_visibility/src/main.fe +++ b/crates/test-files/fixtures/compile_errors/bad_visibility/src/main.fe @@ -21,6 +21,10 @@ contract Main { my_func() } + pub fn priv_enum() { + let e: MyEnum = MyEnum::Some + } + pub fn priv_contract(ctx: Context, addr: address) { let _: MyContract = MyContract(addr) MyContract.create(ctx, 1) diff --git a/crates/test-files/fixtures/ingots/basic_ingot/src/ding/dang.fe b/crates/test-files/fixtures/ingots/basic_ingot/src/ding/dang.fe index 9d3f08aae1..118bf499ff 100644 --- a/crates/test-files/fixtures/ingots/basic_ingot/src/ding/dang.fe +++ b/crates/test-files/fixtures/ingots/basic_ingot/src/ding/dang.fe @@ -1 +1 @@ -type Dang = Array +pub type Dang = Array diff --git a/crates/test-files/fixtures/ingots/visibility_ingot/src/foo.fe b/crates/test-files/fixtures/ingots/visibility_ingot/src/foo.fe index 9cc700fffd..720ba0899f 100644 --- a/crates/test-files/fixtures/ingots/visibility_ingot/src/foo.fe +++ b/crates/test-files/fixtures/ingots/visibility_ingot/src/foo.fe @@ -2,7 +2,7 @@ pub struct Bing { pub my_address: address } -fn get_42_backend() -> u256 { +pub fn get_42_backend() -> u256 { return 42 } diff --git a/newsfragments/815.bugfix.md b/newsfragments/815.bugfix.md new file mode 100644 index 0000000000..2ae72dd6b8 --- /dev/null +++ b/newsfragments/815.bugfix.md @@ -0,0 +1,5 @@ +Disallow importing private type via `use` + +The following was previously allowed but will now error: + +`use foo::PrivateStruct`