Change:
This was working previously before . If this is an intended change, we should probably give the error where the re-export is defined and not on use of the trait.
I've noticed this too while compiling nphysics, I've narrowed it to The error is I'm using .
I'm facing the same problem for quite some time now (currently rustc 1.0.0-nightly ( 2015-01-20 23:03:09 +0000)). Is this a bug or is it intended behavior?
is this expected?
Just ran into this bug in my code, would love to see a fix for this!
Im also still running into this from time to time (rustc 1.3.0). I'd love to see it fixed or clarified whether this is intended or a bug.
I also have this with rustc nightly (from PPA: "~~wily")
I think this is a bug, actually. do you agree?
yes I realize I'm responding to a comment from Jan 28 :) a bit late, I know
this was "fixed" by but reverted by due to a regression. Personally, I think that the correct fix for the regression should be to make a privacy error, but as far as I can tell, it's not easy to implement this currently, and it's likely to cause further regressions. Trait privacy is hard :(
better late than never :heart:
yeah this looks like a bug to me, and I think is right in that is probably the right fix if we deal with , which I think is the cause of some other visibility/privacy bug around here...
This can be simplified even further to: Also an additional note, this only affects usage in the same crate. Other crates are able to use the re-exports fine.
Still a bug in 1.6 :cry:
+1
still a bug in cargo 0.8.0-nightly ( 2016-01-17)
For those who may fall on this issue, it can be bypassed by using the UFCS syntax: . For example becomes

Discussion:
} impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { <del> // used when debugging fn nodestr(&self, id: ast::NodeId) -> String { self.tcx.map.node_to_string(id).to_string() } </del> // Determines whether the given definition is public from the point of view // of the current item. fn def_privacy(&self, did: DefId) -> PrivacyResult {

return Allowable; } <del> // We now know that there is at least one private member between the // destination and the root. let mut closest_private_id = node_id; loop { debug!("privacy - examining {}", self.nodestr(closest_private_id)); let vis = match self.tcx.map.find(closest_private_id) { // If this item is a method, then we know for sure that it's an // actual method and not a static method. The reason for this is // that these cases are only hit in the ExprMethodCall // expression, and ExprCall will have its path checked later // (the path of the trait/impl) if it's a static method. // // With this information, then we can completely ignore all // trait methods. The privacy violation would be if the trait // couldn't get imported, not if the method couldn't be used // (all trait methods are public). // // However, if this is an impl method, then we dictate this // decision solely based on the privacy of the method // invocation. // FIXME(#10573) is this the right behavior? Why not consider //               where the method was defined? Some(ast_map::NodeImplItem(ii)) => { match ii.node { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => { let imp = self.tcx.map .get_parent_did(closest_private_id); match self.tcx.impl_trait_ref(imp) { Some(..) => return Allowable, _ if ii.vis == hir::Public => { return Allowable } _ => ii.vis } } hir::ImplItemKind::Type(_) => return Allowable, } } Some(ast_map::NodeTraitItem(_)) => { return Allowable; </del> <ins> let vis = match self.tcx.map.find(node_id) { // If this item is a method, then we know for sure that it's an // actual method and not a static method. The reason for this is // that these cases are only hit in the ExprMethodCall // expression, and ExprCall will have its path checked later // (the path of the trait/impl) if it's a static method. // // With this information, then we can completely ignore all // trait methods. The privacy violation would be if the trait // couldn't get imported, not if the method couldn't be used // (all trait methods are public). // // However, if this is an impl method, then we dictate this // decision solely based on the privacy of the method // invocation. Some(ast_map::NodeImplItem(ii)) => { let imp = self.tcx.map.get_parent_did(node_id); match self.tcx.impl_trait_ref(imp) { Some(..) => hir::Public, _ => ii.vis, </ins> } <ins> } Some(ast_map::NodeTraitItem(_)) => hir::Public, </ins> <del> // This is not a method call, extract the visibility as one // would normally look at it Some(ast_map::NodeItem(it)) => it.vis, Some(ast_map::NodeForeignItem(_)) => { self.tcx.map.get_foreign_vis(closest_private_id) } Some(ast_map::NodeVariant(..)) => { hir::Public // need to move up a level (to the enum) } _ => hir::Public, }; if vis != hir::Public { break } // if we've reached the root, then everything was allowable and this // access is public. if closest_private_id == ast::CRATE_NODE_ID { return Allowable } closest_private_id = *self.parents.get(&closest_private_id).unwrap(); // If we reached the top, then we were public all the way down and // we can allow this access. if closest_private_id == ast::DUMMY_NODE_ID { return Allowable } } debug!("privacy - closest priv {}", self.nodestr(closest_private_id)); if self.private_accessible(closest_private_id) { </del> <ins> // This is not a method call, extract the visibility as one // would normally look at it Some(ast_map::NodeItem(it)) => it.vis, Some(ast_map::NodeForeignItem(_)) => { self.tcx.map.get_foreign_vis(node_id) } _ => hir::Public, }; if vis == hir::Public { return Allowable } if self.private_accessible(node_id) { </ins> Allowable } else { <del> DisallowedBy(closest_private_id) </del> <ins> DisallowedBy(node_id) </ins> } }

// Trait methods are always all public. The only controlling factor // is whether the trait itself is accessible or not. ty::TraitContainer(trait_def_id) => { <del> self.report_error(self.ensure_public(span, trait_def_id, None, "source trait")); </del> <ins> let msg = format!("source trait `{}`", self.tcx.item_path_str(trait_def_id)); self.report_error(self.ensure_public(span, trait_def_id, None, &msg)); </ins> } } }

impl m::Pub for S {} fn g<T: m::Pub>(arg: T) { <del> arg.f(); //~ ERROR: source trait is private </del> <ins> arg.f(); //~ ERROR: source trait `m::Priv` is private </ins> } fn main() {

<ins> // Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(rustc_attrs)] #![allow(dead_code)] mod foo { pub use self::bar::T; mod bar { pub trait T { fn f(&self) {} } impl T for () {} } } fn g() { use foo::T; ().f(); // Check that this does not trigger a privacy error } #[rustc_error] fn main() {} //~ ERROR compilation successful </ins>