Skip to content

Add more privacy checks #108610

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions compiler/rustc_privacy/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ pub struct InPublicInterface<'a> {
pub vis_span: Span,
}

// Duplicate of `InPublicInterface` but with a different error code, shares the same slug.
#[derive(Diagnostic)]
#[diag(privacy_in_public_interface)]
pub struct WarnInPublicInterfaceTraits<'a> {
#[primary_span]
#[label]
pub span: Span,
pub vis_descr: &'static str,
pub kind: &'a str,
pub descr: DiagnosticArgFromDisplay<'a>,
#[label(privacy_visibility_label)]
pub vis_span: Span,
}

#[derive(Diagnostic)]
#[diag(privacy_report_effective_visibility)]
pub struct ReportEffectiveVisibility {
Expand Down
89 changes: 69 additions & 20 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use std::{cmp, fmt, mem};
use errors::{
FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface,
InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportEffectiveVisibility,
UnnamedItemIsPrivate,
UnnamedItemIsPrivate, WarnInPublicInterfaceTraits,
};

fluent_messages! { "../locales/en-US.ftl" }
Expand Down Expand Up @@ -1753,6 +1753,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
required_visibility: ty::Visibility,
has_old_errors: bool,
in_assoc_ty: bool,
in_trait_impl: bool,
}

impl SearchInterfaceForPrivateItemsVisitor<'_> {
Expand Down Expand Up @@ -1817,10 +1818,24 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
};

let vis = self.tcx.local_visibility(local_def_id);
if !vis.is_at_least(self.required_visibility, self.tcx) {
let is_a_trait = matches!(self.tcx.def_kind(local_def_id), DefKind::Trait);
let vis_at_least = vis.is_at_least(self.required_visibility, self.tcx);
let is_exported = if !vis_at_least {
true
} else if self.tcx.entry_fn(()).is_none() {
// If this is not a binary, it's an issue to have a private item in a public API.
let visibilities = self.tcx.effective_visibilities(());
is_a_trait
|| self.in_trait_impl
|| !visibilities.is_exported(self.item_def_id)
|| visibilities.is_exported(local_def_id)
} else {
true
};
if !vis_at_least || !is_exported {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
let vis_descr = match vis {
ty::Visibility::Public => "public",
ty::Visibility::Public => "public but not reexported",
ty::Visibility::Restricted(vis_def_id) => {
if vis_def_id == self.tcx.parent_module(hir_id) {
"private"
Expand All @@ -1838,21 +1853,49 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
{
let vis_span = self.tcx.def_span(def_id);
if kind == "trait" {
self.tcx.sess.emit_err(InPublicInterfaceTraits {
span,
vis_descr,
kind,
descr: descr.into(),
vis_span,
});
if vis == ty::Visibility::Public {
let (vis_descr, descr) = rustc_middle::ty::print::with_no_trimmed_paths!((
vis_descr.into(),
descr.into()
));
self.tcx.sess.emit_warning(WarnInPublicInterfaceTraits {
span,
vis_descr,
kind,
descr,
vis_span,
});
} else {
self.tcx.sess.emit_err(InPublicInterfaceTraits {
span,
vis_descr,
kind,
descr: descr.into(),
vis_span,
});
}
} else {
self.tcx.sess.emit_err(InPublicInterface {
span,
vis_descr,
kind,
descr: descr.into(),
vis_span,
});
if vis == ty::Visibility::Public {
let (vis_descr, descr) = rustc_middle::ty::print::with_no_trimmed_paths!((
vis_descr.into(),
descr.into()
));
self.tcx.sess.emit_warning(WarnInPublicInterfaceTraits {
span,
vis_descr,
kind,
descr,
vis_span,
});
} else {
self.tcx.sess.emit_err(InPublicInterface {
span,
vis_descr,
kind,
descr: descr.into(),
vis_span,
});
}
}
} else {
self.tcx.emit_spanned_lint(
Expand Down Expand Up @@ -1900,6 +1943,7 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
struct PrivateItemsInPublicInterfacesChecker<'tcx> {
tcx: TyCtxt<'tcx>,
old_error_set_ancestry: HirIdSet,
in_trait_impl: bool,
}

impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
Expand All @@ -1916,6 +1960,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
.old_error_set_ancestry
.contains(&self.tcx.hir().local_def_id_to_hir_id(def_id)),
in_assoc_ty: false,
in_trait_impl: self.in_trait_impl,
}
}

Expand Down Expand Up @@ -2022,11 +2067,13 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
if let hir::ItemKind::Impl(ref impl_) = item.kind {
let impl_vis =
ty::Visibility::of_impl(item.owner_id.def_id, tcx, &Default::default());
// check that private components do not appear in the generics or predicates of inherent impls
// this check is intentionally NOT performed for impls of traits, per #90586
// check that private components do not appear in the generics or predicates of
// inherent impls this check is intentionally NOT performed for impls of traits,
// per #90586
if impl_.of_trait.is_none() {
self.check(item.owner_id.def_id, impl_vis).generics().predicates();
}
self.in_trait_impl = impl_.of_trait.is_some();
for impl_item_ref in impl_.items {
let impl_item_vis = if impl_.of_trait.is_none() {
min(
Expand All @@ -2043,6 +2090,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
impl_item_vis,
);
}
self.in_trait_impl = false;
}
}
_ => {}
Expand Down Expand Up @@ -2180,7 +2228,8 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
}

// Check for private types and traits in public interfaces.
let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, old_error_set_ancestry };
let mut checker =
PrivateItemsInPublicInterfacesChecker { tcx, old_error_set_ancestry, in_trait_impl: false };

for id in tcx.hir().items() {
checker.check_item(id);
Expand Down
7 changes: 5 additions & 2 deletions library/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ mod tests;
use crate::any::{Demand, Provider, TypeId};
use crate::fmt::{Debug, Display};

#[doc(hidden)]
pub use private::Internal;

/// `Error` is a trait representing the basic expectations for error values,
/// i.e., values of type `E` in [`Result<T, E>`].
///
Expand Down Expand Up @@ -205,8 +208,8 @@ where
}

mod private {
// This is a hack to prevent `type_id` from being overridden by `Error`
// implementations, since that can enable unsound downcasting.
/// This is a hack to prevent `type_id` from being overridden by `Error`
/// implementations, since that can enable unsound downcasting.
#[unstable(feature = "error_type_id", issue = "60784")]
#[derive(Debug)]
pub struct Internal;
Expand Down
7 changes: 7 additions & 0 deletions library/core/src/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,13 @@ pub use self::range::Step;
reason = "generators are unstable"
)]
pub use self::sources::from_generator;
#[unstable(
feature = "iter_from_generator",
issue = "43122",
reason = "generators are unstable"
)]
#[doc(hidden)]
pub use self::sources::FromGenerator;
#[stable(feature = "iter_empty", since = "1.2.0")]
pub use self::sources::{empty, Empty};
#[stable(feature = "iter_from_fn", since = "1.34.0")]
Expand Down
7 changes: 7 additions & 0 deletions library/core/src/iter/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ pub use self::from_fn::{from_fn, FromFn};
reason = "generators are unstable"
)]
pub use self::from_generator::from_generator;
#[unstable(
feature = "iter_from_generator",
issue = "43122",
reason = "generators are unstable"
)]
#[doc(hidden)]
pub use self::from_generator::FromGenerator;

#[stable(feature = "iter_successors", since = "1.34.0")]
pub use self::successors::{successors, Successors};
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/num/dec2flt/lemire.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Implementation of the Eisel-Lemire algorithm.

use crate::num::dec2flt::common::BiasedFp;
#[doc(hidden)]
pub use crate::num::dec2flt::common::BiasedFp;
use crate::num::dec2flt::float::RawFloat;
use crate::num::dec2flt::table::{
LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE,
Expand Down
1 change: 1 addition & 0 deletions library/core/src/str/lossy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ impl<'a> Utf8Chunk<'a> {
}
}

/// Utility struct for debug printing `Utf8Chunks`.
#[must_use]
#[unstable(feature = "str_internals", issue = "none")]
pub struct Debug<'a>(&'a [u8]);
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub mod pattern;

mod lossy;
#[unstable(feature = "utf8_chunks", issue = "99543")]
#[doc(hidden)]
pub use lossy::Debug;
#[unstable(feature = "utf8_chunks", issue = "99543")]
pub use lossy::{Utf8Chunk, Utf8Chunks};

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
11 changes: 11 additions & 0 deletions library/portable-simd/crates/core_simd/src/masks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ where
}
}

#[cfg(not(all(target_arch = "x86_64", target_feature = "avx512f")))]
impl<T, const LANES: usize> core::convert::From<Mask<T, LANES>> for Simd<T, LANES>
where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
fn from(value: Mask<T, LANES>) -> Self {
value.0.0
}
}

impl<T, const LANES: usize> Mask<T, LANES>
where
T: MaskElement,
Expand Down
12 changes: 1 addition & 11 deletions library/portable-simd/crates/core_simd/src/masks/full_masks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::simd::{LaneCount, Simd, SupportedLaneCount, ToBitMask};
use crate::simd::ToBitMaskArray;

#[repr(transparent)]
pub struct Mask<T, const LANES: usize>(Simd<T, LANES>)
pub struct Mask<T, const LANES: usize>(pub(super) Simd<T, LANES>)
where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount;
Expand Down Expand Up @@ -257,16 +257,6 @@ where
}
}

impl<T, const LANES: usize> core::convert::From<Mask<T, LANES>> for Simd<T, LANES>
where
T: MaskElement,
LaneCount<LANES>: SupportedLaneCount,
{
fn from(value: Mask<T, LANES>) -> Self {
value.0
}
}

impl<T, const LANES: usize> core::ops::BitAnd for Mask<T, LANES>
where
T: MaskElement,
Expand Down
3 changes: 2 additions & 1 deletion library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ pub mod server;
#[allow(unsafe_code)]
mod symbol;

use buffer::Buffer;
#[doc(hidden)]
pub use buffer::Buffer;
pub use rpc::PanicMessage;
use rpc::{Decode, DecodeMut, Encode, Reader, Writer};

Expand Down
3 changes: 3 additions & 0 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ pub mod bridge;

mod diagnostic;

#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
#[doc(hidden)]
pub use diagnostic::Children;
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub use diagnostic::{Diagnostic, Level, MultiSpan};

Expand Down
4 changes: 2 additions & 2 deletions library/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
// Public reexports
pub use self::bench::{black_box, Bencher};
pub use self::console::run_tests_console;
pub use self::event::{CompletedTest, TestEvent};
pub use self::options::{ColorConfig, Options, OutputFormat, RunIgnored, ShouldPanic};
pub use self::types::TestName::*;
pub use self::types::*;
Expand All @@ -43,7 +44,7 @@ pub mod test {
options::{Options, RunIgnored, RunStrategy, ShouldPanic},
run_test, test_main, test_main_static,
test_result::{TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk},
time::{TestExecTime, TestTimeOptions},
time::{TestExecTime, TestTimeOptions, TimeThreshold},
types::{
DynTestFn, DynTestName, StaticBenchFn, StaticTestFn, StaticTestName, TestDesc,
TestDescAndFn, TestId, TestName, TestType,
Expand Down Expand Up @@ -81,7 +82,6 @@ mod types;
mod tests;

use core::any::Any;
use event::{CompletedTest, TestEvent};
use helpers::concurrency::get_concurrency;
use helpers::exit_code::get_exit_code;
use helpers::shuffle::{get_shuffle_seed, shuffle_tests};
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/issues/auxiliary/issue-14421.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
#![deny(warnings)]
#![allow(dead_code)]

pub use src::aliases::B;
pub use src::aliases::{A, B};
pub use src::hidden_core::make;

mod src {
pub mod aliases {
use super::hidden_core::A;
pub use super::hidden_core::A;
pub type B = A<f32>;
}

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/issues/auxiliary/issue-14422.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#![crate_type="lib"]
#![deny(warnings)]

pub use src::aliases::B;
pub use src::aliases::{A, B};
pub use src::hidden_core::make;

mod src {
pub mod aliases {
use super::hidden_core::A;
pub use super::hidden_core::A;
pub type B = A;
}

Expand Down
Loading