From 8b6f3ddf2347509f9ff90c34e48673a25624d6e5 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 15 Dec 2018 07:00:15 -0500 Subject: [PATCH 01/22] Initial implementation work --- src/librustc/lint/builtin.rs | 6 ++ src/librustc/session/config.rs | 24 ++++++ src/librustc_lint/builtin.rs | 2 + src/librustc_lint/lib.rs | 5 ++ src/librustc_privacy/lib.rs | 129 +++++++++++++++++++++++++++++++-- src/libsyntax/feature_gate.rs | 3 + 6 files changed, 164 insertions(+), 5 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 35a0382359572..16f7f9903f7d5 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -125,6 +125,12 @@ declare_lint! { "detect private items in public interfaces not caught by the old implementation" } +declare_lint! { + pub LEAKED_PRIVATE_DEPENDENCY, + Warn, + "public interface leaks type from a private dependency" +} + declare_lint! { pub PUB_USE_OF_PRIVATE_EXTERN_CRATE, Deny, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 4b1aefb2216fb..5c2aa882a06c6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -411,6 +411,10 @@ top_level_options!( remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED], edition: Edition [TRACKED], + + // The list of crates to consider public for + // checking leaked private dependency types in public interfaces + extern_public: FxHashSet [UNTRACKED], } ); @@ -606,6 +610,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, + extern_public: FxHashSet::default() } } } @@ -1648,6 +1653,13 @@ pub fn rustc_short_optgroups() -> Vec { for the compiler to emit", "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]", ), + opt::multi_s( + "", + "extern-public", + "Comma separated list of crates to consider 'public' + for linting purposes", + "CRATES", + ), opt::opt_s( "", "crate-name", @@ -1905,6 +1917,17 @@ pub fn build_session_options_and_crate_config( let crate_types = parse_crate_types_from_list(unparsed_crate_types) .unwrap_or_else(|e| early_error(error_format, &e[..])); + if matches.opt_present("extern-public") && !nightly_options::is_nightly_build() { + early_error( + ErrorOutputType::default(), + "'--extern-public' is unstable and only \ + available for nightly builds of rustc." + ) + } + + let extern_public: FxHashSet = matches.opt_strs("extern-public"). + iter().cloned().collect(); + let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let mut debugging_opts = build_debugging_options(matches, error_format); @@ -2287,6 +2310,7 @@ pub fn build_session_options_and_crate_config( cli_forced_thinlto_off: disable_thinlto, remap_path_prefix, edition, + extern_public }, cfg, ) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 46e784c4099c8..b0846822b24e1 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1883,3 +1883,5 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { } } + + diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 6607951d2cd14..e2e63b418c72c 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -229,6 +229,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #34537 ", edition: None, }, + FutureIncompatibleInfo { + id: LintId::of(LEAKED_PRIVATE_DEPENDENCY), + reference: "issue #44663 ", + edition: None, + }, FutureIncompatibleInfo { id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), reference: "issue #34537 ", diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index dcbb9ff4a7576..c7cdb30521bf0 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1458,6 +1458,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { has_pub_restricted: bool, has_old_errors: bool, in_assoc_ty: bool, + public_crates: FxHashSet } impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { @@ -1514,22 +1515,134 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC, node_id, self.span, &format!("{} (error {})", msg, err_code)); } + + if self.leaks_private_dep(trait_ref.def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + node_id, + self.span, + &format!("trait `{}` from private dependency '{}' in public \ + interface", trait_ref, + trait_ref.def_id.krate)); + + } } - 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 does not come from a crate marked as public + fn leaks_private_dep(&self, item_id: DefId) -> bool { + // Never do any leak checking if the feature is not enabled + if !self.tcx.features().public_private_dependencies { + return false + } + self.required_visibility == ty::Visibility::Public && + !item_id.is_local() && + !self.public_crates.contains(&item_id.krate) } } -impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { - fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx } - fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { - self.check_def_id(def_id, kind, descr) +impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { + let ty_def_id = match ty.sty { + ty::Adt(adt, _) => Some(adt.did), + ty::Foreign(did) => Some(did), + ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), + ty::Projection(ref proj) => { + if self.required_visibility == ty::Visibility::Invisible { + // Conservatively approximate the whole type alias as public without + // recursing into its components when determining impl publicity. + // For example, `impl ::Alias {...}` may be a public impl + // even if both `Type` and `Trait` are private. + // Ideally, associated types should be substituted in the same way as + // free type aliases, but this isn't done yet. + return false; + } + let trait_ref = proj.trait_ref(self.tcx); + Some(trait_ref.def_id) + } + _ => None + }; + + if let Some(def_id) = ty_def_id { + // Non-local means public (private items can't leave their crate, modulo bugs). + if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) { + let hir_vis = match self.tcx.hir().find(node_id) { + Some(Node::Item(item)) => &item.vis, + Some(Node::ForeignItem(item)) => &item.vis, + _ => bug!("expected item of foreign item"), + }; + + let vis = ty::Visibility::from_hir(hir_vis, node_id, self.tcx); + + if !vis.is_at_least(self.min_visibility, self.tcx) { + self.min_visibility = vis; + } + if !vis.is_at_least(self.required_visibility, self.tcx) { + let vis_adj = match hir_vis.node { + hir::VisibilityKind::Crate(_) => "crate-visible", + hir::VisibilityKind::Restricted { .. } => "restricted", + _ => "private" + }; + + if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty { + let mut err = struct_span_err!(self.tcx.sess, self.span, E0446, + "{} type `{}` in public interface", vis_adj, ty); + err.span_label(self.span, format!("can't leak {} type", vis_adj)); + err.span_label(hir_vis.span, format!("`{}` declared as {}", ty, vis_adj)); + err.emit(); + } else { + self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC, + node_id, + self.span, + &format!("{} type `{}` in public \ + interface (error E0446)", vis_adj, ty)); + } + } + + if self.leaks_private_dep(def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + node_id, + self.span, + &format!("type '{}' from private dependency '{}' in \ + public interface", ty, def_id.krate)); + } + } + } + + ty.super_visit_with(self) + } +} + +/*struct LeakedPrivateDependenciesVisitor<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + public_crates: FxHashSet +} + +impl<'a, 'tcx> LeakedPrivateDependenciesVisitor<'a, 'tcx> { + fn is_private_dep(&self, item_id: DefId) { + !item_id.is_local() && !self.public_crates.contains(item_id.krate) } + } +impl<'a, 'tcx> Visitor<'tcx> for LeakedPrivateDependenciesVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> nestedvisitormap<'this, 'tcx> { + nestedvisitormap::onlybodies(&self.tcx.hir()) + } + + fn visit_item(&mut self, item: &'tcx hir::Item) { + + } + +}*/ + struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, has_pub_restricted: bool, old_error_set: &'a NodeSet, + public_crates: FxHashSet } impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { @@ -1566,6 +1679,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { has_pub_restricted: self.has_pub_restricted, has_old_errors, in_assoc_ty: false, + public_crates: self.public_crates.clone() } } @@ -1690,6 +1804,10 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Lrc { fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { let empty_tables = ty::TypeckTables::empty(None); + let public_crates: FxHashSet = tcx.sess.opts.extern_public.iter().flat_map(|c| { + tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() + }).collect(); + // Check privacy of names not checked in previous compilation stages. let mut visitor = NamePrivacyVisitor { tcx, @@ -1767,6 +1885,7 @@ fn privacy_access_levels<'tcx>( tcx, has_pub_restricted, old_error_set: &visitor.old_error_set, + public_crates }; krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor)); } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9dd17b420aa44..55eb6723188b9 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -462,6 +462,9 @@ declare_features! ( // #[optimize(X)] (active, optimize_attribute, "1.34.0", Some(54882), None), + + // Allows using the 'leaked private dependencies' lint + (active, public_private_dependencies, "1.32.0", Some(44663), None), ); declare_features! ( From 09ff0bacef6dd6bc3854f5c0dafff09e3ae22c6e Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 15 Dec 2018 08:01:57 -0500 Subject: [PATCH 02/22] Fix emitting lint --- src/librustc_privacy/Cargo.toml | 3 ++- src/librustc_privacy/lib.rs | 46 +++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml index 62eab40f3ec9a..dfc4e5b5db45d 100644 --- a/src/librustc_privacy/Cargo.toml +++ b/src/librustc_privacy/Cargo.toml @@ -13,4 +13,5 @@ rustc = { path = "../librustc" } rustc_typeck = { path = "../librustc_typeck" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rustc_data_structures = { path = "../librustc_data_structures" } \ No newline at end of file +rustc_data_structures = { path = "../librustc_data_structures" } +log = "0.4" diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index c7cdb30521bf0..ce0a4a654825a 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -9,6 +9,7 @@ #[macro_use] extern crate rustc; #[macro_use] extern crate syntax; +#[macro_use] extern crate log; extern crate rustc_typeck; extern crate syntax_pos; extern crate rustc_data_structures; @@ -1451,6 +1452,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_id: ast::NodeId, item_def_id: DefId, span: Span, /// The visitor checks that each component type is at least this visible. @@ -1516,16 +1518,18 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { &format!("{} (error {})", msg, err_code)); } - if self.leaks_private_dep(trait_ref.def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, - node_id, - self.span, - &format!("trait `{}` from private dependency '{}' in public \ - interface", trait_ref, - trait_ref.def_id.krate)); + } + + if self.leaks_private_dep(trait_ref.def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + self.item_id, + self.span, + &format!("trait `{}` from private dependency '{}' in public \ + interface", trait_ref, + self.tcx.crate_name(trait_ref.def_id.krate))); - } } + } /// An item is 'leaked' from a private dependency if all @@ -1537,9 +1541,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { if !self.tcx.features().public_private_dependencies { return false } - self.required_visibility == ty::Visibility::Public && + let ret = self.required_visibility == ty::Visibility::Public && !item_id.is_local() && - !self.public_crates.contains(&item_id.krate) + !self.public_crates.contains(&item_id.krate); + + + debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); + return ret; } } @@ -1601,14 +1609,17 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<' } } - if self.leaks_private_dep(def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, - node_id, - self.span, - &format!("type '{}' from private dependency '{}' in \ - public interface", ty, def_id.krate)); - } } + + if self.leaks_private_dep(def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + self.item_id, + self.span, + &format!("type '{}' from private dependency '{}' in \ + public interface", ty, + self.tcx.crate_name(def_id.krate))); + } + } ty.super_visit_with(self) @@ -1673,6 +1684,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { SearchInterfaceForPrivateItemsVisitor { tcx: self.tcx, + item_id, item_def_id: self.tcx.hir().local_def_id(item_id), span: self.tcx.hir().span(item_id), required_visibility, From afb1921c79064a6fb99d2b93ef4835d9da14b517 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 18:07:42 -0500 Subject: [PATCH 03/22] Fixup code --- Cargo.lock | 1 + src/librustc_privacy/lib.rs | 104 +++++++----------------------------- 2 files changed, 21 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 058f1b1e716a9..1ac2dfe25c395 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2878,6 +2878,7 @@ dependencies = [ name = "rustc_privacy" version = "0.0.0" dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_data_structures 0.0.0", "rustc_typeck 0.0.0", diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index ce0a4a654825a..f37d0ce426003 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1495,6 +1495,16 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { } fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { + if self.leaks_private_dep(def_id) { + self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + self.item_id, + self.span, + &format!("{} `{}` from private dependency '{}' in public \ + interface", kind, descr, + self.tcx.crate_name(def_id.krate))); + + } + let node_id = match self.tcx.hir().as_local_node_id(def_id) { Some(node_id) => node_id, None => return false, @@ -1520,16 +1530,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { } - if self.leaks_private_dep(trait_ref.def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, - self.item_id, - self.span, - &format!("trait `{}` from private dependency '{}' in public \ - interface", trait_ref, - self.tcx.crate_name(trait_ref.def_id.krate))); - - } - + false } /// An item is 'leaked' from a private dependency if all @@ -1551,80 +1552,6 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { } } -impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { - fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { - let ty_def_id = match ty.sty { - ty::Adt(adt, _) => Some(adt.did), - ty::Foreign(did) => Some(did), - ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), - ty::Projection(ref proj) => { - if self.required_visibility == ty::Visibility::Invisible { - // Conservatively approximate the whole type alias as public without - // recursing into its components when determining impl publicity. - // For example, `impl ::Alias {...}` may be a public impl - // even if both `Type` and `Trait` are private. - // Ideally, associated types should be substituted in the same way as - // free type aliases, but this isn't done yet. - return false; - } - let trait_ref = proj.trait_ref(self.tcx); - Some(trait_ref.def_id) - } - _ => None - }; - - if let Some(def_id) = ty_def_id { - // Non-local means public (private items can't leave their crate, modulo bugs). - if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) { - let hir_vis = match self.tcx.hir().find(node_id) { - Some(Node::Item(item)) => &item.vis, - Some(Node::ForeignItem(item)) => &item.vis, - _ => bug!("expected item of foreign item"), - }; - - let vis = ty::Visibility::from_hir(hir_vis, node_id, self.tcx); - - if !vis.is_at_least(self.min_visibility, self.tcx) { - self.min_visibility = vis; - } - if !vis.is_at_least(self.required_visibility, self.tcx) { - let vis_adj = match hir_vis.node { - hir::VisibilityKind::Crate(_) => "crate-visible", - hir::VisibilityKind::Restricted { .. } => "restricted", - _ => "private" - }; - - if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty { - let mut err = struct_span_err!(self.tcx.sess, self.span, E0446, - "{} type `{}` in public interface", vis_adj, ty); - err.span_label(self.span, format!("can't leak {} type", vis_adj)); - err.span_label(hir_vis.span, format!("`{}` declared as {}", ty, vis_adj)); - err.emit(); - } else { - self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC, - node_id, - self.span, - &format!("{} type `{}` in public \ - interface (error E0446)", vis_adj, ty)); - } - } - - } - - if self.leaks_private_dep(def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, - self.item_id, - self.span, - &format!("type '{}' from private dependency '{}' in \ - public interface", ty, - self.tcx.crate_name(def_id.krate))); - } - - } - - ty.super_visit_with(self) - } -} /*struct LeakedPrivateDependenciesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1649,6 +1576,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LeakedPrivateDependenciesVisitor<'a, 'tcx> { }*/ + + +impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx } + fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { + self.check_def_id(def_id, kind, descr) + } +} + struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, has_pub_restricted: bool, From 23014b4036ef88522e5134e71622b64eebbcf703 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 18:50:16 -0500 Subject: [PATCH 04/22] Properly register lint --- src/librustc/lint/builtin.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 16f7f9903f7d5..1651175525e05 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -411,6 +411,7 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, + LEAKED_PRIVATE_DEPENDENCY, PUB_USE_OF_PRIVATE_EXTERN_CRATE, INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, From 93d872dbc88412c2ef1c22be1f81961cae730ac2 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 18:50:24 -0500 Subject: [PATCH 05/22] Add UI test --- .../pub-priv-dep/auxiliary/priv_dep.rs | 1 + src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 31 +++++++++++++++++++ .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 25 +++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs create mode 100644 src/test/ui/privacy/pub-priv-dep/pub-priv1.rs create mode 100644 src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr diff --git a/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs b/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs new file mode 100644 index 0000000000000..23426f96c75f0 --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs @@ -0,0 +1 @@ +pub struct OtherType; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs new file mode 100644 index 0000000000000..d8620944065c9 --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -0,0 +1,31 @@ + // aux-build:priv_dep.rs +#![feature(public_private_dependencies)] +#![deny(leaked_private_dependency)] + +// This crate is a private dependency +extern crate priv_dep; + +use priv_dep::OtherType; + +// Type from private dependency used in private +// type - this is fine +struct PrivateType { + field: OtherType +} + +pub struct PublicType { + pub field: OtherType, + //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] + //~| WARNING this was previously accepted + priv_field: OtherType, +} + +impl PublicType { + pub fn pub_fn(param: OtherType) {} + //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] + //~| WARNING this was previously accepted + + fn priv_fn(param: OtherType) {} +} + +fn main() {} diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr new file mode 100644 index 0000000000000..330bf8a1f5226 --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -0,0 +1,25 @@ +error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:17:5 + | +LL | pub field: OtherType, + | ^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/pub-priv1.rs:3:9 + | +LL | #![deny(leaked_private_dependency)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = 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 #44663 + +error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:24:5 + | +LL | pub fn pub_fn(param: OtherType) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 #44663 + +error: aborting due to 2 previous errors + From 08c901f0155b10c55427991e9da6fce83b541f2c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 20:35:14 -0500 Subject: [PATCH 06/22] Always treat 'std' and 'core' as public --- src/librustc/session/config.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 5c2aa882a06c6..16d3d332e4056 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1925,9 +1925,13 @@ pub fn build_session_options_and_crate_config( ) } - let extern_public: FxHashSet = matches.opt_strs("extern-public"). + let mut extern_public: FxHashSet = matches.opt_strs("extern-public"). iter().cloned().collect(); + // TODO - come up with a better way of handling this + extern_public.insert("core".to_string()); + extern_public.insert("std".to_string()); + let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let mut debugging_opts = build_debugging_options(matches, error_format); From 12f9b796ff9a551d540390647043f4bcd1728838 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 20:37:27 -0500 Subject: [PATCH 07/22] Improve UI tests --- .../pub-priv-dep/auxiliary/priv_dep.rs | 1 + .../privacy/pub-priv-dep/auxiliary/pub_dep.rs | 1 + src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 17 +++++++++++++++-- .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 19 +++++++++++++++---- 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs diff --git a/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs b/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs index 23426f96c75f0..e7afeb84fb4f4 100644 --- a/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs +++ b/src/test/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs @@ -1 +1,2 @@ pub struct OtherType; +pub trait OtherTrait {} diff --git a/src/test/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs b/src/test/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs new file mode 100644 index 0000000000000..3ebafd953addf --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs @@ -0,0 +1 @@ +pub struct PubType; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index d8620944065c9..f82c1ad1c93b5 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -1,11 +1,16 @@ // aux-build:priv_dep.rs + // aux-build:pub_dep.rs + // compile-flags: --extern-public=pub_dep #![feature(public_private_dependencies)] #![deny(leaked_private_dependency)] // This crate is a private dependency extern crate priv_dep; +// This crate is a public dependenct +extern crate pub_dep; -use priv_dep::OtherType; +use priv_dep::{OtherType, OtherTrait}; +use pub_dep::PubType; // Type from private dependency used in private // type - this is fine @@ -17,7 +22,8 @@ pub struct PublicType { pub field: OtherType, //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] //~| WARNING this was previously accepted - priv_field: OtherType, + priv_field: OtherType, // Private field - this is fine + pub other_field: PubType // Type from public dependency - this is fine } impl PublicType { @@ -28,4 +34,11 @@ impl PublicType { fn priv_fn(param: OtherType) {} } +pub trait MyPubTrait { + type Foo: OtherTrait; +} +//~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface [leaked_private_dependency] +//~| WARNING this was previously accepted + + fn main() {} diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index 330bf8a1f5226..fa74eb2265d0c 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -1,11 +1,11 @@ error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:17:5 + --> $DIR/pub-priv1.rs:22:5 | LL | pub field: OtherType, | ^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/pub-priv1.rs:3:9 + --> $DIR/pub-priv1.rs:5:9 | LL | #![deny(leaked_private_dependency)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![deny(leaked_private_dependency)] = note: for more information, see issue #44663 error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:24:5 + --> $DIR/pub-priv1.rs:30:5 | LL | pub fn pub_fn(param: OtherType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,5 +21,16 @@ LL | pub fn pub_fn(param: OtherType) {} = 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 #44663 -error: aborting due to 2 previous errors +error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:37:1 + | +LL | / pub trait MyPubTrait { +LL | | type Foo: OtherTrait; +LL | | } + | |_^ + | + = 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 #44663 + +error: aborting due to 3 previous errors From d60214cdf7bea6955d5c3a0bb905022bdae1b232 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 22:29:52 -0500 Subject: [PATCH 08/22] Clippy fixes, rename stuff to match RFC --- src/librustc/lint/builtin.rs | 4 ++-- src/librustc/session/config.rs | 2 +- src/librustc_lint/builtin.rs | 2 -- src/librustc_lint/lib.rs | 2 +- src/librustc_privacy/lib.rs | 2 +- .../ui/feature-gates/auxiliary/pub_dep.rs | 1 + ...eature-gate-public_private_dependencies.rs | 20 +++++++++++++++++++ src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 8 ++++---- .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 4 ++-- 9 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/feature-gates/auxiliary/pub_dep.rs create mode 100644 src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 1651175525e05..473214a04c8ed 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -126,7 +126,7 @@ declare_lint! { } declare_lint! { - pub LEAKED_PRIVATE_DEPENDENCY, + pub EXTERNAL_PRIVATE_DEPENDENCY, Warn, "public interface leaks type from a private dependency" } @@ -411,7 +411,7 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, - LEAKED_PRIVATE_DEPENDENCY, + EXTERNAL_PRIVATE_DEPENDENCY, PUB_USE_OF_PRIVATE_EXTERN_CRATE, INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 16d3d332e4056..635ac6dcc48f8 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1928,7 +1928,7 @@ pub fn build_session_options_and_crate_config( let mut extern_public: FxHashSet = matches.opt_strs("extern-public"). iter().cloned().collect(); - // TODO - come up with a better way of handling this + // FIXME - come up with a better way of handling this extern_public.insert("core".to_string()); extern_public.insert("std".to_string()); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index b0846822b24e1..46e784c4099c8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1883,5 +1883,3 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { } } - - diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index e2e63b418c72c..66e6368e83da0 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -230,7 +230,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { edition: None, }, FutureIncompatibleInfo { - id: LintId::of(LEAKED_PRIVATE_DEPENDENCY), + id: LintId::of(EXTERNAL_PRIVATE_DEPENDENCY), reference: "issue #44663 ", edition: None, }, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index f37d0ce426003..7b5b06257ce90 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1496,7 +1496,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { if self.leaks_private_dep(def_id) { - self.tcx.lint_node(lint::builtin::LEAKED_PRIVATE_DEPENDENCY, + self.tcx.lint_node(lint::builtin::EXTERNAL_PRIVATE_DEPENDENCY, self.item_id, self.span, &format!("{} `{}` from private dependency '{}' in public \ diff --git a/src/test/ui/feature-gates/auxiliary/pub_dep.rs b/src/test/ui/feature-gates/auxiliary/pub_dep.rs new file mode 100644 index 0000000000000..3ebafd953addf --- /dev/null +++ b/src/test/ui/feature-gates/auxiliary/pub_dep.rs @@ -0,0 +1 @@ +pub struct PubType; diff --git a/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs b/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs new file mode 100644 index 0000000000000..bd27c844fc620 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs @@ -0,0 +1,20 @@ +// This test is different from other feature gate tests. +// Instead of checking that an error occurs without the feature gate, +// it checks that *no* errors/warnings occurs without the feature gate. +// This is due to the fact that 'public_private_dependencies' just enables +// a lint, so disabling it shouldn't cause any code to stop compiling. + +// run-pass +// aux-build:pub_dep.rs + +// Without ![feature(public_private_dependencies)], +// this should do nothing/ +#![deny(external_private_dependency)] + +extern crate pub_dep; + +pub struct Foo { + pub field: pub_dep::PubType +} + +fn main() {} diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index f82c1ad1c93b5..16a59dff8780e 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -2,7 +2,7 @@ // aux-build:pub_dep.rs // compile-flags: --extern-public=pub_dep #![feature(public_private_dependencies)] -#![deny(leaked_private_dependency)] +#![deny(external_private_dependency)] // This crate is a private dependency extern crate priv_dep; @@ -20,7 +20,7 @@ struct PrivateType { pub struct PublicType { pub field: OtherType, - //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] + //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface //~| WARNING this was previously accepted priv_field: OtherType, // Private field - this is fine pub other_field: PubType // Type from public dependency - this is fine @@ -28,7 +28,7 @@ pub struct PublicType { impl PublicType { pub fn pub_fn(param: OtherType) {} - //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface [leaked_private_dependency] + //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface //~| WARNING this was previously accepted fn priv_fn(param: OtherType) {} @@ -37,7 +37,7 @@ impl PublicType { pub trait MyPubTrait { type Foo: OtherTrait; } -//~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface [leaked_private_dependency] +//~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface //~| WARNING this was previously accepted diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index fa74eb2265d0c..9e5bffa6eea3e 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -7,8 +7,8 @@ LL | pub field: OtherType, note: lint level defined here --> $DIR/pub-priv1.rs:5:9 | -LL | #![deny(leaked_private_dependency)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(external_private_dependency)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 #44663 From bc2221f7b6778de779113f1b9021477cf313010b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 22:33:06 -0500 Subject: [PATCH 09/22] Add test for 'std' crate being public --- src/test/ui/privacy/pub-priv-dep/std-pub.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/ui/privacy/pub-priv-dep/std-pub.rs diff --git a/src/test/ui/privacy/pub-priv-dep/std-pub.rs b/src/test/ui/privacy/pub-priv-dep/std-pub.rs new file mode 100644 index 0000000000000..7acf0f89c5dbe --- /dev/null +++ b/src/test/ui/privacy/pub-priv-dep/std-pub.rs @@ -0,0 +1,13 @@ +// The 'std' crates should always be implicitly public, +// without having to pass any compiler arguments + +// run-pass + +#![feature(public_private_dependencies)] +#![deny(external_private_dependency)] + +pub struct PublicType { + pub field: Option +} + +fn main() {} From d8fc6300525a71372300807f9ed76a37ae99649d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 22:39:24 -0500 Subject: [PATCH 10/22] Track extern_public command-line argument --- src/librustc/session/config.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 635ac6dcc48f8..e63336437cdb0 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -414,7 +414,7 @@ top_level_options!( // The list of crates to consider public for // checking leaked private dependency types in public interfaces - extern_public: FxHashSet [UNTRACKED], + extern_public: Vec [TRACKED], } ); @@ -610,7 +610,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, - extern_public: FxHashSet::default() + extern_public: vec![] } } } @@ -1925,12 +1925,12 @@ pub fn build_session_options_and_crate_config( ) } - let mut extern_public: FxHashSet = matches.opt_strs("extern-public"). + let mut extern_public: Vec = matches.opt_strs("extern-public"). iter().cloned().collect(); // FIXME - come up with a better way of handling this - extern_public.insert("core".to_string()); - extern_public.insert("std".to_string()); + extern_public.push("core".to_string()); + extern_public.push("std".to_string()); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); From dfd26696674ecadc39aabcc94314cda8d571f71b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 13 Jan 2019 22:42:36 -0500 Subject: [PATCH 11/22] Delete dead code --- src/librustc_privacy/lib.rs | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 7b5b06257ce90..6a91ec81e4e71 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1552,32 +1552,6 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { } } - -/*struct LeakedPrivateDependenciesVisitor<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - public_crates: FxHashSet -} - -impl<'a, 'tcx> LeakedPrivateDependenciesVisitor<'a, 'tcx> { - fn is_private_dep(&self, item_id: DefId) { - !item_id.is_local() && !self.public_crates.contains(item_id.krate) - } - -} - -impl<'a, 'tcx> Visitor<'tcx> for LeakedPrivateDependenciesVisitor<'a, 'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> nestedvisitormap<'this, 'tcx> { - nestedvisitormap::onlybodies(&self.tcx.hir()) - } - - fn visit_item(&mut self, item: &'tcx hir::Item) { - - } - -}*/ - - - impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx } fn visit_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { From 3fa36471e81011b7b1c44ec66c5aa70a67dfe475 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 20 Jan 2019 22:04:22 -0500 Subject: [PATCH 12/22] Rename external_private_dependency to exported_private_dependencies --- src/librustc/lint/builtin.rs | 4 ++-- src/librustc_lint/lib.rs | 2 +- src/librustc_privacy/lib.rs | 10 ++++++---- .../feature-gate-public_private_dependencies.rs | 2 +- src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 2 +- src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr | 4 ++-- src/test/ui/privacy/pub-priv-dep/std-pub.rs | 2 +- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 473214a04c8ed..3fe544d690640 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -126,7 +126,7 @@ declare_lint! { } declare_lint! { - pub EXTERNAL_PRIVATE_DEPENDENCY, + pub EXPORTED_PRIVATE_DEPENDENCIES, Warn, "public interface leaks type from a private dependency" } @@ -411,7 +411,7 @@ impl LintPass for HardwiredLints { TRIVIAL_CASTS, TRIVIAL_NUMERIC_CASTS, PRIVATE_IN_PUBLIC, - EXTERNAL_PRIVATE_DEPENDENCY, + EXPORTED_PRIVATE_DEPENDENCIES, PUB_USE_OF_PRIVATE_EXTERN_CRATE, INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 66e6368e83da0..128bc70087f94 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -230,7 +230,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { edition: None, }, FutureIncompatibleInfo { - id: LintId::of(EXTERNAL_PRIVATE_DEPENDENCY), + id: LintId::of(EXPORTED_PRIVATE_DEPENDENCIES), reference: "issue #44663 ", edition: None, }, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 6a91ec81e4e71..01694df1df106 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1496,7 +1496,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { if self.leaks_private_dep(def_id) { - self.tcx.lint_node(lint::builtin::EXTERNAL_PRIVATE_DEPENDENCY, + self.tcx.lint_node(lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES, self.item_id, self.span, &format!("{} `{}` from private dependency '{}' in public \ @@ -1726,9 +1726,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Lrc { fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { let empty_tables = ty::TypeckTables::empty(None); - let public_crates: FxHashSet = tcx.sess.opts.extern_public.iter().flat_map(|c| { - tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() - }).collect(); // Check privacy of names not checked in previous compilation stages. let mut visitor = NamePrivacyVisitor { @@ -1765,6 +1762,11 @@ fn privacy_access_levels<'tcx>( queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } + let public_crates: FxHashSet = tcx.sess.opts.extern_public.iter().flat_map(|c| { + tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() + }).collect(); + + // Build up a set of all exported items in the AST. This is a set of all // items which are reachable from external crates based on visibility. let mut visitor = EmbargoVisitor { diff --git a/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs b/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs index bd27c844fc620..b8fb4b8dc19da 100644 --- a/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs +++ b/src/test/ui/feature-gates/feature-gate-public_private_dependencies.rs @@ -9,7 +9,7 @@ // Without ![feature(public_private_dependencies)], // this should do nothing/ -#![deny(external_private_dependency)] +#![deny(exported_private_dependencies)] extern crate pub_dep; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index 16a59dff8780e..7d71dbe6392d4 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -2,7 +2,7 @@ // aux-build:pub_dep.rs // compile-flags: --extern-public=pub_dep #![feature(public_private_dependencies)] -#![deny(external_private_dependency)] +#![deny(exported_private_dependencies)] // This crate is a private dependency extern crate priv_dep; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index 9e5bffa6eea3e..11f4be8cbbc12 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -7,8 +7,8 @@ LL | pub field: OtherType, note: lint level defined here --> $DIR/pub-priv1.rs:5:9 | -LL | #![deny(external_private_dependency)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(exported_private_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 #44663 diff --git a/src/test/ui/privacy/pub-priv-dep/std-pub.rs b/src/test/ui/privacy/pub-priv-dep/std-pub.rs index 7acf0f89c5dbe..3c1520c69027d 100644 --- a/src/test/ui/privacy/pub-priv-dep/std-pub.rs +++ b/src/test/ui/privacy/pub-priv-dep/std-pub.rs @@ -4,7 +4,7 @@ // run-pass #![feature(public_private_dependencies)] -#![deny(external_private_dependency)] +#![deny(exported_private_dependencies)] pub struct PublicType { pub field: Option From 173f5cf1164ded2409f8c019b5cd61b53119078c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 22 Jan 2019 18:37:58 -0500 Subject: [PATCH 13/22] Remove feature gate --- src/libsyntax/feature_gate.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 55eb6723188b9..9dd17b420aa44 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -462,9 +462,6 @@ declare_features! ( // #[optimize(X)] (active, optimize_attribute, "1.34.0", Some(54882), None), - - // Allows using the 'leaked private dependencies' lint - (active, public_private_dependencies, "1.32.0", Some(44663), None), ); declare_features! ( From fe15f7177f59f4ac9e9eb22dff727cd58a097e11 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Jan 2019 16:10:49 -0500 Subject: [PATCH 14/22] Move --extern-public behind -Z unstable-options --- src/librustc/session/config.rs | 39 +++++++++++++++++++--------------- src/librustc_privacy/lib.rs | 14 ++++++------ 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index e63336437cdb0..132a5a2a62bc2 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -414,7 +414,7 @@ top_level_options!( // The list of crates to consider public for // checking leaked private dependency types in public interfaces - extern_public: Vec [TRACKED], + extern_public: Option> [TRACKED], } ); @@ -610,7 +610,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, - extern_public: vec![] + extern_public: None } } } @@ -1917,21 +1917,7 @@ pub fn build_session_options_and_crate_config( let crate_types = parse_crate_types_from_list(unparsed_crate_types) .unwrap_or_else(|e| early_error(error_format, &e[..])); - if matches.opt_present("extern-public") && !nightly_options::is_nightly_build() { - early_error( - ErrorOutputType::default(), - "'--extern-public' is unstable and only \ - available for nightly builds of rustc." - ) - } - - let mut extern_public: Vec = matches.opt_strs("extern-public"). - iter().cloned().collect(); - - // FIXME - come up with a better way of handling this - extern_public.push("core".to_string()); - extern_public.push("std".to_string()); - + let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let mut debugging_opts = build_debugging_options(matches, error_format); @@ -1950,6 +1936,24 @@ pub fn build_session_options_and_crate_config( ); } + if matches.opt_present("extern-public") && !debugging_opts.unstable_options { + early_error( + ErrorOutputType::default(), + "'--extern-public' is unstable and only \ + available for nightly builds of rustc." + ) + } + + let mut extern_public: Option> = matches.opt_str("extern-public"). + map(|s| s.split(',').map(|c| (*c).to_string()).collect()); + + // FIXME - come up with a better way of handling this + if let Some(p) = extern_public.as_mut() { + p.push("core".to_string()); + p.push("std".to_string()); + } + + let mut output_types = BTreeMap::new(); if !debugging_opts.parse_only { for list in matches.opt_strs("emit") { @@ -2488,6 +2492,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option<(String, u64)>); + impl_dep_tracking_hash_via_hash!(Option>); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 01694df1df106..f4f09db1087f4 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1460,7 +1460,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { has_pub_restricted: bool, has_old_errors: bool, in_assoc_ty: bool, - public_crates: FxHashSet + public_crates: Option> } impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { @@ -1538,13 +1538,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { /// 1. It's contained within a public type /// 2. It does not come from a crate marked as public fn leaks_private_dep(&self, item_id: DefId) -> bool { - // Never do any leak checking if the feature is not enabled - if !self.tcx.features().public_private_dependencies { + // Don't do any leak checking if no public crates were specified + if self.public_crates.is_none() { return false } let ret = self.required_visibility == ty::Visibility::Public && !item_id.is_local() && - !self.public_crates.contains(&item_id.krate); + !self.public_crates.as_ref().unwrap().contains(&item_id.krate); debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); @@ -1563,7 +1563,7 @@ struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, has_pub_restricted: bool, old_error_set: &'a NodeSet, - public_crates: FxHashSet + public_crates: Option> } impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { @@ -1762,9 +1762,9 @@ fn privacy_access_levels<'tcx>( queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } - let public_crates: FxHashSet = tcx.sess.opts.extern_public.iter().flat_map(|c| { + let public_crates: Option> = tcx.sess.opts.extern_public.as_ref().map(|s| s.iter().flat_map(|c| { tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() - }).collect(); + }).collect()); // Build up a set of all exported items in the AST. This is a set of all From 45486cce2c22288ad30634743ba307008d0b2a07 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Jan 2019 16:16:57 -0500 Subject: [PATCH 15/22] Tidy fixes --- src/librustc/session/config.rs | 2 +- src/librustc_privacy/lib.rs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 132a5a2a62bc2..8e6a48f9d56bc 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1917,7 +1917,7 @@ pub fn build_session_options_and_crate_config( let crate_types = parse_crate_types_from_list(unparsed_crate_types) .unwrap_or_else(|e| early_error(error_format, &e[..])); - + let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); let mut debugging_opts = build_debugging_options(matches, error_format); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index f4f09db1087f4..4084e0495db5b 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1762,9 +1762,10 @@ fn privacy_access_levels<'tcx>( queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } - let public_crates: Option> = tcx.sess.opts.extern_public.as_ref().map(|s| s.iter().flat_map(|c| { - tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() - }).collect()); + let public_crates: Option> = tcx.sess.opts.extern_public.as_ref() + .map(|s| s.iter().flat_map(|c| { + tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() + }).collect()); // Build up a set of all exported items in the AST. This is a set of all From b29a21fbae8e2c2efb121d998d804a4195065be0 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Jan 2019 17:03:28 -0500 Subject: [PATCH 16/22] Remove feature from test --- src/test/ui/privacy/pub-priv-dep/std-pub.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/privacy/pub-priv-dep/std-pub.rs b/src/test/ui/privacy/pub-priv-dep/std-pub.rs index 3c1520c69027d..e25aa93a02e60 100644 --- a/src/test/ui/privacy/pub-priv-dep/std-pub.rs +++ b/src/test/ui/privacy/pub-priv-dep/std-pub.rs @@ -3,7 +3,6 @@ // run-pass -#![feature(public_private_dependencies)] #![deny(exported_private_dependencies)] pub struct PublicType { From 48ec29d38e031a2b15c7768e94fa8185f3e08847 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 15:33:50 -0500 Subject: [PATCH 17/22] Replace --extern-public with --extern-private --- src/librustc/session/config.rs | 41 ++++++++++--------- src/librustc_privacy/lib.rs | 20 ++++----- src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 3 +- .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 8 ++-- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 8e6a48f9d56bc..6b12e549c3388 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -412,9 +412,9 @@ top_level_options!( edition: Edition [TRACKED], - // The list of crates to consider public for + // The list of crates to consider private when // checking leaked private dependency types in public interfaces - extern_public: Option> [TRACKED], + extern_private: Vec [TRACKED], } ); @@ -610,7 +610,7 @@ impl Default for Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, - extern_public: None + extern_private: Vec::new() } } } @@ -1736,6 +1736,12 @@ pub fn rustc_optgroups() -> Vec { "Specify where an external rust library is located", "NAME=PATH", ), + opt::multi_s( + "", + "extern-private", + "Specify where an extern rust library is located, marking it as a private dependency", + "NAME=PATH", + ), opt::opt_s("", "sysroot", "Override the system root", "PATH"), opt::multi("Z", "", "Set internal debugging options", "FLAG"), opt::opt_s( @@ -1936,22 +1942,7 @@ pub fn build_session_options_and_crate_config( ); } - if matches.opt_present("extern-public") && !debugging_opts.unstable_options { - early_error( - ErrorOutputType::default(), - "'--extern-public' is unstable and only \ - available for nightly builds of rustc." - ) - } - - let mut extern_public: Option> = matches.opt_str("extern-public"). - map(|s| s.split(',').map(|c| (*c).to_string()).collect()); - // FIXME - come up with a better way of handling this - if let Some(p) = extern_public.as_mut() { - p.push("core".to_string()); - p.push("std".to_string()); - } let mut output_types = BTreeMap::new(); @@ -2249,8 +2240,18 @@ pub fn build_session_options_and_crate_config( ); } + if matches.opt_present("extern-private") && !debugging_opts.unstable_options { + early_error( + ErrorOutputType::default(), + "'--extern-private' is unstable and only \ + available for nightly builds of rustc." + ) + } + + let extern_private = matches.opt_strs("extern-private"); + let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new(); - for arg in &matches.opt_strs("extern") { + for arg in matches.opt_strs("extern").into_iter().chain(matches.opt_strs("extern-private")) { let mut parts = arg.splitn(2, '='); let name = parts.next().unwrap_or_else(|| early_error(error_format, "--extern value must not be empty")); @@ -2318,7 +2319,7 @@ pub fn build_session_options_and_crate_config( cli_forced_thinlto_off: disable_thinlto, remap_path_prefix, edition, - extern_public + extern_private }, cfg, ) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4084e0495db5b..0f3c586383363 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1460,7 +1460,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { has_pub_restricted: bool, has_old_errors: bool, in_assoc_ty: bool, - public_crates: Option> + private_crates: FxHashSet } impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { @@ -1538,13 +1538,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { /// 1. It's contained within a public type /// 2. It does not come from a crate marked as public fn leaks_private_dep(&self, item_id: DefId) -> bool { - // Don't do any leak checking if no public crates were specified - if self.public_crates.is_none() { + // Don't do any leak checking if no private crates were specified + if self.private_crates.is_empty() { return false } let ret = self.required_visibility == ty::Visibility::Public && !item_id.is_local() && - !self.public_crates.as_ref().unwrap().contains(&item_id.krate); + self.private_crates.contains(&item_id.krate); debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); @@ -1563,7 +1563,7 @@ struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, has_pub_restricted: bool, old_error_set: &'a NodeSet, - public_crates: Option> + private_crates: FxHashSet } impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { @@ -1601,7 +1601,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { has_pub_restricted: self.has_pub_restricted, has_old_errors, in_assoc_ty: false, - public_crates: self.public_crates.clone() + private_crates: self.private_crates.clone() } } @@ -1762,10 +1762,10 @@ fn privacy_access_levels<'tcx>( queries::check_mod_privacy::ensure(tcx, tcx.hir().local_def_id(module)); } - let public_crates: Option> = tcx.sess.opts.extern_public.as_ref() - .map(|s| s.iter().flat_map(|c| { + let private_crates: FxHashSet = tcx.sess.opts.extern_private.iter() + .flat_map(|c| { tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned() - }).collect()); + }).collect(); // Build up a set of all exported items in the AST. This is a set of all @@ -1810,7 +1810,7 @@ fn privacy_access_levels<'tcx>( tcx, has_pub_restricted, old_error_set: &visitor.old_error_set, - public_crates + private_crates }; krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor)); } diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index 7d71dbe6392d4..9c60284f66c48 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -1,7 +1,6 @@ // aux-build:priv_dep.rs // aux-build:pub_dep.rs - // compile-flags: --extern-public=pub_dep -#![feature(public_private_dependencies)] + // compile-flags: --extern-private priv_dep #![deny(exported_private_dependencies)] // This crate is a private dependency diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index 11f4be8cbbc12..7c701035d2877 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -1,11 +1,11 @@ error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:22:5 + --> $DIR/pub-priv1.rs:21:5 | LL | pub field: OtherType, | ^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/pub-priv1.rs:5:9 + --> $DIR/pub-priv1.rs:4:9 | LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![deny(exported_private_dependencies)] = note: for more information, see issue #44663 error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:30:5 + --> $DIR/pub-priv1.rs:29:5 | LL | pub fn pub_fn(param: OtherType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | pub fn pub_fn(param: OtherType) {} = note: for more information, see issue #44663 error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:37:1 + --> $DIR/pub-priv1.rs:36:1 | LL | / pub trait MyPubTrait { LL | | type Foo: OtherTrait; From a05bfc6aeb8e5be70d15b3296cd4ba68d3578e01 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 15:37:27 -0500 Subject: [PATCH 18/22] Test allowing individual struct field --- src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index 9c60284f66c48..ca77378d3613e 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -39,5 +39,11 @@ pub trait MyPubTrait { //~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface //~| WARNING this was previously accepted +pub struct AllowedPrivType { + #[allow(exported_private_dependencies)] + pub allowed: OtherType +} + + fn main() {} From 24f3595c02064340a85c1b15d1a7c8e670c6d5de Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 16:00:40 -0500 Subject: [PATCH 19/22] Remove unnecessary is_local() check --- src/librustc_privacy/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 0f3c586383363..3d67aeff00e8a 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1536,14 +1536,13 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { /// 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 does not come from a crate marked as public + /// 2. It comes from a private crate fn leaks_private_dep(&self, item_id: DefId) -> bool { // Don't do any leak checking if no private crates were specified if self.private_crates.is_empty() { return false } let ret = self.required_visibility == ty::Visibility::Public && - !item_id.is_local() && self.private_crates.contains(&item_id.krate); From bfcd14dd2b6476980df2a18137d09faf2b796919 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 17:09:31 -0500 Subject: [PATCH 20/22] Add future compat lint declaration --- src/librustc_lint/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 128bc70087f94..6607951d2cd14 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -229,11 +229,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #34537 ", edition: None, }, - FutureIncompatibleInfo { - id: LintId::of(EXPORTED_PRIVATE_DEPENDENCIES), - reference: "issue #44663 ", - edition: None, - }, FutureIncompatibleInfo { id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), reference: "issue #34537 ", From 541d31531322bd1d5f2bf7bb8b9cf4c79d85f01d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 30 Jan 2019 17:28:41 -0500 Subject: [PATCH 21/22] Update tests for future-compat warning removal --- src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 3 --- src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr | 12 ++---------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index ca77378d3613e..9ebc96017fe9c 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -20,7 +20,6 @@ struct PrivateType { pub struct PublicType { pub field: OtherType, //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - //~| WARNING this was previously accepted priv_field: OtherType, // Private field - this is fine pub other_field: PubType // Type from public dependency - this is fine } @@ -28,7 +27,6 @@ pub struct PublicType { impl PublicType { pub fn pub_fn(param: OtherType) {} //~^ ERROR type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - //~| WARNING this was previously accepted fn priv_fn(param: OtherType) {} } @@ -37,7 +35,6 @@ pub trait MyPubTrait { type Foo: OtherTrait; } //~^^^ ERROR trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface -//~| WARNING this was previously accepted pub struct AllowedPrivType { #[allow(exported_private_dependencies)] diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index 7c701035d2877..b31efdbd781dc 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -9,28 +9,20 @@ note: lint level defined here | LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = 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 #44663 error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:29:5 + --> $DIR/pub-priv1.rs:28:5 | LL | pub fn pub_fn(param: OtherType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = 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 #44663 error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:36:1 + --> $DIR/pub-priv1.rs:34:1 | LL | / pub trait MyPubTrait { LL | | type Foo: OtherTrait; LL | | } | |_^ - | - = 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 #44663 error: aborting due to 3 previous errors From 369faaeaffa1b960f8260a1905b1fc34f33a23f6 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 31 Jan 2019 14:36:26 -0500 Subject: [PATCH 22/22] Cleanup unecessary code --- src/librustc/session/config.rs | 10 ---------- src/librustc_privacy/lib.rs | 5 ----- 2 files changed, 15 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 6b12e549c3388..86f676fbf888a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1653,13 +1653,6 @@ pub fn rustc_short_optgroups() -> Vec { for the compiler to emit", "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]", ), - opt::multi_s( - "", - "extern-public", - "Comma separated list of crates to consider 'public' - for linting purposes", - "CRATES", - ), opt::opt_s( "", "crate-name", @@ -1942,9 +1935,6 @@ pub fn build_session_options_and_crate_config( ); } - - - let mut output_types = BTreeMap::new(); if !debugging_opts.parse_only { for list in matches.opt_strs("emit") { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 3d67aeff00e8a..73f83eb6f7a3a 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1538,14 +1538,9 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { /// 1. It's contained within a public type /// 2. It comes from a private crate fn leaks_private_dep(&self, item_id: DefId) -> bool { - // Don't do any leak checking if no private crates were specified - if self.private_crates.is_empty() { - return false - } let ret = self.required_visibility == ty::Visibility::Public && self.private_crates.contains(&item_id.krate); - debug!("leaks_private_dep(item_id={:?})={}", item_id, ret); return ret; }