diff --git a/Cargo.lock b/Cargo.lock index 8d68be636fa92..82c524a04f03b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4626,7 +4626,6 @@ dependencies = [ "rustc_middle", "rustc_span", "rustc_ty_walk", - "tracing", ] [[package]] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1265bae778601..d2722ba3d71b1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -56,7 +56,7 @@ use rustc_errors::codes::*; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, ErrorGuaranteed}; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; -use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; +use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::lints::DelayedLint; use rustc_hir::{ @@ -182,6 +182,7 @@ struct LoweringContext<'a, 'hir> { owner: &'a PerOwnerResolverData<'hir>, item_local_id_counter: hir::ItemLocalId, trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>, + paths_from_private_deps: SortedMap, impl_trait_defs: Vec>, impl_trait_bounds: Vec>, @@ -254,6 +255,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { relowering_checker: Default::default(), trait_map: Default::default(), + paths_from_private_deps: SortedMap::default(), next_node_id: resolver.next_node_id, node_id_to_def_id: NodeMap::default(), partial_res_overrides: NodeMap::default(), @@ -843,6 +845,7 @@ impl<'hir> LoweringContext<'_, 'hir> { #[cfg(debug_assertions)] let current_relowering_checker = mem::take(&mut self.relowering_checker); let current_trait_map = mem::take(&mut self.trait_map); + let current_paths_from_private_deps = mem::take(&mut self.paths_from_private_deps); let current_owner = mem::replace(&mut self.current_hir_id_owner, owner_id); let current_local_counter = mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1)); @@ -878,6 +881,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.relowering_checker = current_relowering_checker; } self.trait_map = current_trait_map; + self.paths_from_private_deps = current_paths_from_private_deps; self.current_hir_id_owner = current_owner; self.item_local_id_counter = current_local_counter; self.impl_trait_defs = current_impl_trait_defs; @@ -895,6 +899,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut bodies = mem::take(&mut self.bodies); let define_opaque = mem::take(&mut self.define_opaque); let trait_map = mem::take(&mut self.trait_map); + let paths_from_private_deps = mem::take(&mut self.paths_from_private_deps); let delayed_lints = Steal::new(mem::take(&mut self.delayed_lints).into_boxed_slice()); let children = mem::take(&mut self.children); @@ -926,6 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> { parenting.stable_hash(&mut hcx, &mut stable_hasher); trait_map.stable_hash(&mut hcx, &mut stable_hasher); children.stable_hash(&mut hcx, &mut stable_hasher); + paths_from_private_deps.stable_hash(&mut hcx, &mut stable_hasher); stable_hasher.finish() }) }); @@ -938,6 +944,7 @@ impl<'hir> LoweringContext<'_, 'hir> { trait_map, delayed_lints, children, + paths_from_private_deps, }) } @@ -964,6 +971,10 @@ impl<'hir> LoweringContext<'_, 'hir> { self.trait_map.insert(hir_id.local_id, *traits); } + if let Some(&krate) = self.owner.paths_from_private_deps.get(&ast_node_id) { + self.paths_from_private_deps.insert(hir_id.local_id, krate); + } + // Check whether the same `NodeId` is lowered more than once. #[cfg(debug_assertions)] self.relowering_checker.assert_node_is_not_relowered(ast_node_id, local_id); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 37b2ca7718498..5535cc7746bf3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -34,7 +34,7 @@ use rustc_target::asm::InlineAsmRegOrRegClass; use tracing::debug; use crate::def::{CtorKind, DefKind, MacroKinds, PerNS, Res}; -use crate::def_id::{DefId, LocalDefIdMap}; +use crate::def_id::{CrateNum, DefId, LocalDefIdMap}; use crate::intravisit::{FnKind, VisitorExt}; use crate::lints::DelayedLints; @@ -1388,6 +1388,9 @@ pub struct OwnerInfo<'hir> { pub trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>, /// Owners generated as side-effect by lowering. pub children: UnordMap>, + /// Map from each nested owner that is a type imported from a + /// private dependency; generated by resolve. + pub paths_from_private_deps: SortedMap, /// Lints delayed during ast lowering to be emitted /// after hir has completely built diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 60de9d179cb98..06b1c65274dd6 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -577,6 +577,10 @@ impl CStore { } } + fn is_extern_private_dep(&self, externs: &Externs, name: Symbol) -> bool { + externs.get(name.as_str()).map(|e| e.is_private_dep).unwrap_or_default() + } + fn register_crate<'tcx>( &mut self, tcx: TyCtxt<'tcx>, @@ -593,6 +597,7 @@ impl CStore { let Library { source, metadata } = lib; let crate_root = metadata.get_root(); let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash()); + let extern_private_dep = self.is_extern_private_dep(&tcx.sess.opts.externs, name); let private_dep = self.is_private_dep(&tcx.sess.opts.externs, name, private_dep); // Claim this crate number and cache it @@ -651,6 +656,7 @@ impl CStore { dep_kind, source, private_dep, + extern_private_dep, host_hash, ); diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 8a565369d7610..9439474d471ba 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -133,6 +133,10 @@ pub(crate) struct CrateMetadata { /// Used by the 'exported_private_dependencies' lint, and for determining /// whether to emit suggestions that reference this crate. private_dep: bool, + /// Whether or not this is explicitly marked as a private dependency, specifically whether + /// `--extern` contained `priv:`. This is not the same thing as `private_dep` as some + /// dependencies might be marked `priv:` but are public dependencies transitively. + extern_private_dep: bool, /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`. host_hash: Option, /// The crate was used non-speculatively. @@ -802,14 +806,23 @@ impl MetadataBlob { let dylib_dependency_formats = root.dylib_dependency_formats.decode(self).collect::>(); for (i, dep) in root.crate_deps.decode(self).enumerate() { - let CrateDep { name, extra_filename, hash, host_hash, kind, is_private } = - dep; + let CrateDep { + name, + extra_filename, + hash, + host_hash, + kind, + is_private, + is_extern_private_dep, + } = dep; let number = i + 1; writeln!( out, - "{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}{linkage}", + "{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}{direct_privacy}{linkage}", privacy = if is_private { "private" } else { "public" }, + direct_privacy = + if is_extern_private_dep { " extern:priv" } else { "" }, linkage = if dylib_dependency_formats.is_empty() { String::new() } else { @@ -1950,6 +1963,7 @@ impl CrateMetadata { dep_kind: CrateDepKind, source: CrateSource, private_dep: bool, + extern_private_dep: bool, host_hash: Option, ) -> CrateMetadata { let trait_impls = root @@ -1979,6 +1993,7 @@ impl CrateMetadata { dep_kind, source: Arc::new(source), private_dep, + extern_private_dep, host_hash, used: false, extern_crate: None, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 8fe1d6561d135..fb48aa3347fb2 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -335,6 +335,7 @@ provide! { tcx, def_id, other, cdata, dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) } is_private_dep => { cdata.private_dep } + is_extern_private_dep => { cdata.extern_private_dep } is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } @@ -437,6 +438,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(), alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(), is_private_dep: |_tcx, LocalCrate| false, + is_extern_private_dep: |_tcx, LocalCrate| false, native_library: |tcx, id| { tcx.native_libraries(id.krate) .iter() diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index cc7da00fcec5c..a790f520aada4 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2097,6 +2097,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { kind: self.tcx.crate_dep_kind(cnum), extra_filename: self.tcx.extra_filename(cnum).clone(), is_private: self.tcx.is_private_dep(cnum), + is_extern_private_dep: self.tcx.is_extern_private_dep(cnum), }; (cnum, dep) }) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 064d906293ae8..a437d36747693 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -339,6 +339,7 @@ pub(crate) struct CrateDep { pub kind: CrateDepKind, pub extra_filename: String, pub is_private: bool, + pub is_extern_private_dep: bool, } #[derive(MetadataEncodable, LazyDecodable)] diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 5099859218187..4fd81190ed6b1 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -497,4 +497,6 @@ pub fn provide(providers: &mut Providers) { |tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]); providers.expn_that_defined = |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()); + providers.paths_from_private_deps = + |tcx, id| tcx.lower_to_hir(id).as_owner().map(|owner| &owner.paths_from_private_deps); } diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index ba790cadfe24f..e1f847dca1617 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -2359,6 +2359,16 @@ rustc_queries! { desc { "checking whether crate `{}` is a private dependency", c } separate_provide_extern } + /// Returns whether or not the crate with CrateNum 'cnum' + /// is marked as a direct public dependency + query is_extern_private_dep(c: CrateNum) -> bool { + eval_always + desc { "checking whether crate `{}` is a direct public dependency", c } + separate_provide_extern + } + query paths_from_private_deps(key: hir::OwnerId) -> Option<&'tcx SortedMap> { + desc { "getting paths imported from private dependencies in `{}`", tcx.def_path_str(key) } + } query allocator_kind(_: ()) -> Option { eval_always desc { "getting the allocator kind for the current crate" } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7a3b4c7fbbeb8..946a9c66185bd 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1268,6 +1268,10 @@ impl<'tcx> TyCtxt<'tcx> { None => Err(VarError::NotPresent), } } + + pub fn path_pointing_to_private_crate(self, hir_id: HirId) -> Option { + self.paths_from_private_deps(hir_id.owner)?.get(&hir_id.local_id).copied() + } } impl<'tcx> TyCtxtAt<'tcx> { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 3d8e30191c700..23337b3176adb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -222,6 +222,9 @@ pub struct PerOwnerResolverData<'tcx> { /// Lifetime parameters that lowering will have to introduce. pub extra_lifetime_params_map: NodeMap> = Default::default(), + /// Paths that use items exported or re-exported from a private dependency. + pub paths_from_private_deps: NodeMap = Default::default(), + /// The id of the owner pub id: ast::NodeId, /// The `DefId` of the owner, can't be found in `node_id_to_def_id`. @@ -262,6 +265,8 @@ pub struct ResolverAstLowering<'tcx> { /// Resolutions for nodes that have a single resolution. pub partial_res_map: NodeMap, + pub paths_from_private_deps: NodeMap, + pub next_node_id: ast::NodeId, pub owners: NodeMap>, diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index e5fdcc6e0749e..cec3cf9d8972c 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -14,5 +14,4 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_span = { path = "../rustc_span" } rustc_ty_walk = { path = "../rustc_ty_walk" } -tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 535b18d6c2fb0..9955eb882f02a 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -23,7 +23,7 @@ use rustc_errors::{MultiSpan, listify}; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModId}; use rustc_hir::intravisit::{self, InferKind, Visitor}; -use rustc_hir::{self as hir, AmbigArg, ForeignItemId, ItemId, OwnerId, PatKind, find_attr}; +use rustc_hir::{self as hir, AmbigArg, ForeignItemId, ItemId, Node, OwnerId, PatKind, find_attr}; use rustc_lint_defs::builtin::{ EXPORTED_PRIVATE_DEPENDENCIES, PRIVATE_BOUNDS, PRIVATE_INTERFACES, UNNAMEABLE_TYPES, }; @@ -36,7 +36,6 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_span::{Ident, Span, Symbol, sym}; -use tracing::debug; //////////////////////////////////////////////////////////////////////////////// // Generic infrastructure used to implement specific visitors below. @@ -1362,7 +1361,7 @@ impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> { /// SearchInterfaceForPrivateItemsVisitor traverses an item's interface and /// finds any private components in it. /// -/// PrivateItemsInPublicInterfacesVisitor ensures there are no private types +/// PrivateItemsInPublicInterfacesChecker ensures there are no private types /// and traits in public interfaces. struct SearchInterfaceForPrivateItemsVisitor<'tcx> { tcx: TyCtxt<'tcx>, @@ -1424,19 +1423,6 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } fn check_def_id(&self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { - if self.leaks_private_dep(def_id) { - self.tcx.emit_node_span_lint( - EXPORTED_PRIVATE_DEPENDENCIES, - self.tcx.local_def_id_to_hir_id(self.item_def_id), - self.tcx.def_span(self.item_def_id.to_def_id()), - FromPrivateDependencyInPublicInterface { - kind, - descr: descr.into(), - krate: self.tcx.crate_name(def_id.krate), - }, - ); - } - let Some(local_def_id) = def_id.as_local() else { return false; }; @@ -1501,17 +1487,6 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { false } - - /// An item is 'leaked' from a private dependency if all - /// of the following are true: - /// 1. It's contained within a public type - /// 2. It comes from a private crate - fn leaks_private_dep(&self, item_id: DefId) -> bool { - let ret = self.required_visibility.is_public() && self.tcx.is_private_dep(item_id.krate); - - debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); - ret - } } impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> { @@ -1896,4 +1871,72 @@ fn check_private_in_public(tcx: TyCtxt<'_>, mod_id: LocalModId) { let crate_items = tcx.hir_module_items(mod_id); let _ = crate_items.par_items(|id| Ok(checker.check_item(id))); let _ = crate_items.par_foreign_items(|id| Ok(checker.check_foreign_item(id))); + + let mut private_in_public_visitor = + SearchInterfaceForImportedItemsVisitor { tcx, effective_visibilities }; + + tcx.hir_visit_item_likes_in_module(mod_id, &mut private_in_public_visitor); +} + +struct SearchInterfaceForImportedItemsVisitor<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + effective_visibilities: &'a EffectiveVisibilities, +} + +impl<'a, 'tcx> SearchInterfaceForImportedItemsVisitor<'a, 'tcx> { + fn check_path(&mut self, path: &hir::Path<'_>, kind: &'static str, hir_id: hir::HirId) { + let Some(crate_num) = self.tcx.path_pointing_to_private_crate(hir_id) else { + return; + }; + + let Some(enclosing_def) = + self.tcx.hir_parent_iter(hir_id).find_map(|(_, node)| match node { + Node::Field(field) => Some(field.def_id), + Node::Item(item) => Some(item.owner_id.def_id), + Node::ImplItem(impl_item) => Some(impl_item.owner_id.def_id), + Node::TraitItem(trait_item) => Some(trait_item.owner_id.def_id), + Node::ForeignItem(foreign_item) => Some(foreign_item.owner_id.def_id), + _ => None, + }) + else { + return; + }; + + let Some(effective_visibility) = + self.effective_visibilities.effective_vis(enclosing_def).copied() + else { + return; + }; + + if !effective_visibility.is_public_at_level(Level::Reachable) { + return; + } + + self.tcx.emit_node_span_lint( + EXPORTED_PRIVATE_DEPENDENCIES, + hir_id, + path.span, + FromPrivateDependencyInPublicInterface { + kind, + descr: (&path.segments.last().unwrap().ident.name.as_str()).into(), + krate: self.tcx.crate_name(crate_num), + }, + ); + } +} + +impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for SearchInterfaceForImportedItemsVisitor<'a, 'tcx> { + fn visit_ty(&mut self, t: &'v hir::Ty<'v, AmbigArg>) -> Self::Result { + if let hir::TyKind::Path(hir::QPath::Resolved(_hir_ty, path)) = t.kind { + self.check_path(path, "type", t.hir_id); + } + + intravisit::walk_ty(self, t) + } + + fn visit_trait_ref(&mut self, trait_ref: &'v rustc_hir::TraitRef<'v>) { + self.check_path(trait_ref.path, "trait", trait_ref.hir_ref_id); + + intravisit::walk_trait_ref(self, trait_ref); + } } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index d58ec6b5032b8..408b24d8aaa18 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -5,6 +5,7 @@ use Namespace::*; use rustc_ast::{self as ast, NodeId}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS}; +use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_lint_defs::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK; use rustc_middle::{bug, span_bug}; use rustc_session::diagnostics::feature_err; @@ -2064,6 +2065,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module_had_parse_errors = true; } module = Some(ModuleOrUniformRoot::Module(self.expect_module(def_id))); + if let Some(finalize) = finalize + && let Some(ns) = opt_ns + { + self.record_path_pointing_to_private_crate(finalize, ns, binding); + } record_segment_res(self.reborrow(), finalize, res, id); } else if res == Res::ToolMod && !is_last && opt_ns.is_some() { if binding.is_import() { @@ -2076,13 +2082,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return PathResult::NonModule(PartialRes::new(res)); } else if res == Res::Err { return PathResult::NonModule(PartialRes::new(Res::Err)); - } else if opt_ns.is_some() && (is_last || maybe_assoc) { + } else if let Some(ns) = opt_ns + && (is_last || maybe_assoc) + { if let Some(finalize) = finalize { self.get_mut().lint_if_path_starts_with_module( finalize, path, second_binding, ); + self.record_path_pointing_to_private_crate(finalize, ns, binding); } record_segment_res(self.reborrow(), finalize, res, id); return PathResult::NonModule(PartialRes::with_unresolved_segments( @@ -2195,4 +2204,39 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { _ => bug!("resolve_path: non-empty path `{:?}` has no module", path), }) } + + fn record_path_pointing_to_private_crate<'r>( + self: &mut CmResolver<'r, 'ra, 'tcx>, + finalize: Finalize, + ns: Namespace, + binding: Decl<'ra>, + ) { + if ns != TypeNS || finalize.stage != Stage::Late { + return; + } + + let Some(krate) = entry_crate(binding) else { return }; + + if !self.tcx.is_extern_private_dep(krate) { + return; + } + + self.get_mut().current_owner.paths_from_private_deps.insert(finalize.node_id, krate); + // .expect("paths_from_private_deps should be written at most once per node ID"); // but it isn't... + } +} + +fn entry_crate(decl: Decl<'_>) -> Option { + match decl.kind { + DeclKind::Import { source_decl, .. } => entry_crate(source_decl), + DeclKind::Def(res) => { + if let Res::Def(_, def_id) = res + && def_id.is_crate_root() + { + return Some(def_id.krate); + } + let module_krate = decl.parent_module?.opt_def_id()?.krate; + (module_krate != LOCAL_CRATE).then_some(module_krate) + } + } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2b1c0bf80a694..a905c462cc60a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1471,6 +1471,9 @@ pub struct Resolver<'ra, 'tcx> { potentially_unnecessary_qualifications: Vec> = Vec::new(), + /// Paths that reference items imported from private dependencies + paths_from_private_deps: NodeMap = NodeMap::default(), + /// Table for mapping struct IDs into struct constructor IDs, /// it's not used during normal resolution, only for better error reporting. /// Also includes of list of each fields visibility @@ -1984,6 +1987,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; let ast_lowering = ty::ResolverAstLowering { partial_res_map: self.partial_res_map, + paths_from_private_deps: self.paths_from_private_deps, next_node_id: self.next_node_id, owners: self.owners, lint_buffer: Steal::new(self.lint_buffer), diff --git a/tests/ui/extern-flag/public-and-private.stderr b/tests/ui/extern-flag/public-and-private.stderr index 209f5d4dadc5d..5a52998f098a4 100644 --- a/tests/ui/extern-flag/public-and-private.stderr +++ b/tests/ui/extern-flag/public-and-private.stderr @@ -1,8 +1,8 @@ error: type `S` from private dependency 'somedep' in public interface - --> $DIR/public-and-private.rs:10:5 + --> $DIR/public-and-private.rs:10:16 | LL | pub field: somedep::S, - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/public-and-private.rs:5:9 diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/reexport.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/reexport.rs index 0655e3ae2cfdb..4d18fdc97b0dd 100644 --- a/tests/ui/privacy/pub-priv-dep/auxiliary/reexport.rs +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/reexport.rs @@ -1,5 +1,5 @@ //@ aux-crate:shared=shared.rs -extern crate shared; +pub extern crate shared; pub use shared::Shared; diff --git a/tests/ui/privacy/pub-priv-dep/diamond_deps.rs b/tests/ui/privacy/pub-priv-dep/diamond_deps.rs index 0e1f6f36bc8cc..3e168aad39fe9 100644 --- a/tests/ui/privacy/pub-priv-dep/diamond_deps.rs +++ b/tests/ui/privacy/pub-priv-dep/diamond_deps.rs @@ -29,8 +29,8 @@ extern crate diamond_priv_dep; extern crate diamond_pub_dep; -// FIXME: This should trigger. pub fn leaks_priv() -> diamond_priv_dep::Shared { + //~^ ERROR type `Shared` from private dependency 'diamond_priv_dep' in public interface diamond_priv_dep::Shared } @@ -40,7 +40,7 @@ pub fn leaks_pub() -> diamond_pub_dep::Shared { pub struct PrivInStruct { pub f: diamond_priv_dep::SharedInType -//~^ ERROR type `diamond_priv_dep::SharedInType` from private dependency 'diamond_priv_dep' in public interface + //~^ ERROR type `SharedInType` from private dependency 'diamond_priv_dep' in public interface } pub struct PubInStruct { diff --git a/tests/ui/privacy/pub-priv-dep/diamond_deps.stderr b/tests/ui/privacy/pub-priv-dep/diamond_deps.stderr index 8a6d35a747b63..d4b4d5844a37b 100644 --- a/tests/ui/privacy/pub-priv-dep/diamond_deps.stderr +++ b/tests/ui/privacy/pub-priv-dep/diamond_deps.stderr @@ -1,8 +1,8 @@ -error: type `diamond_priv_dep::SharedInType` from private dependency 'diamond_priv_dep' in public interface - --> $DIR/diamond_deps.rs:42:5 +error: type `Shared` from private dependency 'diamond_priv_dep' in public interface + --> $DIR/diamond_deps.rs:32:24 | -LL | pub f: diamond_priv_dep::SharedInType - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub fn leaks_priv() -> diamond_priv_dep::Shared { + | ^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diamond_deps.rs:27:9 @@ -10,5 +10,11 @@ note: the lint level is defined here LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: type `SharedInType` from private dependency 'diamond_priv_dep' in public interface + --> $DIR/diamond_deps.rs:42:12 + | +LL | pub f: diamond_priv_dep::SharedInType + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs index ba947de7f182a..8569a2a762251 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -75,11 +75,9 @@ pub trait MyPubTrait { fn required_impl_trait() -> impl OtherTrait; //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface - //~| ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface fn provided_impl_trait() -> impl OtherTrait { OtherType } //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface - //~| ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface fn required_concrete() -> OtherType; //~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface @@ -123,7 +121,7 @@ pub type Alias = OtherType; //~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface pub type AliasOfAlias = priv_dep::PubPub; -//~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface +//~^ ERROR type `PubPub` from private dependency 'priv_dep' in public interface pub struct PublicWithPrivateImpl; @@ -134,7 +132,6 @@ pub trait PubTraitOnPrivate {} impl PubTraitOnPrivate for OtherType {} //~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface -//~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface pub struct PublicWithStdImpl; @@ -146,10 +143,7 @@ impl From for PublicWithStdImpl { impl From for OtherType { //~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface - //~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface fn from(val: PublicWithStdImpl) -> Self { Self } - //~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface - //~| ERROR type `OtherType` from private dependency 'priv_dep' in public interface } pub struct AllowedPrivType { diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr index 609dbd77f9c19..61c0a539736ef 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -11,70 +11,70 @@ LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: macro `m` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:160:9 + --> $DIR/pub-priv1.rs:154:9 | LL | pub use priv_dep::m; | ^^^^^^^^^^^ error: macro `fn_like` from private dependency 'pm' is re-exported - --> $DIR/pub-priv1.rs:162:9 + --> $DIR/pub-priv1.rs:156:9 | LL | pub use pm::fn_like; | ^^^^^^^^^^^ error: derive macro `PmDerive` from private dependency 'pm' is re-exported - --> $DIR/pub-priv1.rs:164:9 + --> $DIR/pub-priv1.rs:158:9 | LL | pub use pm::PmDerive; | ^^^^^^^^^^^^ error: attribute macro `pm_attr` from private dependency 'pm' is re-exported - --> $DIR/pub-priv1.rs:166:9 + --> $DIR/pub-priv1.rs:160:9 | LL | pub use pm::pm_attr; | ^^^^^^^^^^^ error: variant `V1` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:169:9 + --> $DIR/pub-priv1.rs:163:9 | LL | pub use priv_dep::E::V1; | ^^^^^^^^^^^^^^^ error: type alias `Unit` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:172:9 + --> $DIR/pub-priv1.rs:166:9 | LL | pub use priv_dep::Unit; | ^^^^^^^^^^^^^^ error: type alias `PubPub` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:174:9 + --> $DIR/pub-priv1.rs:168:9 | LL | pub use priv_dep::PubPub; | ^^^^^^^^^^^^^^^^ error: type alias `PubPriv` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:176:9 + --> $DIR/pub-priv1.rs:170:9 | LL | pub use priv_dep::PubPriv; | ^^^^^^^^^^^^^^^^^ error: struct `Renamed` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:178:9 + --> $DIR/pub-priv1.rs:172:9 | LL | pub use priv_dep::OtherType as Renamed; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:29:5 + --> $DIR/pub-priv1.rs:29:16 | LL | pub field: OtherType, - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:36:5 + --> $DIR/pub-priv1.rs:36:9 | LL | pub OtherType, - | ^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface --> $DIR/pub-priv1.rs:44:21 @@ -83,206 +83,160 @@ LL | ActualOtherType(OtherType, PubType), | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:47:9 + --> $DIR/pub-priv1.rs:47:16 | LL | field: OtherType, - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:54:1 + --> $DIR/pub-priv1.rs:54:54 | LL | pub type ReexportedPublicGeneric = PublicGenericType; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:56:1 + --> $DIR/pub-priv1.rs:56:59 | LL | pub type ReexportedPrivateGeneric = PublicGenericType<(), OtherType>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:59:1 + --> $DIR/pub-priv1.rs:59:40 | LL | pub struct PublicGenericBoundedType(T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:63:5 - | -LL | pub fn pub_fn_param(param: OtherType) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:66:5 - | -LL | pub fn pub_fn_return() -> OtherType { OtherType } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:73:5 - | -LL | type Foo: OtherTrait; - | ^^^^^^^^^^^^^^^^^^^^ - -error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:76:33 - | -LL | fn required_impl_trait() -> impl OtherTrait; - | ^^^^^^^^^^^^^^^ - -error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:76:33 - | -LL | fn required_impl_trait() -> impl OtherTrait; - | ^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:80:33 - | -LL | fn provided_impl_trait() -> impl OtherTrait { OtherType } - | ^^^^^^^^^^^^^^^ - -error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:80:33 - | -LL | fn provided_impl_trait() -> impl OtherTrait { OtherType } - | ^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:84:5 - | -LL | fn required_concrete() -> OtherType; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:87:5 - | -LL | fn provided_concrete() -> OtherType { OtherType } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:91:1 + --> $DIR/pub-priv1.rs:89:27 | LL | pub trait WithSuperTrait: OtherTrait {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:100:5 - | -LL | type X = OtherType; - | ^^^^^^ + | ^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:104:1 + --> $DIR/pub-priv1.rs:102:21 | LL | pub fn in_bounds(x: T) { unimplemented!() } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:107:1 + --> $DIR/pub-priv1.rs:105:44 | LL | pub fn private_return_impl_trait() -> impl OtherTrait { OtherType } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:110:1 + --> $DIR/pub-priv1.rs:108:28 | LL | pub fn private_return() -> OtherType { OtherType } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:113:1 + --> $DIR/pub-priv1.rs:111:53 | LL | pub fn private_in_generic() -> std::num::Saturating { unimplemented!() } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:116:1 + --> $DIR/pub-priv1.rs:114:20 | LL | pub static STATIC: OtherType = OtherType; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:119:1 + --> $DIR/pub-priv1.rs:117:18 | LL | pub const CONST: OtherType = OtherType; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:122:1 + --> $DIR/pub-priv1.rs:120:18 | LL | pub type Alias = OtherType; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^ -error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:125:1 +error: type `PubPub` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:123:25 | LL | pub type AliasOfAlias = priv_dep::PubPub; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:130:1 + --> $DIR/pub-priv1.rs:128:6 | LL | impl OtherTrait for PublicWithPrivateImpl {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:135:1 + --> $DIR/pub-priv1.rs:133:28 | LL | impl PubTraitOnPrivate for OtherType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:135:1 - | -LL | impl PubTraitOnPrivate for OtherType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $DIR/pub-priv1.rs:138:11 | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | impl From for PublicWithStdImpl { + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:141:1 + --> $DIR/pub-priv1.rs:144:34 | -LL | impl From for PublicWithStdImpl { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl From for OtherType { + | ^^^^^^^^^ -error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:143:5 +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:73:15 | -LL | fn from(val: OtherType) -> Self { Self } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Foo: OtherTrait; + | ^^^^^^^^^^ + +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:76:38 + | +LL | fn required_impl_trait() -> impl OtherTrait; + | ^^^^^^^^^^ + +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:79:38 + | +LL | fn provided_impl_trait() -> impl OtherTrait { OtherType } + | ^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:147:1 + --> $DIR/pub-priv1.rs:82:31 | -LL | impl From for OtherType { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn required_concrete() -> OtherType; + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:147:1 + --> $DIR/pub-priv1.rs:85:31 | -LL | impl From for OtherType { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn provided_concrete() -> OtherType { OtherType } + | ^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:63:32 | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | pub fn pub_fn_param(param: OtherType) {} + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:150:5 + --> $DIR/pub-priv1.rs:66:31 | -LL | fn from(val: PublicWithStdImpl) -> Self { Self } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub fn pub_fn_return() -> OtherType { OtherType } + | ^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:150:5 + --> $DIR/pub-priv1.rs:98:14 | -LL | fn from(val: PublicWithStdImpl) -> Self { Self } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type X = OtherType; + | ^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:140:18 | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | fn from(val: OtherType) -> Self { Self } + | ^^^^^^^^^ -error: aborting due to 45 previous errors +error: aborting due to 39 previous errors diff --git a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs index 136e0ceeb5bec..fbb85dee83b14 100644 --- a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs +++ b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs @@ -7,8 +7,14 @@ #![deny(exported_private_dependencies)] extern crate reexport; +use reexport::Shared; pub fn leaks_priv() -> reexport::Shared { - //~^ ERROR type `Shared` from private dependency 'shared' in public interface + //~^ ERROR type `Shared` from private dependency 'reexport' in public interface reexport::Shared } + +pub fn leaks_priv_use() -> Shared { + //~^ ERROR type `Shared` from private dependency 'reexport' in public interface + Shared +} diff --git a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr index f1573283ff2e3..258ac23df6911 100644 --- a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr +++ b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr @@ -1,8 +1,8 @@ -error: type `Shared` from private dependency 'shared' in public interface - --> $DIR/reexport_from_priv.rs:11:1 +error: type `Shared` from private dependency 'reexport' in public interface + --> $DIR/reexport_from_priv.rs:12:24 | LL | pub fn leaks_priv() -> reexport::Shared { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/reexport_from_priv.rs:7:9 @@ -10,5 +10,11 @@ note: the lint level is defined here LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: type `Shared` from private dependency 'reexport' in public interface + --> $DIR/reexport_from_priv.rs:17:28 + | +LL | pub fn leaks_priv_use() -> Shared { + | ^^^^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/privacy/pub-priv-dep/shared_both_private.rs b/tests/ui/privacy/pub-priv-dep/shared_both_private.rs index 06debee1ff9e8..813eef7ac1e95 100644 --- a/tests/ui/privacy/pub-priv-dep/shared_both_private.rs +++ b/tests/ui/privacy/pub-priv-dep/shared_both_private.rs @@ -26,6 +26,6 @@ pub fn leaks_priv() -> shared::Shared { } pub fn leaks_priv_reexport() -> reexport::Shared { - //~^ ERROR type `Shared` from private dependency 'shared' in public interface + //~^ ERROR type `Shared` from private dependency 'reexport' in public interface reexport::Shared } diff --git a/tests/ui/privacy/pub-priv-dep/shared_both_private.stderr b/tests/ui/privacy/pub-priv-dep/shared_both_private.stderr index b26e026b2d67b..12ee29dd1054a 100644 --- a/tests/ui/privacy/pub-priv-dep/shared_both_private.stderr +++ b/tests/ui/privacy/pub-priv-dep/shared_both_private.stderr @@ -1,8 +1,8 @@ error: type `Shared` from private dependency 'shared' in public interface - --> $DIR/shared_both_private.rs:23:1 + --> $DIR/shared_both_private.rs:23:24 | LL | pub fn leaks_priv() -> shared::Shared { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/shared_both_private.rs:18:9 @@ -10,11 +10,11 @@ note: the lint level is defined here LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: type `Shared` from private dependency 'shared' in public interface - --> $DIR/shared_both_private.rs:28:1 +error: type `Shared` from private dependency 'reexport' in public interface + --> $DIR/shared_both_private.rs:28:33 | LL | pub fn leaks_priv_reexport() -> reexport::Shared { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/privacy/pub-priv-dep/shared_direct_private.rs b/tests/ui/privacy/pub-priv-dep/shared_direct_private.rs index b329a7acb5834..fccafa86b8255 100644 --- a/tests/ui/privacy/pub-priv-dep/shared_direct_private.rs +++ b/tests/ui/privacy/pub-priv-dep/shared_direct_private.rs @@ -1,7 +1,6 @@ //@ aux-crate:priv:shared=shared.rs //@ aux-crate:reexport=reexport.rs //@ compile-flags: -Zunstable-options -//@ check-pass // A shared dependency, where the public side reexports the same item as a // direct private dependency. @@ -23,17 +22,17 @@ extern crate shared; extern crate reexport; -// FIXME: Should this trigger? -// -// One could make an argument that I said I want "reexport" to be public, and -// since "reexport" says "shared_direct_private" is public, then it should -// transitively be public for me. However, as written, this is explicitly -// referring to a dependency that is marked "private", which I think is -// confusing. +use reexport::Shared; + pub fn leaks_priv() -> shared::Shared { + //~^ error: type `Shared` from private dependency 'shared' in public interface shared::Shared } pub fn leaks_pub() -> reexport::Shared { reexport::Shared } + +pub fn leaks_pub_use() -> Shared { + Shared +} diff --git a/tests/ui/privacy/pub-priv-dep/shared_direct_private.stderr b/tests/ui/privacy/pub-priv-dep/shared_direct_private.stderr new file mode 100644 index 0000000000000..1193e57d8b65f --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/shared_direct_private.stderr @@ -0,0 +1,14 @@ +error: type `Shared` from private dependency 'shared' in public interface + --> $DIR/shared_direct_private.rs:27:24 + | +LL | pub fn leaks_priv() -> shared::Shared { + | ^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/shared_direct_private.rs:20:9 + | +LL | #![deny(exported_private_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr b/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr index dbc534713d16e..73b2bdfd128d3 100644 --- a/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr +++ b/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr @@ -1,8 +1,8 @@ error: type `Shared` from private dependency 'shared' in public interface - --> $DIR/shared_indirect.rs:25:1 + --> $DIR/shared_indirect.rs:25:24 | LL | pub fn leaks_priv() -> shared::Shared { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/shared_indirect.rs:20:9