diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-04-14 17:49:26 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-04-14 17:49:26 +0200 |
| commit | 9506f62a7ab10629f10926f2bad8bd7e78e755a8 (patch) | |
| tree | 611ef7727c62cd6efd63a47d08d6a7d8b761e802 | |
| parent | 271eb8fc5a420280937bb1745f1e7aee7901ad26 (diff) | |
| parent | dbc7042bfe690d55cbcd40e75851efd8af9bb34e (diff) | |
| download | rust-9506f62a7ab10629f10926f2bad8bd7e78e755a8.tar.gz rust-9506f62a7ab10629f10926f2bad8bd7e78e755a8.zip | |
Rollup merge of #59936 - petrochenkov:confict, r=davidtwco
Fix cross-crate visibility of fictive variant constructors After merging https://github.com/rust-lang/rust/pull/59376 I realized that the code in the decoder wasn't entirely correct - we "decoded" fictive variant constructors with their variant's visibility, which could be public, rather than demoted to `pub(crate)`. Fictive constructors are not directly usable in expression/patterns, but the effect still can be observed with imports. r? @davidtwco
| -rw-r--r-- | src/librustc_metadata/decoder.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs | 12 |
2 files changed, 24 insertions, 1 deletions
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index f7ea67ef349..5dade8d9438 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -831,7 +831,18 @@ impl<'a, 'tcx> CrateMetadata { let ctor_def_id = self.get_ctor_def_id(child_index).unwrap_or(def_id); let ctor_kind = self.get_ctor_kind(child_index); let ctor_def = Def::Ctor(ctor_def_id, CtorOf::Variant, ctor_kind); - let vis = self.get_visibility(ctor_def_id.index); + let mut vis = self.get_visibility(ctor_def_id.index); + if ctor_def_id == def_id && vis == ty::Visibility::Public { + // For non-exhaustive variants lower the constructor visibility to + // within the crate. We only need this for fictive constructors, + // for other constructors correct visibilities + // were already encoded in metadata. + let attrs = self.get_item_attrs(def_id.index, sess); + if attr::contains_name(&attrs, "non_exhaustive") { + let crate_def_id = DefId { index: CRATE_DEF_INDEX, ..def_id }; + vis = ty::Visibility::Restricted(crate_def_id); + } + } callback(def::Export { def: ctor_def, ident, vis, span }); } _ => {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs new file mode 100644 index 00000000000..62f6e4463f9 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs @@ -0,0 +1,12 @@ +// compile-pass +// aux-build:variants.rs + +extern crate variants; + +const S: u8 = 0; + +// OK, `Struct` in value namespace is crate-private, so it's filtered away +// and there's no conflict with the previously defined `const S`. +use variants::NonExhaustiveVariants::Struct as S; + +fn main() {} |
