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:
commit
3db335b934
7 changed files with 83 additions and 14 deletions
|
@ -995,7 +995,20 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
|||
// Record some extra data for better diagnostics.
|
||||
let cstore = self.r.cstore();
|
||||
match res {
|
||||
Res::Def(DefKind::Struct | DefKind::Union, def_id) => {
|
||||
Res::Def(DefKind::Struct, def_id) => {
|
||||
let field_names = cstore.struct_field_names_untracked(def_id, self.r.session);
|
||||
let ctor = cstore.ctor_def_id_and_kind_untracked(def_id);
|
||||
if let Some((ctor_def_id, ctor_kind)) = ctor {
|
||||
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
|
||||
let ctor_vis = cstore.visibility_untracked(ctor_def_id);
|
||||
let field_visibilities = cstore.struct_field_visibilities_untracked(def_id);
|
||||
self.r
|
||||
.struct_constructors
|
||||
.insert(def_id, (ctor_res, ctor_vis, field_visibilities));
|
||||
}
|
||||
self.insert_field_names(def_id, field_names);
|
||||
}
|
||||
Res::Def(DefKind::Union, def_id) => {
|
||||
let field_names = cstore.struct_field_names_untracked(def_id, self.r.session);
|
||||
self.insert_field_names(def_id, field_names);
|
||||
}
|
||||
|
@ -1007,12 +1020,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
|||
self.r.has_self.insert(def_id);
|
||||
}
|
||||
}
|
||||
Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
|
||||
let parent = cstore.def_key(def_id).parent;
|
||||
if let Some(struct_def_id) = parent.map(|index| DefId { index, ..def_id }) {
|
||||
self.r.struct_constructors.insert(struct_def_id, (res, vis, vec![]));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue