]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/collector.rs
trans: Collect drop-glue translation item for closure env in fn-once-adapters.
[rust.git] / src / librustc_trans / collector.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Translation Item Collection
12 //! ===========================
13 //!
14 //! This module is responsible for discovering all items that will contribute to
15 //! to code generation of the crate. The important part here is that it not only
16 //! needs to find syntax-level items (functions, structs, etc) but also all
17 //! their monomorphized instantiations. Every non-generic, non-const function
18 //! maps to one LLVM artifact. Every generic function can produce
19 //! from zero to N artifacts, depending on the sets of type arguments it
20 //! is instantiated with.
21 //! This also applies to generic items from other crates: A generic definition
22 //! in crate X might produce monomorphizations that are compiled into crate Y.
23 //! We also have to collect these here.
24 //!
25 //! The following kinds of "translation items" are handled here:
26 //!
27 //! - Functions
28 //! - Methods
29 //! - Closures
30 //! - Statics
31 //! - Drop glue
32 //!
33 //! The following things also result in LLVM artifacts, but are not collected
34 //! here, since we instantiate them locally on demand when needed in a given
35 //! codegen unit:
36 //!
37 //! - Constants
38 //! - Vtables
39 //! - Object Shims
40 //!
41 //!
42 //! General Algorithm
43 //! -----------------
44 //! Let's define some terms first:
45 //!
46 //! - A "translation item" is something that results in a function or global in
47 //!   the LLVM IR of a codegen unit. Translation items do not stand on their
48 //!   own, they can reference other translation items. For example, if function
49 //!   `foo()` calls function `bar()` then the translation item for `foo()`
50 //!   references the translation item for function `bar()`. In general, the
51 //!   definition for translation item A referencing a translation item B is that
52 //!   the LLVM artifact produced for A references the LLVM artifact produced
53 //!   for B.
54 //!
55 //! - Translation items and the references between them for a directed graph,
56 //!   where the translation items are the nodes and references form the edges.
57 //!   Let's call this graph the "translation item graph".
58 //!
59 //! - The translation item graph for a program contains all translation items
60 //!   that are needed in order to produce the complete LLVM IR of the program.
61 //!
62 //! The purpose of the algorithm implemented in this module is to build the
63 //! translation item graph for the current crate. It runs in two phases:
64 //!
65 //! 1. Discover the roots of the graph by traversing the HIR of the crate.
66 //! 2. Starting from the roots, find neighboring nodes by inspecting the MIR
67 //!    representation of the item corresponding to a given node, until no more
68 //!    new nodes are found.
69 //!
70 //! ### Discovering roots
71 //!
72 //! The roots of the translation item graph correspond to the non-generic
73 //! syntactic items in the source code. We find them by walking the HIR of the
74 //! crate, and whenever we hit upon a function, method, or static item, we
75 //! create a translation item consisting of the items DefId and, since we only
76 //! consider non-generic items, an empty type-substitution set.
77 //!
78 //! ### Finding neighbor nodes
79 //! Given a translation item node, we can discover neighbors by inspecting its
80 //! MIR. We walk the MIR and any time we hit upon something that signifies a
81 //! reference to another translation item, we have found a neighbor. Since the
82 //! translation item we are currently at is always monomorphic, we also know the
83 //! concrete type arguments of its neighbors, and so all neighbors again will be
84 //! monomorphic. The specific forms a reference to a neighboring node can take
85 //! in MIR are quite diverse. Here is an overview:
86 //!
87 //! #### Calling Functions/Methods
88 //! The most obvious form of one translation item referencing another is a
89 //! function or method call (represented by a CALL terminator in MIR). But
90 //! calls are not the only thing that might introduce a reference between two
91 //! function translation items, and as we will see below, they are just a
92 //! specialized of the form described next, and consequently will don't get any
93 //! special treatment in the algorithm.
94 //!
95 //! #### Taking a reference to a function or method
96 //! A function does not need to actually be called in order to be a neighbor of
97 //! another function. It suffices to just take a reference in order to introduce
98 //! an edge. Consider the following example:
99 //!
100 //! ```rust
101 //! fn print_val<T: Display>(x: T) {
102 //!     println!("{}", x);
103 //! }
104 //!
105 //! fn call_fn(f: &Fn(i32), x: i32) {
106 //!     f(x);
107 //! }
108 //!
109 //! fn main() {
110 //!     let print_i32 = print_val::<i32>;
111 //!     call_fn(&print_i32, 0);
112 //! }
113 //! ```
114 //! The MIR of none of these functions will contain an explicit call to
115 //! `print_val::<i32>`. Nonetheless, in order to translate this program, we need
116 //! an instance of this function. Thus, whenever we encounter a function or
117 //! method in operand position, we treat it as a neighbor of the current
118 //! translation item. Calls are just a special case of that.
119 //!
120 //! #### Closures
121 //! In a way, closures are a simple case. Since every closure object needs to be
122 //! constructed somewhere, we can reliably discover them by observing
123 //! `RValue::Aggregate` expressions with `AggregateKind::Closure`. This is also
124 //! true for closures inlined from other crates.
125 //!
126 //! #### Drop glue
127 //! Drop glue translation items are introduced by MIR drop-statements. The
128 //! generated translation item will again have drop-glue item neighbors if the
129 //! type to be dropped contains nested values that also need to be dropped. It
130 //! might also have a function item neighbor for the explicit `Drop::drop`
131 //! implementation of its type.
132 //!
133 //! #### Unsizing Casts
134 //! A subtle way of introducing neighbor edges is by casting to a trait object.
135 //! Since the resulting fat-pointer contains a reference to a vtable, we need to
136 //! instantiate all object-save methods of the trait, as we need to store
137 //! pointers to these functions even if they never get called anywhere. This can
138 //! be seen as a special case of taking a function reference.
139 //!
140 //! #### Boxes
141 //! Since `Box` expression have special compiler support, no explicit calls to
142 //! `exchange_malloc()` and `exchange_free()` may show up in MIR, even if the
143 //! compiler will generate them. We have to observe `Rvalue::Box` expressions
144 //! and Box-typed drop-statements for that purpose.
145 //!
146 //!
147 //! Interaction with Cross-Crate Inlining
148 //! -------------------------------------
149 //! The binary of a crate will not only contain machine code for the items
150 //! defined in the source code of that crate. It will also contain monomorphic
151 //! instantiations of any extern generic functions and of functions marked with
152 //! #[inline].
153 //! The collection algorithm handles this more or less transparently. If it is
154 //! about to create a translation item for something with an external `DefId`,
155 //! it will take a look if the MIR for that item is available, and if so just
156 //! proceed normally. If the MIR is not available, it assumes that the item is
157 //! just linked to and no node is created; which is exactly what we want, since
158 //! no machine code should be generated in the current crate for such an item.
159 //!
160 //! Eager and Lazy Collection Mode
161 //! ------------------------------
162 //! Translation item collection can be performed in one of two modes:
163 //!
164 //! - Lazy mode means that items will only be instantiated when actually
165 //!   referenced. The goal is to produce the least amount of machine code
166 //!   possible.
167 //!
168 //! - Eager mode is meant to be used in conjunction with incremental compilation
169 //!   where a stable set of translation items is more important than a minimal
170 //!   one. Thus, eager mode will instantiate drop-glue for every drop-able type
171 //!   in the crate, even of no drop call for that type exists (yet). It will
172 //!   also instantiate default implementations of trait methods, something that
173 //!   otherwise is only done on demand.
174 //!
175 //!
176 //! Open Issues
177 //! -----------
178 //! Some things are not yet fully implemented in the current version of this
179 //! module.
180 //!
181 //! ### Initializers of Constants and Statics
182 //! Since no MIR is constructed yet for initializer expressions of constants and
183 //! statics we cannot inspect these properly.
184 //!
185 //! ### Const Fns
186 //! Ideally, no translation item should be generated for const fns unless there
187 //! is a call to them that cannot be evaluated at compile time. At the moment
188 //! this is not implemented however: a translation item will be produced
189 //! regardless of whether it is actually needed or not.
190
191 use rustc::hir;
192 use rustc::hir::itemlikevisit::ItemLikeVisitor;
193
194 use rustc::hir::map as hir_map;
195 use rustc::hir::def_id::DefId;
196 use rustc::middle::lang_items::{BoxFreeFnLangItem, ExchangeMallocFnLangItem};
197 use rustc::traits;
198 use rustc::ty::subst::{Kind, Substs, Subst};
199 use rustc::ty::{self, TypeFoldable, TyCtxt};
200 use rustc::ty::adjustment::CustomCoerceUnsized;
201 use rustc::mir::{self, Location};
202 use rustc::mir::visit as mir_visit;
203 use rustc::mir::visit::Visitor as MirVisitor;
204
205 use syntax::abi::Abi;
206 use syntax_pos::DUMMY_SP;
207 use base::custom_coerce_unsize_info;
208 use callee::needs_fn_once_adapter_shim;
209 use context::SharedCrateContext;
210 use common::fulfill_obligation;
211 use glue::{self, DropGlueKind};
212 use monomorphize::{self, Instance};
213 use util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
214
215 use trans_item::{TransItem, DefPathBasedNames};
216
217 use std::iter;
218
219 #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
220 pub enum TransItemCollectionMode {
221     Eager,
222     Lazy
223 }
224
225 /// Maps every translation item to all translation items it references in its
226 /// body.
227 pub struct InliningMap<'tcx> {
228     // Maps a source translation item to a range of target translation items
229     // that are potentially inlined by LLVM into the source.
230     // The two numbers in the tuple are the start (inclusive) and
231     // end index (exclusive) within the `targets` vecs.
232     index: FxHashMap<TransItem<'tcx>, (usize, usize)>,
233     targets: Vec<TransItem<'tcx>>,
234 }
235
236 impl<'tcx> InliningMap<'tcx> {
237
238     fn new() -> InliningMap<'tcx> {
239         InliningMap {
240             index: FxHashMap(),
241             targets: Vec::new(),
242         }
243     }
244
245     fn record_inlining_canditates<I>(&mut self,
246                                      source: TransItem<'tcx>,
247                                      targets: I)
248         where I: Iterator<Item=TransItem<'tcx>>
249     {
250         assert!(!self.index.contains_key(&source));
251
252         let start_index = self.targets.len();
253         self.targets.extend(targets);
254         let end_index = self.targets.len();
255         self.index.insert(source, (start_index, end_index));
256     }
257
258     // Internally iterate over all items referenced by `source` which will be
259     // made available for inlining.
260     pub fn with_inlining_candidates<F>(&self, source: TransItem<'tcx>, mut f: F)
261         where F: FnMut(TransItem<'tcx>) {
262         if let Some(&(start_index, end_index)) = self.index.get(&source)
263         {
264             for candidate in &self.targets[start_index .. end_index] {
265                 f(*candidate)
266             }
267         }
268     }
269 }
270
271 pub fn collect_crate_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
272                                                  mode: TransItemCollectionMode)
273                                                  -> (FxHashSet<TransItem<'tcx>>,
274                                                      InliningMap<'tcx>) {
275     // We are not tracking dependencies of this pass as it has to be re-executed
276     // every time no matter what.
277     scx.tcx().dep_graph.with_ignore(|| {
278         let roots = collect_roots(scx, mode);
279
280         debug!("Building translation item graph, beginning at roots");
281         let mut visited = FxHashSet();
282         let mut recursion_depths = DefIdMap();
283         let mut inlining_map = InliningMap::new();
284
285         for root in roots {
286             collect_items_rec(scx,
287                               root,
288                               &mut visited,
289                               &mut recursion_depths,
290                               &mut inlining_map);
291         }
292
293         (visited, inlining_map)
294     })
295 }
296
297 // Find all non-generic items by walking the HIR. These items serve as roots to
298 // start monomorphizing from.
299 fn collect_roots<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
300                            mode: TransItemCollectionMode)
301                            -> Vec<TransItem<'tcx>> {
302     debug!("Collecting roots");
303     let mut roots = Vec::new();
304
305     {
306         let mut visitor = RootCollector {
307             scx: scx,
308             mode: mode,
309             output: &mut roots,
310         };
311
312         scx.tcx().map.krate().visit_all_item_likes(&mut visitor);
313     }
314
315     roots
316 }
317
318 // Collect all monomorphized translation items reachable from `starting_point`
319 fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
320                                    starting_point: TransItem<'tcx>,
321                                    visited: &mut FxHashSet<TransItem<'tcx>>,
322                                    recursion_depths: &mut DefIdMap<usize>,
323                                    inlining_map: &mut InliningMap<'tcx>) {
324     if !visited.insert(starting_point.clone()) {
325         // We've been here already, no need to search again.
326         return;
327     }
328     debug!("BEGIN collect_items_rec({})", starting_point.to_string(scx.tcx()));
329
330     let mut neighbors = Vec::new();
331     let recursion_depth_reset;
332
333     match starting_point {
334         TransItem::DropGlue(t) => {
335             find_drop_glue_neighbors(scx, t, &mut neighbors);
336             recursion_depth_reset = None;
337         }
338         TransItem::Static(node_id) => {
339             let def_id = scx.tcx().map.local_def_id(node_id);
340             let ty = scx.tcx().item_type(def_id);
341             let ty = glue::get_drop_glue_type(scx, ty);
342             neighbors.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
343
344             recursion_depth_reset = None;
345
346             collect_neighbours(scx, Instance::mono(scx, def_id), &mut neighbors);
347         }
348         TransItem::Fn(instance) => {
349             // Keep track of the monomorphization recursion depth
350             recursion_depth_reset = Some(check_recursion_limit(scx.tcx(),
351                                                                instance,
352                                                                recursion_depths));
353             check_type_length_limit(scx.tcx(), instance);
354
355             collect_neighbours(scx, instance, &mut neighbors);
356         }
357     }
358
359     record_inlining_canditates(scx.tcx(), starting_point, &neighbors[..], inlining_map);
360
361     for neighbour in neighbors {
362         collect_items_rec(scx, neighbour, visited, recursion_depths, inlining_map);
363     }
364
365     if let Some((def_id, depth)) = recursion_depth_reset {
366         recursion_depths.insert(def_id, depth);
367     }
368
369     debug!("END collect_items_rec({})", starting_point.to_string(scx.tcx()));
370 }
371
372 fn record_inlining_canditates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
373                                         caller: TransItem<'tcx>,
374                                         callees: &[TransItem<'tcx>],
375                                         inlining_map: &mut InliningMap<'tcx>) {
376     let is_inlining_candidate = |trans_item: &TransItem<'tcx>| {
377         trans_item.needs_local_copy(tcx)
378     };
379
380     let inlining_candidates = callees.into_iter()
381                                      .map(|x| *x)
382                                      .filter(is_inlining_candidate);
383
384     inlining_map.record_inlining_canditates(caller, inlining_candidates);
385 }
386
387 fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
388                                    instance: Instance<'tcx>,
389                                    recursion_depths: &mut DefIdMap<usize>)
390                                    -> (DefId, usize) {
391     let recursion_depth = recursion_depths.get(&instance.def)
392                                           .map(|x| *x)
393                                           .unwrap_or(0);
394     debug!(" => recursion depth={}", recursion_depth);
395
396     // Code that needs to instantiate the same function recursively
397     // more than the recursion limit is assumed to be causing an
398     // infinite expansion.
399     if recursion_depth > tcx.sess.recursion_limit.get() {
400         let error = format!("reached the recursion limit while instantiating `{}`",
401                             instance);
402         if let Some(node_id) = tcx.map.as_local_node_id(instance.def) {
403             tcx.sess.span_fatal(tcx.map.span(node_id), &error);
404         } else {
405             tcx.sess.fatal(&error);
406         }
407     }
408
409     recursion_depths.insert(instance.def, recursion_depth + 1);
410
411     (instance.def, recursion_depth)
412 }
413
414 fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
415                                      instance: Instance<'tcx>)
416 {
417     let type_length = instance.substs.types().flat_map(|ty| ty.walk()).count();
418     debug!(" => type length={}", type_length);
419
420     // Rust code can easily create exponentially-long types using only a
421     // polynomial recursion depth. Even with the default recursion
422     // depth, you can easily get cases that take >2^60 steps to run,
423     // which means that rustc basically hangs.
424     //
425     // Bail out in these cases to avoid that bad user experience.
426     let type_length_limit = tcx.sess.type_length_limit.get();
427     if type_length > type_length_limit {
428         // The instance name is already known to be too long for rustc. Use
429         // `{:.64}` to avoid blasting the user's terminal with thousands of
430         // lines of type-name.
431         let instance_name = instance.to_string();
432         let msg = format!("reached the type-length limit while instantiating `{:.64}...`",
433                           instance_name);
434         let mut diag = if let Some(node_id) = tcx.map.as_local_node_id(instance.def) {
435             tcx.sess.struct_span_fatal(tcx.map.span(node_id), &msg)
436         } else {
437             tcx.sess.struct_fatal(&msg)
438         };
439
440         diag.note(&format!(
441             "consider adding a `#![type_length_limit=\"{}\"]` attribute to your crate",
442             type_length_limit*2));
443         diag.emit();
444         tcx.sess.abort_if_errors();
445     }
446 }
447
448 struct MirNeighborCollector<'a, 'tcx: 'a> {
449     scx: &'a SharedCrateContext<'a, 'tcx>,
450     mir: &'a mir::Mir<'tcx>,
451     output: &'a mut Vec<TransItem<'tcx>>,
452     param_substs: &'tcx Substs<'tcx>
453 }
454
455 impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
456
457     fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
458         debug!("visiting rvalue {:?}", *rvalue);
459
460         match *rvalue {
461             // When doing an cast from a regular pointer to a fat pointer, we
462             // have to instantiate all methods of the trait being cast to, so we
463             // can build the appropriate vtable.
464             mir::Rvalue::Cast(mir::CastKind::Unsize, ref operand, target_ty) => {
465                 let target_ty = monomorphize::apply_param_substs(self.scx,
466                                                                  self.param_substs,
467                                                                  &target_ty);
468                 let source_ty = operand.ty(self.mir, self.scx.tcx());
469                 let source_ty = monomorphize::apply_param_substs(self.scx,
470                                                                  self.param_substs,
471                                                                  &source_ty);
472                 let (source_ty, target_ty) = find_vtable_types_for_unsizing(self.scx,
473                                                                             source_ty,
474                                                                             target_ty);
475                 // This could also be a different Unsize instruction, like
476                 // from a fixed sized array to a slice. But we are only
477                 // interested in things that produce a vtable.
478                 if target_ty.is_trait() && !source_ty.is_trait() {
479                     create_trans_items_for_vtable_methods(self.scx,
480                                                           target_ty,
481                                                           source_ty,
482                                                           self.output);
483                 }
484             }
485             mir::Rvalue::Box(..) => {
486                 let exchange_malloc_fn_def_id =
487                     self.scx
488                         .tcx()
489                         .lang_items
490                         .require(ExchangeMallocFnLangItem)
491                         .unwrap_or_else(|e| self.scx.sess().fatal(&e));
492
493                 assert!(can_have_local_instance(self.scx.tcx(), exchange_malloc_fn_def_id));
494                 let empty_substs = self.scx.empty_substs_for_def_id(exchange_malloc_fn_def_id);
495                 let exchange_malloc_fn_trans_item =
496                     create_fn_trans_item(self.scx,
497                                          exchange_malloc_fn_def_id,
498                                          empty_substs,
499                                          self.param_substs);
500
501                 self.output.push(exchange_malloc_fn_trans_item);
502             }
503             _ => { /* not interesting */ }
504         }
505
506         self.super_rvalue(rvalue, location);
507     }
508
509     fn visit_lvalue(&mut self,
510                     lvalue: &mir::Lvalue<'tcx>,
511                     context: mir_visit::LvalueContext<'tcx>,
512                     location: Location) {
513         debug!("visiting lvalue {:?}", *lvalue);
514
515         if let mir_visit::LvalueContext::Drop = context {
516             let ty = lvalue.ty(self.mir, self.scx.tcx())
517                            .to_ty(self.scx.tcx());
518
519             let ty = monomorphize::apply_param_substs(self.scx,
520                                                       self.param_substs,
521                                                       &ty);
522             assert!(ty.is_normalized_for_trans());
523             let ty = glue::get_drop_glue_type(self.scx, ty);
524             self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
525         }
526
527         self.super_lvalue(lvalue, context, location);
528     }
529
530     fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
531         debug!("visiting operand {:?}", *operand);
532
533         let callee = match *operand {
534             mir::Operand::Constant(ref constant) => {
535                 if let ty::TyFnDef(def_id, substs, _) = constant.ty.sty {
536                     // This is something that can act as a callee, proceed
537                     Some((def_id, substs))
538                 } else {
539                     // This is not a callee, but we still have to look for
540                     // references to `const` items
541                     if let mir::Literal::Item { def_id, substs } = constant.literal {
542                         let substs = monomorphize::apply_param_substs(self.scx,
543                                                                       self.param_substs,
544                                                                       &substs);
545
546                         let instance = Instance::new(def_id, substs).resolve_const(self.scx);
547                         collect_neighbours(self.scx, instance, self.output);
548                     }
549
550                     None
551                 }
552             }
553             _ => None
554         };
555
556         if let Some((callee_def_id, callee_substs)) = callee {
557             debug!(" => operand is callable");
558
559             // `callee_def_id` might refer to a trait method instead of a
560             // concrete implementation, so we have to find the actual
561             // implementation. For example, the call might look like
562             //
563             // std::cmp::partial_cmp(0i32, 1i32)
564             //
565             // Calling do_static_dispatch() here will map the def_id of
566             // `std::cmp::partial_cmp` to the def_id of `i32::partial_cmp<i32>`
567             let dispatched = do_static_dispatch(self.scx,
568                                                 callee_def_id,
569                                                 callee_substs,
570                                                 self.param_substs);
571
572             if let StaticDispatchResult::Dispatched {
573                     def_id: callee_def_id,
574                     substs: callee_substs,
575                     fn_once_adjustment,
576                 } = dispatched {
577                 // if we have a concrete impl (which we might not have
578                 // in the case of something compiler generated like an
579                 // object shim or a closure that is handled differently),
580                 // we check if the callee is something that will actually
581                 // result in a translation item ...
582                 if can_result_in_trans_item(self.scx.tcx(), callee_def_id) {
583                     // ... and create one if it does.
584                     let trans_item = create_fn_trans_item(self.scx,
585                                                           callee_def_id,
586                                                           callee_substs,
587                                                           self.param_substs);
588                     self.output.push(trans_item);
589
590                     // This call will instantiate an FnOnce adapter, which drops
591                     // the closure environment. Therefore we need to make sure
592                     // that we collect the drop-glue for the environment type.
593                     if let Some(env_ty) = fn_once_adjustment {
594                         let env_ty = glue::get_drop_glue_type(self.scx, env_ty);
595                         if self.scx.type_needs_drop(env_ty) {
596                             let dg = DropGlueKind::Ty(env_ty);
597                             self.output.push(TransItem::DropGlue(dg));
598                         }
599                     }
600                 }
601             }
602         }
603
604         self.super_operand(operand, location);
605
606         fn can_result_in_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
607                                               def_id: DefId)
608                                               -> bool {
609             match tcx.item_type(def_id).sty {
610                 ty::TyFnDef(def_id, _, f) => {
611                     // Some constructors also have type TyFnDef but they are
612                     // always instantiated inline and don't result in
613                     // translation item. Same for FFI functions.
614                     if let Some(hir_map::NodeForeignItem(_)) = tcx.map.get_if_local(def_id) {
615                         return false;
616                     }
617
618                     if let Some(adt_def) = f.sig.output().skip_binder().ty_adt_def() {
619                         if adt_def.variants.iter().any(|v| def_id == v.did) {
620                             return false;
621                         }
622                     }
623                 }
624                 ty::TyClosure(..) => {}
625                 _ => return false
626             }
627
628             can_have_local_instance(tcx, def_id)
629         }
630     }
631
632     // This takes care of the "drop_in_place" intrinsic for which we otherwise
633     // we would not register drop-glues.
634     fn visit_terminator_kind(&mut self,
635                              block: mir::BasicBlock,
636                              kind: &mir::TerminatorKind<'tcx>,
637                              location: Location) {
638         let tcx = self.scx.tcx();
639         match *kind {
640             mir::TerminatorKind::Call {
641                 func: mir::Operand::Constant(ref constant),
642                 ref args,
643                 ..
644             } => {
645                 match constant.ty.sty {
646                     ty::TyFnDef(def_id, _, bare_fn_ty)
647                         if is_drop_in_place_intrinsic(tcx, def_id, bare_fn_ty) => {
648                         let operand_ty = args[0].ty(self.mir, tcx);
649                         if let ty::TyRawPtr(mt) = operand_ty.sty {
650                             let operand_ty = monomorphize::apply_param_substs(self.scx,
651                                                                               self.param_substs,
652                                                                               &mt.ty);
653                             let ty = glue::get_drop_glue_type(self.scx, operand_ty);
654                             self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
655                         } else {
656                             bug!("Has the drop_in_place() intrinsic's signature changed?")
657                         }
658                     }
659                     _ => { /* Nothing to do. */ }
660                 }
661             }
662             _ => { /* Nothing to do. */ }
663         }
664
665         self.super_terminator_kind(block, kind, location);
666
667         fn is_drop_in_place_intrinsic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
668                                                 def_id: DefId,
669                                                 bare_fn_ty: &ty::BareFnTy<'tcx>)
670                                                 -> bool {
671             (bare_fn_ty.abi == Abi::RustIntrinsic ||
672              bare_fn_ty.abi == Abi::PlatformIntrinsic) &&
673             tcx.item_name(def_id) == "drop_in_place"
674         }
675     }
676 }
677
678 fn can_have_local_instance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
679                                      def_id: DefId)
680                                      -> bool {
681     tcx.sess.cstore.can_have_local_instance(tcx, def_id)
682 }
683
684 fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
685                                       dg: DropGlueKind<'tcx>,
686                                       output: &mut Vec<TransItem<'tcx>>) {
687     let ty = match dg {
688         DropGlueKind::Ty(ty) => ty,
689         DropGlueKind::TyContents(_) => {
690             // We already collected the neighbors of this item via the
691             // DropGlueKind::Ty variant.
692             return
693         }
694     };
695
696     debug!("find_drop_glue_neighbors: {}", type_to_string(scx.tcx(), ty));
697
698     // Make sure the BoxFreeFn lang-item gets translated if there is a boxed value.
699     if let ty::TyBox(content_type) = ty.sty {
700         let def_id = scx.tcx().require_lang_item(BoxFreeFnLangItem);
701         assert!(can_have_local_instance(scx.tcx(), def_id));
702         let box_free_fn_trans_item =
703             create_fn_trans_item(scx,
704                                  def_id,
705                                  scx.tcx().mk_substs(iter::once(Kind::from(content_type))),
706                                  scx.tcx().intern_substs(&[]));
707
708         output.push(box_free_fn_trans_item);
709     }
710
711     // If the type implements Drop, also add a translation item for the
712     // monomorphized Drop::drop() implementation.
713     let destructor_did = match ty.sty {
714         ty::TyAdt(def, _) => def.destructor(),
715         _ => None
716     };
717
718     if let Some(destructor_did) = destructor_did {
719         use rustc::ty::ToPolyTraitRef;
720
721         let drop_trait_def_id = scx.tcx()
722                                    .lang_items
723                                    .drop_trait()
724                                    .unwrap();
725
726         let self_type_substs = scx.tcx().mk_substs_trait(ty, &[]);
727
728         let trait_ref = ty::TraitRef {
729             def_id: drop_trait_def_id,
730             substs: self_type_substs,
731         }.to_poly_trait_ref();
732
733         let substs = match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
734             traits::VtableImpl(data) => data.substs,
735             _ => bug!()
736         };
737
738         if can_have_local_instance(scx.tcx(), destructor_did) {
739             let trans_item = create_fn_trans_item(scx,
740                                                   destructor_did,
741                                                   substs,
742                                                   scx.tcx().intern_substs(&[]));
743             output.push(trans_item);
744         }
745
746         // This type has a Drop implementation, we'll need the contents-only
747         // version of the glue too.
748         output.push(TransItem::DropGlue(DropGlueKind::TyContents(ty)));
749     }
750
751     // Finally add the types of nested values
752     match ty.sty {
753         ty::TyBool      |
754         ty::TyChar      |
755         ty::TyInt(_)    |
756         ty::TyUint(_)   |
757         ty::TyStr       |
758         ty::TyFloat(_)  |
759         ty::TyRawPtr(_) |
760         ty::TyRef(..)   |
761         ty::TyFnDef(..) |
762         ty::TyFnPtr(_)  |
763         ty::TyNever     |
764         ty::TyDynamic(..)  => {
765             /* nothing to do */
766         }
767         ty::TyAdt(adt_def, substs) => {
768             for field in adt_def.all_fields() {
769                 let field_type = scx.tcx().item_type(field.did);
770                 let field_type = monomorphize::apply_param_substs(scx,
771                                                                   substs,
772                                                                   &field_type);
773                 let field_type = glue::get_drop_glue_type(scx, field_type);
774
775                 if scx.type_needs_drop(field_type) {
776                     output.push(TransItem::DropGlue(DropGlueKind::Ty(field_type)));
777                 }
778             }
779         }
780         ty::TyClosure(def_id, substs) => {
781             for upvar_ty in substs.upvar_tys(def_id, scx.tcx()) {
782                 let upvar_ty = glue::get_drop_glue_type(scx, upvar_ty);
783                 if scx.type_needs_drop(upvar_ty) {
784                     output.push(TransItem::DropGlue(DropGlueKind::Ty(upvar_ty)));
785                 }
786             }
787         }
788         ty::TyBox(inner_type)      |
789         ty::TySlice(inner_type)    |
790         ty::TyArray(inner_type, _) => {
791             let inner_type = glue::get_drop_glue_type(scx, inner_type);
792             if scx.type_needs_drop(inner_type) {
793                 output.push(TransItem::DropGlue(DropGlueKind::Ty(inner_type)));
794             }
795         }
796         ty::TyTuple(args) => {
797             for arg in args {
798                 let arg = glue::get_drop_glue_type(scx, arg);
799                 if scx.type_needs_drop(arg) {
800                     output.push(TransItem::DropGlue(DropGlueKind::Ty(arg)));
801                 }
802             }
803         }
804         ty::TyProjection(_) |
805         ty::TyParam(_)      |
806         ty::TyInfer(_)      |
807         ty::TyAnon(..)      |
808         ty::TyError         => {
809             bug!("encountered unexpected type");
810         }
811     }
812 }
813
814 fn do_static_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
815                                 fn_def_id: DefId,
816                                 fn_substs: &'tcx Substs<'tcx>,
817                                 param_substs: &'tcx Substs<'tcx>)
818                                 -> StaticDispatchResult<'tcx> {
819     debug!("do_static_dispatch(fn_def_id={}, fn_substs={:?}, param_substs={:?})",
820            def_id_to_string(scx.tcx(), fn_def_id),
821            fn_substs,
822            param_substs);
823
824     if let Some(trait_def_id) = scx.tcx().trait_of_item(fn_def_id) {
825         debug!(" => trait method, attempting to find impl");
826         do_static_trait_method_dispatch(scx,
827                                         &scx.tcx().associated_item(fn_def_id),
828                                         trait_def_id,
829                                         fn_substs,
830                                         param_substs)
831     } else {
832         debug!(" => regular function");
833         // The function is not part of an impl or trait, no dispatching
834         // to be done
835         StaticDispatchResult::Dispatched {
836             def_id: fn_def_id,
837             substs: fn_substs,
838             fn_once_adjustment: None,
839         }
840     }
841 }
842
843 enum StaticDispatchResult<'tcx> {
844     // The call could be resolved statically as going to the method with
845     // `def_id` and `substs`.
846     Dispatched {
847         def_id: DefId,
848         substs: &'tcx Substs<'tcx>,
849
850         // If this is a call to a closure that needs an FnOnce adjustment,
851         // this contains the new self type of the call (= type of the closure
852         // environment)
853         fn_once_adjustment: Option<ty::Ty<'tcx>>,
854     },
855     // This goes to somewhere that we don't know at compile-time
856     Unknown
857 }
858
859 // Given a trait-method and substitution information, find out the actual
860 // implementation of the trait method.
861 fn do_static_trait_method_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
862                                              trait_method: &ty::AssociatedItem,
863                                              trait_id: DefId,
864                                              callee_substs: &'tcx Substs<'tcx>,
865                                              param_substs: &'tcx Substs<'tcx>)
866                                              -> StaticDispatchResult<'tcx> {
867     let tcx = scx.tcx();
868     debug!("do_static_trait_method_dispatch(trait_method={}, \
869                                             trait_id={}, \
870                                             callee_substs={:?}, \
871                                             param_substs={:?}",
872            def_id_to_string(scx.tcx(), trait_method.def_id),
873            def_id_to_string(scx.tcx(), trait_id),
874            callee_substs,
875            param_substs);
876
877     let rcvr_substs = monomorphize::apply_param_substs(scx,
878                                                        param_substs,
879                                                        &callee_substs);
880     let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
881     let vtbl = fulfill_obligation(scx, DUMMY_SP, ty::Binder(trait_ref));
882
883     // Now that we know which impl is being used, we can dispatch to
884     // the actual function:
885     match vtbl {
886         traits::VtableImpl(impl_data) => {
887             let (def_id, substs) = traits::find_method(tcx,
888                                                        trait_method.name,
889                                                        rcvr_substs,
890                                                        &impl_data);
891             StaticDispatchResult::Dispatched {
892                 def_id: def_id,
893                 substs: substs,
894                 fn_once_adjustment: None,
895             }
896         }
897         traits::VtableClosure(closure_data) => {
898             let closure_def_id = closure_data.closure_def_id;
899             let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
900             let actual_closure_kind = tcx.closure_kind(closure_def_id);
901
902             let needs_fn_once_adapter_shim =
903                 match needs_fn_once_adapter_shim(actual_closure_kind,
904                                                  trait_closure_kind) {
905                 Ok(true) => true,
906                 _ => false,
907             };
908
909             let fn_once_adjustment = if needs_fn_once_adapter_shim {
910                 Some(tcx.mk_closure_from_closure_substs(closure_def_id,
911                                                         closure_data.substs))
912             } else {
913                 None
914             };
915
916             StaticDispatchResult::Dispatched {
917                 def_id: closure_def_id,
918                 substs: closure_data.substs.substs,
919                 fn_once_adjustment: fn_once_adjustment,
920             }
921         }
922         // Trait object and function pointer shims are always
923         // instantiated in-place, and as they are just an ABI-adjusting
924         // indirect call they do not have any dependencies.
925         traits::VtableFnPointer(..) |
926         traits::VtableObject(..) => {
927             StaticDispatchResult::Unknown
928         }
929         _ => {
930             bug!("static call to invalid vtable: {:?}", vtbl)
931         }
932     }
933 }
934
935 /// For given pair of source and target type that occur in an unsizing coercion,
936 /// this function finds the pair of types that determines the vtable linking
937 /// them.
938 ///
939 /// For example, the source type might be `&SomeStruct` and the target type\
940 /// might be `&SomeTrait` in a cast like:
941 ///
942 /// let src: &SomeStruct = ...;
943 /// let target = src as &SomeTrait;
944 ///
945 /// Then the output of this function would be (SomeStruct, SomeTrait) since for
946 /// constructing the `target` fat-pointer we need the vtable for that pair.
947 ///
948 /// Things can get more complicated though because there's also the case where
949 /// the unsized type occurs as a field:
950 ///
951 /// ```rust
952 /// struct ComplexStruct<T: ?Sized> {
953 ///    a: u32,
954 ///    b: f64,
955 ///    c: T
956 /// }
957 /// ```
958 ///
959 /// In this case, if `T` is sized, `&ComplexStruct<T>` is a thin pointer. If `T`
960 /// is unsized, `&SomeStruct` is a fat pointer, and the vtable it points to is
961 /// for the pair of `T` (which is a trait) and the concrete type that `T` was
962 /// originally coerced from:
963 ///
964 /// let src: &ComplexStruct<SomeStruct> = ...;
965 /// let target = src as &ComplexStruct<SomeTrait>;
966 ///
967 /// Again, we want this `find_vtable_types_for_unsizing()` to provide the pair
968 /// `(SomeStruct, SomeTrait)`.
969 ///
970 /// Finally, there is also the case of custom unsizing coercions, e.g. for
971 /// smart pointers such as `Rc` and `Arc`.
972 fn find_vtable_types_for_unsizing<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
973                                             source_ty: ty::Ty<'tcx>,
974                                             target_ty: ty::Ty<'tcx>)
975                                             -> (ty::Ty<'tcx>, ty::Ty<'tcx>) {
976     match (&source_ty.sty, &target_ty.sty) {
977         (&ty::TyBox(a), &ty::TyBox(b)) |
978         (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }),
979          &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) |
980         (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }),
981          &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) |
982         (&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }),
983          &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => {
984             let (inner_source, inner_target) = (a, b);
985
986             if !scx.type_is_sized(inner_source) {
987                 (inner_source, inner_target)
988             } else {
989                 scx.tcx().struct_lockstep_tails(inner_source, inner_target)
990             }
991         }
992
993         (&ty::TyAdt(source_adt_def, source_substs),
994          &ty::TyAdt(target_adt_def, target_substs)) => {
995             assert_eq!(source_adt_def, target_adt_def);
996
997             let kind = custom_coerce_unsize_info(scx, source_ty, target_ty);
998
999             let coerce_index = match kind {
1000                 CustomCoerceUnsized::Struct(i) => i
1001             };
1002
1003             let source_fields = &source_adt_def.struct_variant().fields;
1004             let target_fields = &target_adt_def.struct_variant().fields;
1005
1006             assert!(coerce_index < source_fields.len() &&
1007                     source_fields.len() == target_fields.len());
1008
1009             find_vtable_types_for_unsizing(scx,
1010                                            source_fields[coerce_index].ty(scx.tcx(),
1011                                                                           source_substs),
1012                                            target_fields[coerce_index].ty(scx.tcx(),
1013                                                                           target_substs))
1014         }
1015         _ => bug!("find_vtable_types_for_unsizing: invalid coercion {:?} -> {:?}",
1016                   source_ty,
1017                   target_ty)
1018     }
1019 }
1020
1021 fn create_fn_trans_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
1022                                   def_id: DefId,
1023                                   fn_substs: &'tcx Substs<'tcx>,
1024                                   param_substs: &'tcx Substs<'tcx>)
1025                                   -> TransItem<'tcx> {
1026     let tcx = scx.tcx();
1027
1028     debug!("create_fn_trans_item(def_id={}, fn_substs={:?}, param_substs={:?})",
1029             def_id_to_string(tcx, def_id),
1030             fn_substs,
1031             param_substs);
1032
1033     // We only get here, if fn_def_id either designates a local item or
1034     // an inlineable external item. Non-inlineable external items are
1035     // ignored because we don't want to generate any code for them.
1036     let concrete_substs = monomorphize::apply_param_substs(scx,
1037                                                            param_substs,
1038                                                            &fn_substs);
1039     assert!(concrete_substs.is_normalized_for_trans(),
1040             "concrete_substs not normalized for trans: {:?}",
1041             concrete_substs);
1042     TransItem::Fn(Instance::new(def_id, concrete_substs))
1043 }
1044
1045 /// Creates a `TransItem` for each method that is referenced by the vtable for
1046 /// the given trait/impl pair.
1047 fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
1048                                                    trait_ty: ty::Ty<'tcx>,
1049                                                    impl_ty: ty::Ty<'tcx>,
1050                                                    output: &mut Vec<TransItem<'tcx>>) {
1051     assert!(!trait_ty.needs_subst() && !impl_ty.needs_subst());
1052
1053     if let ty::TyDynamic(ref trait_ty, ..) = trait_ty.sty {
1054         if let Some(principal) = trait_ty.principal() {
1055             let poly_trait_ref = principal.with_self_ty(scx.tcx(), impl_ty);
1056             let param_substs = scx.tcx().intern_substs(&[]);
1057
1058             // Walk all methods of the trait, including those of its supertraits
1059             let methods = traits::get_vtable_methods(scx.tcx(), poly_trait_ref);
1060             let methods = methods.filter_map(|method| method)
1061                 .filter_map(|(def_id, substs)| {
1062                     if let StaticDispatchResult::Dispatched {
1063                         def_id,
1064                         substs,
1065                         // We already add the drop-glue for the closure env
1066                         // unconditionally below.
1067                         fn_once_adjustment: _ ,
1068                     } = do_static_dispatch(scx, def_id, substs, param_substs) {
1069                         Some((def_id, substs))
1070                     } else {
1071                         None
1072                     }
1073                 })
1074                 .filter(|&(def_id, _)| can_have_local_instance(scx.tcx(), def_id))
1075                 .map(|(def_id, substs)| create_fn_trans_item(scx, def_id, substs, param_substs));
1076             output.extend(methods);
1077         }
1078         // Also add the destructor
1079         let dg_type = glue::get_drop_glue_type(scx, impl_ty);
1080         output.push(TransItem::DropGlue(DropGlueKind::Ty(dg_type)));
1081     }
1082 }
1083
1084 //=-----------------------------------------------------------------------------
1085 // Root Collection
1086 //=-----------------------------------------------------------------------------
1087
1088 struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> {
1089     scx: &'b SharedCrateContext<'a, 'tcx>,
1090     mode: TransItemCollectionMode,
1091     output: &'b mut Vec<TransItem<'tcx>>,
1092 }
1093
1094 impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
1095     fn visit_item(&mut self, item: &'v hir::Item) {
1096         match item.node {
1097             hir::ItemExternCrate(..) |
1098             hir::ItemUse(..)         |
1099             hir::ItemForeignMod(..)  |
1100             hir::ItemTy(..)          |
1101             hir::ItemDefaultImpl(..) |
1102             hir::ItemTrait(..)       |
1103             hir::ItemMod(..)         => {
1104                 // Nothing to do, just keep recursing...
1105             }
1106
1107             hir::ItemImpl(..) => {
1108                 if self.mode == TransItemCollectionMode::Eager {
1109                     create_trans_items_for_default_impls(self.scx,
1110                                                          item,
1111                                                          self.output);
1112                 }
1113             }
1114
1115             hir::ItemEnum(_, ref generics) |
1116             hir::ItemStruct(_, ref generics) |
1117             hir::ItemUnion(_, ref generics) => {
1118                 if !generics.is_parameterized() {
1119                     if self.mode == TransItemCollectionMode::Eager {
1120                         let def_id = self.scx.tcx().map.local_def_id(item.id);
1121                         debug!("RootCollector: ADT drop-glue for {}",
1122                                def_id_to_string(self.scx.tcx(), def_id));
1123
1124                         let ty = self.scx.tcx().item_type(def_id);
1125                         let ty = glue::get_drop_glue_type(self.scx, ty);
1126                         self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
1127                     }
1128                 }
1129             }
1130             hir::ItemStatic(..) => {
1131                 debug!("RootCollector: ItemStatic({})",
1132                        def_id_to_string(self.scx.tcx(),
1133                                         self.scx.tcx().map.local_def_id(item.id)));
1134                 self.output.push(TransItem::Static(item.id));
1135             }
1136             hir::ItemConst(..) => {
1137                 // const items only generate translation items if they are
1138                 // actually used somewhere. Just declaring them is insufficient.
1139             }
1140             hir::ItemFn(.., ref generics, _) => {
1141                 if !generics.is_type_parameterized() {
1142                     let def_id = self.scx.tcx().map.local_def_id(item.id);
1143
1144                     debug!("RootCollector: ItemFn({})",
1145                            def_id_to_string(self.scx.tcx(), def_id));
1146
1147                     let instance = Instance::mono(self.scx, def_id);
1148                     self.output.push(TransItem::Fn(instance));
1149                 }
1150             }
1151         }
1152     }
1153
1154     fn visit_trait_item(&mut self, _: &'v hir::TraitItem) {
1155         // Even if there's a default body with no explicit generics,
1156         // it's still generic over some `Self: Trait`, so not a root.
1157     }
1158
1159     fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
1160         match ii.node {
1161             hir::ImplItemKind::Method(hir::MethodSig {
1162                 ref generics,
1163                 ..
1164             }, _) => {
1165                 let hir_map = &self.scx.tcx().map;
1166                 let parent_node_id = hir_map.get_parent_node(ii.id);
1167                 let is_impl_generic = match hir_map.expect_item(parent_node_id) {
1168                     &hir::Item {
1169                         node: hir::ItemImpl(_, _, ref generics, ..),
1170                         ..
1171                     } => {
1172                         generics.is_type_parameterized()
1173                     }
1174                     _ => {
1175                         bug!()
1176                     }
1177                 };
1178
1179                 if !generics.is_type_parameterized() && !is_impl_generic {
1180                     let def_id = self.scx.tcx().map.local_def_id(ii.id);
1181
1182                     debug!("RootCollector: MethodImplItem({})",
1183                            def_id_to_string(self.scx.tcx(), def_id));
1184
1185                     let instance = Instance::mono(self.scx, def_id);
1186                     self.output.push(TransItem::Fn(instance));
1187                 }
1188             }
1189             _ => { /* Nothing to do here */ }
1190         }
1191     }
1192 }
1193
1194 fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
1195                                                   item: &'tcx hir::Item,
1196                                                   output: &mut Vec<TransItem<'tcx>>) {
1197     let tcx = scx.tcx();
1198     match item.node {
1199         hir::ItemImpl(_,
1200                       _,
1201                       ref generics,
1202                       ..,
1203                       ref impl_item_refs) => {
1204             if generics.is_type_parameterized() {
1205                 return
1206             }
1207
1208             let impl_def_id = tcx.map.local_def_id(item.id);
1209
1210             debug!("create_trans_items_for_default_impls(item={})",
1211                    def_id_to_string(tcx, impl_def_id));
1212
1213             if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
1214                 let callee_substs = tcx.erase_regions(&trait_ref.substs);
1215                 let overridden_methods: FxHashSet<_> =
1216                     impl_item_refs.iter()
1217                                   .map(|iiref| iiref.name)
1218                                   .collect();
1219                 for method in tcx.provided_trait_methods(trait_ref.def_id) {
1220                     if overridden_methods.contains(&method.name) {
1221                         continue;
1222                     }
1223
1224                     if !tcx.item_generics(method.def_id).types.is_empty() {
1225                         continue;
1226                     }
1227
1228                     // The substitutions we have are on the impl, so we grab
1229                     // the method type from the impl to substitute into.
1230                     let impl_substs = Substs::for_item(tcx, impl_def_id,
1231                                                        |_, _| tcx.mk_region(ty::ReErased),
1232                                                        |_, _| tcx.types.err);
1233                     let impl_data = traits::VtableImplData {
1234                         impl_def_id: impl_def_id,
1235                         substs: impl_substs,
1236                         nested: vec![]
1237                     };
1238                     let (def_id, substs) = traits::find_method(tcx,
1239                                                                method.name,
1240                                                                callee_substs,
1241                                                                &impl_data);
1242
1243                     let predicates = tcx.item_predicates(def_id).predicates
1244                                         .subst(tcx, substs);
1245                     if !traits::normalize_and_test_predicates(tcx, predicates) {
1246                         continue;
1247                     }
1248
1249                     if can_have_local_instance(tcx, method.def_id) {
1250                         let item = create_fn_trans_item(scx,
1251                                                         method.def_id,
1252                                                         callee_substs,
1253                                                         tcx.erase_regions(&substs));
1254                         output.push(item);
1255                     }
1256                 }
1257             }
1258         }
1259         _ => {
1260             bug!()
1261         }
1262     }
1263 }
1264
1265 /// Scan the MIR in order to find function calls, closures, and drop-glue
1266 fn collect_neighbours<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
1267                                 instance: Instance<'tcx>,
1268                                 output: &mut Vec<TransItem<'tcx>>)
1269 {
1270     let mir = scx.tcx().item_mir(instance.def);
1271
1272     let mut visitor = MirNeighborCollector {
1273         scx: scx,
1274         mir: &mir,
1275         output: output,
1276         param_substs: instance.substs
1277     };
1278
1279     visitor.visit_mir(&mir);
1280     for promoted in &mir.promoted {
1281         visitor.visit_mir(promoted);
1282     }
1283 }
1284
1285 fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1286                               def_id: DefId)
1287                               -> String {
1288     let mut output = String::new();
1289     let printer = DefPathBasedNames::new(tcx, false, false);
1290     printer.push_def_path(def_id, &mut output);
1291     output
1292 }
1293
1294 fn type_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1295                             ty: ty::Ty<'tcx>)
1296                             -> String {
1297     let mut output = String::new();
1298     let printer = DefPathBasedNames::new(tcx, false, false);
1299     printer.push_type_name(ty, &mut output);
1300     output
1301 }