Skip to content

Implement public/private dependency feature #57586

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Feb 1, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move --extern-public behind -Z unstable-options
  • Loading branch information
Aaron1011 committed Feb 1, 2019
commit fe15f7177f59f4ac9e9eb22dff727cd58a097e11
39 changes: 22 additions & 17 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> [TRACKED],
extern_public: Option<Vec<String>> [TRACKED],
}
);

Expand Down Expand Up @@ -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
}
}
}
Expand Down Expand Up @@ -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<String> = 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);
Expand All @@ -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<Vec<String>> = 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") {
Expand Down Expand Up @@ -2488,6 +2492,7 @@ mod dep_tracking {
impl_dep_tracking_hash_via_hash!(Option<usize>);
impl_dep_tracking_hash_via_hash!(Option<String>);
impl_dep_tracking_hash_via_hash!(Option<(String, u64)>);
impl_dep_tracking_hash_via_hash!(Option<Vec<String>>);
impl_dep_tracking_hash_via_hash!(Option<MergeFunctions>);
impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
Expand Down
14 changes: 7 additions & 7 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1460,7 +1460,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
has_pub_restricted: bool,
has_old_errors: bool,
in_assoc_ty: bool,
public_crates: FxHashSet<CrateNum>
public_crates: Option<FxHashSet<CrateNum>>
}

impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
Expand Down Expand Up @@ -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 &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will report things used in pub, but unreachable items, e.g.

mod private_details {
    pub fn details() -> PrivateDep { ... } // Will be linted
}

, but that's probably okay for a start.

!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);
Expand All @@ -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<CrateNum>
public_crates: Option<FxHashSet<CrateNum>>
}

impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
Expand Down Expand Up @@ -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<CrateNum> = tcx.sess.opts.extern_public.iter().flat_map(|c| {
let public_crates: Option<FxHashSet<CrateNum>> = 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
Expand Down