diff options
| author | bors <bors@rust-lang.org> | 2016-12-11 06:37:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-12-11 06:37:19 +0000 |
| commit | 368e092c26d40da2d4442bf7cf1b6e4df13a6f87 (patch) | |
| tree | 95d7ee7e177aad13fd902ce731fd3cbb421b3d1b /src/librustc/middle | |
| parent | ea798527e42379af207b3da9e9aef41fd7e812c8 (diff) | |
| parent | 5d35dfb01edd8f53862ac30e1eaec2cea40bace9 (diff) | |
| download | rust-368e092c26d40da2d4442bf7cf1b6e4df13a6f87.tar.gz rust-368e092c26d40da2d4442bf7cf1b6e4df13a6f87.zip | |
Auto merge of #38250 - michaelwoerister:trait-methods-in-reachable, r=alexcrichton
Consider provided trait methods in middle::reachable Fixes https://github.com/rust-lang/rust/issues/38226 by also considering trait methods with default implementation instead of just methods provided in an impl. r? @alexcrichton cc @panicbit
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, }; |
