Rollup merge of #85068 - luqmana:78708-xcrate-diag, r=estebank

Fix diagnostic for cross crate private tuple struct constructors

Fixes #78708.

There was already some limited support for certain cross-crate scenarios but that didn't handle a tuple struct rexported from an inner module for example (e.g. the NonZero* types as seen in #85049).

```Rust
➜  cat bug.rs
fn main() {
    let _x = std::num::NonZeroU32(12);
    let n = std::num::NonZeroU32::new(1).unwrap();
    match n {
        std::num::NonZeroU32(i) => {},
    }
}
```

**Before:**
<details>

```Rust
➜  rustc +nightly bug.rs
error[E0423]: expected function, tuple struct or tuple variant, found struct `std::num::NonZeroU32`
   --> bug.rs:2:14
    |
2   |       let _x = std::num::NonZeroU32(12);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `std::num::NonZeroU32 { 0: val }`
    |
   ::: /home/luqman/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/nonzero.rs:148:1
[snip]
error[E0532]: expected tuple struct or tuple variant, found struct `std::num::NonZeroU32`
   --> bug.rs:5:9
    |
5   |           std::num::NonZeroU32(i) => {},
    |           ^^^^^^^^^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `std::num::NonZeroU32 { 0 }`
    |
   ::: /home/luqman/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/nonzero.rs:148:1
[snip]

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0423, E0532.
For more information about an error, try `rustc --explain E0423`.
```
</details>

**After:**
<details>

```Rust
➜  /rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc bug.rs
error[E0423]: cannot initialize a tuple struct which contains private fields
   --> bug.rs:2:14
    |
2   |     let _x = std::num::NonZeroU32(12);
    |              ^^^^^^^^^^^^^^^^^^^^
    |
note: constructor is not visible here due to private fields
   --> /rust/library/core/src/num/nonzero.rs:148:1
[snip]
error[E0532]: cannot match against a tuple struct which contains private fields
 --> bug.rs:5:9
  |
5 |         std::num::NonZeroU32(i) => {},
  |         ^^^^^^^^^^^^^^^^^^^^
  |
note: constructor is not visible here due to private fields
 --> bug.rs:5:30
  |
5 |         std::num::NonZeroU32(i) => {},
  |                              ^ private field

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0423, E0532.
For more information about an error, try `rustc --explain E0423`.
```
</details>

One question is if we should only collect the needed info for the cross-crate case after encountering an error instead of always doing it. Perf run perhaps to gauge the impact.
This commit is contained in:
Guillaume Gomez 2021-05-13 15:54:10 +02:00 committed by GitHub
commit 3db335b934
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 83 additions and 14 deletions

View file

@ -3,3 +3,15 @@ pub struct Bar(pub u8, u8, u8);
pub fn make_bar() -> Bar {
Bar(1, 12, 10)
}
mod inner {
pub struct Foo(u8, pub u8, u8);
impl Foo {
pub fn new() -> Foo {
Foo(1, 12, 10)
}
}
}
pub use inner::Foo;

View file

@ -3,9 +3,12 @@
extern crate issue_75907 as a;
use a::{make_bar, Bar};
use a::{make_bar, Bar, Foo};
fn main() {
let Bar(x, y, z) = make_bar();
//~^ ERROR cannot match against a tuple struct which contains private fields
let Foo(x, y, z) = Foo::new();
//~^ ERROR cannot match against a tuple struct which contains private fields
}

View file

@ -2,8 +2,30 @@ error[E0532]: cannot match against a tuple struct which contains private fields
--> $DIR/issue-75907_b.rs:9:9
|
LL | let Bar(x, y, z) = make_bar();
| ^^^ constructor is not visible here due to private fields
| ^^^
|
note: constructor is not visible here due to private fields
--> $DIR/issue-75907_b.rs:9:16
|
LL | let Bar(x, y, z) = make_bar();
| ^ ^ private field
| |
| private field
error: aborting due to previous error
error[E0532]: cannot match against a tuple struct which contains private fields
--> $DIR/issue-75907_b.rs:12:9
|
LL | let Foo(x, y, z) = Foo::new();
| ^^^
|
note: constructor is not visible here due to private fields
--> $DIR/issue-75907_b.rs:12:13
|
LL | let Foo(x, y, z) = Foo::new();
| ^ ^ private field
| |
| private field
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0532`.

View file

@ -2,7 +2,7 @@ error[E0423]: cannot initialize a tuple struct which contains private fields
--> $DIR/struct.rs:20:14
|
LL | let ts = TupleStruct(640, 480);
| ^^^^^^^^^^^ constructor is not visible here due to private fields
| ^^^^^^^^^^^
error[E0423]: expected value, found struct `UnitStruct`
--> $DIR/struct.rs:29:14