From 8515a7c58c1154dd280844de86db5636920d9004 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 1 Mar 2023 14:42:54 +0100 Subject: [PATCH 1/4] Warn when private items are present in public APIs --- compiler/rustc_privacy/src/errors.rs | 14 +++++ compiler/rustc_privacy/src/lib.rs | 89 +++++++++++++++++++++------- 2 files changed, 83 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 72b53eefa0817..afd53a211581d 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -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 { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 50176c8023288..13181433dbdd4 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -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" } @@ -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<'_> { @@ -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" @@ -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( @@ -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> { @@ -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, } } @@ -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( @@ -2043,6 +2090,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { impl_item_vis, ); } + self.in_trait_impl = false; } } _ => {} @@ -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); From 20ff89fc57365b04095b3bdac0f81bfa791ece72 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 1 Mar 2023 14:43:06 +0100 Subject: [PATCH 2/4] Fix invalid private types in public APIs --- library/core/src/error.rs | 7 +++++-- library/core/src/iter/mod.rs | 7 +++++++ library/core/src/iter/sources.rs | 7 +++++++ library/core/src/num/dec2flt/lemire.rs | 3 ++- library/core/src/str/lossy.rs | 1 + library/core/src/str/mod.rs | 3 +++ library/portable-simd/crates/core_simd/src/masks.rs | 11 +++++++++++ .../crates/core_simd/src/masks/full_masks.rs | 12 +----------- library/proc_macro/src/bridge/mod.rs | 3 ++- library/proc_macro/src/lib.rs | 3 +++ library/test/src/lib.rs | 4 ++-- 11 files changed, 44 insertions(+), 17 deletions(-) diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 571bc4bcfd13d..37c69067a9d22 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -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`]. /// @@ -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; diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs index ae00232c12c8a..7ce6fb67e8bb7 100644 --- a/library/core/src/iter/mod.rs +++ b/library/core/src/iter/mod.rs @@ -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")] diff --git a/library/core/src/iter/sources.rs b/library/core/src/iter/sources.rs index 3ec426a3ad9a1..df286a6d6676a 100644 --- a/library/core/src/iter/sources.rs +++ b/library/core/src/iter/sources.rs @@ -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}; diff --git a/library/core/src/num/dec2flt/lemire.rs b/library/core/src/num/dec2flt/lemire.rs index 9f7594460a1d5..ca56ce2354ee3 100644 --- a/library/core/src/num/dec2flt/lemire.rs +++ b/library/core/src/num/dec2flt/lemire.rs @@ -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, diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs index 59f873d1268ce..f12fca0a128d0 100644 --- a/library/core/src/str/lossy.rs +++ b/library/core/src/str/lossy.rs @@ -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]); diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index ab2f8520ecb33..301ad00d697c8 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -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")] diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs index c36c336d8a216..c38772cebf9e4 100644 --- a/library/portable-simd/crates/core_simd/src/masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks.rs @@ -107,6 +107,17 @@ where } } +#[cfg(not(all(target_arch = "x86_64", target_feature = "avx512f")))] +impl core::convert::From> for Simd +where + T: MaskElement, + LaneCount: SupportedLaneCount, +{ + fn from(value: Mask) -> Self { + value.0.0 + } +} + impl Mask where T: MaskElement, diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs index adf0fcbeae2bd..c8b99a724922c 100644 --- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs @@ -8,7 +8,7 @@ use crate::simd::{LaneCount, Simd, SupportedLaneCount, ToBitMask}; use crate::simd::ToBitMaskArray; #[repr(transparent)] -pub struct Mask(Simd) +pub struct Mask(pub(super) Simd) where T: MaskElement, LaneCount: SupportedLaneCount; @@ -257,16 +257,6 @@ where } } -impl core::convert::From> for Simd -where - T: MaskElement, - LaneCount: SupportedLaneCount, -{ - fn from(value: Mask) -> Self { - value.0 - } -} - impl core::ops::BitAnd for Mask where T: MaskElement, diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 4c1e196b5ad16..dc3c352185961 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -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}; diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 938935771d64e..8c0018dc5992a 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -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}; diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 69fb529d7f563..4e3e872452aef 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -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::*; @@ -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, @@ -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}; From 190dc878b3d6d59a5cb25cd55659130fbc3f168c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 1 Mar 2023 14:43:22 +0100 Subject: [PATCH 3/4] Add new UI test for private types in public APIs --- .../ui/privacy/local-public-in-public-api.rs | 42 +++++++++++++++++++ .../privacy/local-public-in-public-api.stderr | 25 +++++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/ui/privacy/local-public-in-public-api.rs create mode 100644 tests/ui/privacy/local-public-in-public-api.stderr diff --git a/tests/ui/privacy/local-public-in-public-api.rs b/tests/ui/privacy/local-public-in-public-api.rs new file mode 100644 index 0000000000000..9cb0909087107 --- /dev/null +++ b/tests/ui/privacy/local-public-in-public-api.rs @@ -0,0 +1,42 @@ +// This ui test checks that private types present in public APIs get +// a warning. + +#![crate_type = "lib"] +#![deny(private_in_public)] + +mod my_type { + pub struct Field; + pub struct MyType { + pub field: Field, + } + + impl MyType { + pub fn builder() -> MyTypeBuilder { + //~^ ERROR + //~| WARN + MyTypeBuilder { field: Field } + } + + pub fn with_builder(_: MyTypeBuilder) {} + //~^ ERROR + //~| WARN + } + + pub struct MyTypeBuilder { + field: Field, + } + + impl MyTypeBuilder { + pub fn field(mut self, val: Field) -> Self { + self.field = val; + + self + } + + pub fn build(self) -> MyType { + MyType { field: self.field } + } + } +} + +pub use my_type::{MyType, Field}; diff --git a/tests/ui/privacy/local-public-in-public-api.stderr b/tests/ui/privacy/local-public-in-public-api.stderr new file mode 100644 index 0000000000000..a97fc7ee8b79c --- /dev/null +++ b/tests/ui/privacy/local-public-in-public-api.stderr @@ -0,0 +1,25 @@ +error: public but not reexported type `MyTypeBuilder` in public interface (error E0446) + --> $DIR/local-public-in-public-api.rs:14:9 + | +LL | pub fn builder() -> MyTypeBuilder { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 +note: the lint level is defined here + --> $DIR/local-public-in-public-api.rs:5:9 + | +LL | #![deny(private_in_public)] + | ^^^^^^^^^^^^^^^^^ + +error: public but not reexported type `MyTypeBuilder` in public interface (error E0446) + --> $DIR/local-public-in-public-api.rs:20:9 + | +LL | pub fn with_builder(_: MyTypeBuilder) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 + +error: aborting due to 2 previous errors + From 64d154205167d64386281613efd54bae5c75b603 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 1 Mar 2023 15:23:28 +0100 Subject: [PATCH 4/4] Update some UI tests --- tests/ui/issues/auxiliary/issue-14421.rs | 4 ++-- tests/ui/issues/auxiliary/issue-14422.rs | 4 ++-- tests/ui/suggestions/bound-suggestions.stderr | 24 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/ui/issues/auxiliary/issue-14421.rs b/tests/ui/issues/auxiliary/issue-14421.rs index 5fe4b24cf1708..733f40028d240 100644 --- a/tests/ui/issues/auxiliary/issue-14421.rs +++ b/tests/ui/issues/auxiliary/issue-14421.rs @@ -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; } diff --git a/tests/ui/issues/auxiliary/issue-14422.rs b/tests/ui/issues/auxiliary/issue-14422.rs index a6026c1d03fd5..641ecb03f3f53 100644 --- a/tests/ui/issues/auxiliary/issue-14422.rs +++ b/tests/ui/issues/auxiliary/issue-14422.rs @@ -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; } diff --git a/tests/ui/suggestions/bound-suggestions.stderr b/tests/ui/suggestions/bound-suggestions.stderr index cd27947f02fad..9667b78812ed5 100644 --- a/tests/ui/suggestions/bound-suggestions.stderr +++ b/tests/ui/suggestions/bound-suggestions.stderr @@ -1,8 +1,8 @@ -error[E0277]: `impl Sized` doesn't implement `Debug` +error[E0277]: `impl Sized` doesn't implement `std::fmt::Debug` --> $DIR/bound-suggestions.rs:9:22 | LL | println!("{:?}", t); - | ^ `impl Sized` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | ^ `impl Sized` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound @@ -10,11 +10,11 @@ help: consider further restricting this bound LL | fn test_impl(t: impl Sized + std::fmt::Debug) { | +++++++++++++++++ -error[E0277]: `T` doesn't implement `Debug` +error[E0277]: `T` doesn't implement `std::fmt::Debug` --> $DIR/bound-suggestions.rs:15:22 | LL | println!("{:?}", t); - | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` @@ -22,11 +22,11 @@ help: consider restricting type parameter `T` LL | fn test_no_bounds(t: T) { | +++++++++++++++++ -error[E0277]: `T` doesn't implement `Debug` +error[E0277]: `T` doesn't implement `std::fmt::Debug` --> $DIR/bound-suggestions.rs:21:22 | LL | println!("{:?}", t); - | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound @@ -34,11 +34,11 @@ help: consider further restricting this bound LL | fn test_one_bound(t: T) { | +++++++++++++++++ -error[E0277]: `Y` doesn't implement `Debug` +error[E0277]: `Y` doesn't implement `std::fmt::Debug` --> $DIR/bound-suggestions.rs:27:30 | LL | println!("{:?} {:?}", x, y); - | ^ `Y` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | ^ `Y` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `Y` @@ -46,11 +46,11 @@ help: consider further restricting type parameter `Y` LL | fn test_no_bounds_where(x: X, y: Y) where X: std::fmt::Debug, Y: std::fmt::Debug { | ~~~~~~~~~~~~~~~~~~~~ -error[E0277]: `X` doesn't implement `Debug` +error[E0277]: `X` doesn't implement `std::fmt::Debug` --> $DIR/bound-suggestions.rs:33:22 | LL | println!("{:?}", x); - | ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | ^ `X` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound @@ -58,11 +58,11 @@ help: consider further restricting this bound LL | fn test_one_bound_where(x: X) where X: Sized + std::fmt::Debug { | +++++++++++++++++ -error[E0277]: `X` doesn't implement `Debug` +error[E0277]: `X` doesn't implement `std::fmt::Debug` --> $DIR/bound-suggestions.rs:39:22 | LL | println!("{:?}", x); - | ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | ^ `X` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound