diff options
| author | Michael Woerister <michaelwoerister@posteo.net> | 2016-12-08 16:55:51 -0500 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo.net> | 2016-12-08 17:06:56 -0500 |
| commit | d602d7b97e737c461fdd0ff724d092ec53707157 (patch) | |
| tree | b75979205d659c8dfc482abd0ff9394b0a6025e6 /src/librustc/middle | |
| parent | 209308439a1099b285520459f57e380f18793c07 (diff) | |
| download | rust-d602d7b97e737c461fdd0ff724d092ec53707157.tar.gz rust-d602d7b97e737c461fdd0ff724d092ec53707157.zip | |
Extend middle::reachable to also consider provided trait methods.
Diffstat (limited to 'src/librustc/middle')
| -rw-r--r-- | src/librustc/middle/reachable.rs | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 9798b2d587d..2c4710f1e45 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -323,19 +323,37 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // items of non-exported traits (or maybe all local traits?) unless their respective // trait items are used from inlinable code through method call syntax or UFCS, or their // trait is a lang item. -struct CollectPrivateImplItemsVisitor<'a> { +struct CollectPrivateImplItemsVisitor<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, access_levels: &'a privacy::AccessLevels, worklist: &'a mut Vec<ast::NodeId>, } -impl<'a, 'v> ItemLikeVisitor<'v> for CollectPrivateImplItemsVisitor<'a> { +impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { // We need only trait impls here, not inherent impls, and only non-exported ones - if let hir::ItemImpl(.., Some(_), _, ref impl_item_refs) = item.node { + if let hir::ItemImpl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.node { if !self.access_levels.is_reachable(item.id) { for impl_item_ref in impl_item_refs { self.worklist.push(impl_item_ref.id.node_id); } + + let trait_def_id = match trait_ref.path.def { + Def::Trait(def_id) => def_id, + _ => unreachable!() + }; + + if !trait_def_id.is_local() { + return + } + + for default_method in self.tcx.provided_trait_methods(trait_def_id) { + let node_id = self.tcx + .map + .as_local_node_id(default_method.def_id) + .unwrap(); + self.worklist.push(node_id); + } } } } @@ -369,6 +387,7 @@ pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } { let mut collect_private_impl_items = CollectPrivateImplItemsVisitor { + tcx: tcx, access_levels: access_levels, worklist: &mut reachable_context.worklist, }; |
