]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/clean/auto_trait.rs
Fix rustdoc crash when 'static bound appears in struct declaration
[rust.git] / src / librustdoc / clean / auto_trait.rs
1 // Copyright 2018 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 use rustc::hir;
12 use rustc::traits::{self, auto_trait as auto};
13 use rustc::ty::{self, ToPredicate, TypeFoldable};
14 use rustc::ty::subst::Subst;
15 use rustc::infer::InferOk;
16 use std::fmt::Debug;
17 use syntax_pos::DUMMY_SP;
18
19 use core::DocAccessLevels;
20
21 use super::*;
22
23 pub struct AutoTraitFinder<'a, 'tcx: 'a, 'rcx: 'a> {
24     pub cx: &'a core::DocContext<'a, 'tcx, 'rcx>,
25     pub f: auto::AutoTraitFinder<'a, 'tcx>,
26 }
27
28 impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
29     pub fn new(cx: &'a core::DocContext<'a, 'tcx, 'rcx>) -> Self {
30         let f = auto::AutoTraitFinder::new(&cx.tcx);
31
32         AutoTraitFinder { cx, f }
33     }
34
35     pub fn get_with_def_id(&self, def_id: DefId) -> Vec<Item> {
36         let ty = self.cx.tcx.type_of(def_id);
37
38         let def_ctor: fn(DefId) -> Def = match ty.sty {
39             ty::TyAdt(adt, _) => match adt.adt_kind() {
40                 AdtKind::Struct => Def::Struct,
41                 AdtKind::Enum => Def::Enum,
42                 AdtKind::Union => Def::Union,
43             }
44             ty::TyInt(_) |
45             ty::TyUint(_) |
46             ty::TyFloat(_) |
47             ty::TyStr |
48             ty::TyBool |
49             ty::TyChar => return self.get_auto_trait_impls(def_id, &move |_: DefId| {
50                 match ty.sty {
51                     ty::TyInt(x) => Def::PrimTy(hir::TyInt(x)),
52                     ty::TyUint(x) => Def::PrimTy(hir::TyUint(x)),
53                     ty::TyFloat(x) => Def::PrimTy(hir::TyFloat(x)),
54                     ty::TyStr => Def::PrimTy(hir::TyStr),
55                     ty::TyBool => Def::PrimTy(hir::TyBool),
56                     ty::TyChar => Def::PrimTy(hir::TyChar),
57                     _ => unreachable!(),
58                 }
59             }, None),
60             _ => {
61                 debug!("Unexpected type {:?}", def_id);
62                 return Vec::new()
63             }
64         };
65
66         self.get_auto_trait_impls(def_id, &def_ctor, None)
67     }
68
69     pub fn get_with_node_id(&self, id: ast::NodeId, name: String) -> Vec<Item> {
70         let item = &self.cx.tcx.hir.expect_item(id).node;
71         let did = self.cx.tcx.hir.local_def_id(id);
72
73         let def_ctor = match *item {
74             hir::ItemKind::Struct(_, _) => Def::Struct,
75             hir::ItemKind::Union(_, _) => Def::Union,
76             hir::ItemKind::Enum(_, _) => Def::Enum,
77             _ => panic!("Unexpected type {:?} {:?}", item, id),
78         };
79
80         self.get_auto_trait_impls(did, &def_ctor, Some(name))
81     }
82
83     fn get_real_ty<F>(&self,
84                       def_id: DefId,
85                       def_ctor: &F,
86                       real_name: &Option<Ident>,
87                       generics: &ty::Generics,
88     ) -> hir::Ty
89     where F: Fn(DefId) -> Def {
90         let path = get_path_for_type(self.cx.tcx, def_id, def_ctor);
91         let mut segments = path.segments.into_vec();
92         let last = segments.pop().unwrap();
93
94         segments.push(hir::PathSegment::new(
95             real_name.unwrap_or(last.ident),
96             self.generics_to_path_params(generics.clone()),
97             false,
98         ));
99
100         let new_path = hir::Path {
101             span: path.span,
102             def: path.def,
103             segments: HirVec::from_vec(segments),
104         };
105
106         hir::Ty {
107             id: ast::DUMMY_NODE_ID,
108             node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))),
109             span: DUMMY_SP,
110             hir_id: hir::DUMMY_HIR_ID,
111         }
112     }
113
114     pub fn get_blanket_impls<F>(
115         &self,
116         def_id: DefId,
117         def_ctor: &F,
118         name: Option<String>,
119         generics: &ty::Generics,
120     ) -> Vec<Item>
121     where F: Fn(DefId) -> Def {
122         let ty = self.cx.tcx.type_of(def_id);
123         let mut traits = Vec::new();
124         if self.cx.access_levels.borrow().is_doc_reachable(def_id) {
125             let real_name = name.clone().map(|name| Ident::from_str(&name));
126             let param_env = self.cx.tcx.param_env(def_id);
127             for &trait_def_id in self.cx.all_traits.iter() {
128                 if !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) ||
129                    self.cx.generated_synthetics
130                           .borrow_mut()
131                           .get(&(def_id, trait_def_id))
132                           .is_some() {
133                     continue
134                 }
135                 self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
136                     self.cx.tcx.infer_ctxt().enter(|infcx| {
137                         let t_generics = infcx.tcx.generics_of(impl_def_id);
138                         let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap();
139
140                         match infcx.tcx.type_of(impl_def_id).sty {
141                             ::rustc::ty::TypeVariants::TyParam(_) => {},
142                             _ => return,
143                         }
144
145                         let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id);
146                         let ty = ty.subst(infcx.tcx, substs);
147                         let param_env = param_env.subst(infcx.tcx, substs);
148
149                         let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
150                         let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
151
152                         // Require the type the impl is implemented on to match
153                         // our type, and ignore the impl if there was a mismatch.
154                         let cause = traits::ObligationCause::dummy();
155                         let eq_result = infcx.at(&cause, param_env)
156                                              .eq(trait_ref.self_ty(), ty);
157                         if let Ok(InferOk { value: (), obligations }) = eq_result {
158                             // FIXME(eddyb) ignoring `obligations` might cause false positives.
159                             drop(obligations);
160
161                             let may_apply = infcx.predicate_may_hold(&traits::Obligation::new(
162                                 cause.clone(),
163                                 param_env,
164                                 trait_ref.to_predicate(),
165                             ));
166                             if !may_apply {
167                                 return
168                             }
169                             self.cx.generated_synthetics.borrow_mut()
170                                                         .insert((def_id, trait_def_id));
171                             let trait_ = hir::TraitRef {
172                                 path: get_path_for_type(infcx.tcx,
173                                                         trait_def_id,
174                                                         hir::def::Def::Trait),
175                                 ref_id: ast::DUMMY_NODE_ID,
176                             };
177                             let provided_trait_methods =
178                                 infcx.tcx.provided_trait_methods(trait_def_id)
179                                          .into_iter()
180                                          .map(|meth| meth.ident.to_string())
181                                          .collect();
182
183                             let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics);
184                             let predicates = infcx.tcx.predicates_of(impl_def_id);
185
186                             traits.push(Item {
187                                 source: infcx.tcx.def_span(impl_def_id).clean(self.cx),
188                                 name: None,
189                                 attrs: Default::default(),
190                                 visibility: None,
191                                 def_id: self.next_def_id(impl_def_id.krate),
192                                 stability: None,
193                                 deprecation: None,
194                                 inner: ImplItem(Impl {
195                                     unsafety: hir::Unsafety::Normal,
196                                     generics: (t_generics, &predicates).clean(self.cx),
197                                     provided_trait_methods,
198                                     trait_: Some(trait_.clean(self.cx)),
199                                     for_: ty.clean(self.cx),
200                                     items: infcx.tcx.associated_items(impl_def_id)
201                                                     .collect::<Vec<_>>()
202                                                     .clean(self.cx),
203                                     polarity: None,
204                                     synthetic: false,
205                                     blanket_impl: Some(infcx.tcx.type_of(impl_def_id)
206                                                                 .clean(self.cx)),
207                                 }),
208                             });
209                             debug!("{:?} => {}", trait_ref, may_apply);
210                         }
211                     });
212                 });
213             }
214         }
215         traits
216     }
217
218     pub fn get_auto_trait_impls<F>(
219         &self,
220         def_id: DefId,
221         def_ctor: &F,
222         name: Option<String>,
223     ) -> Vec<Item>
224     where F: Fn(DefId) -> Def {
225         if self.cx
226             .tcx
227             .get_attrs(def_id)
228             .lists("doc")
229             .has_word("hidden")
230         {
231             debug!(
232                 "get_auto_trait_impls(def_id={:?}, def_ctor=...): item has doc('hidden'), \
233                  aborting",
234                 def_id
235             );
236             return Vec::new();
237         }
238
239         let tcx = self.cx.tcx;
240         let generics = self.cx.tcx.generics_of(def_id);
241
242         debug!(
243             "get_auto_trait_impls(def_id={:?}, def_ctor=..., generics={:?}",
244             def_id, generics
245         );
246         let auto_traits: Vec<_> = self.cx
247             .send_trait
248             .and_then(|send_trait| {
249                 self.get_auto_trait_impl_for(
250                     def_id,
251                     name.clone(),
252                     generics.clone(),
253                     def_ctor,
254                     send_trait,
255                 )
256             })
257             .into_iter()
258             .chain(self.get_auto_trait_impl_for(
259                 def_id,
260                 name.clone(),
261                 generics.clone(),
262                 def_ctor,
263                 tcx.require_lang_item(lang_items::SyncTraitLangItem),
264             ).into_iter())
265             .chain(self.get_blanket_impls(def_id, def_ctor, name, &generics).into_iter())
266             .collect();
267
268         debug!(
269             "get_auto_traits: type {:?} auto_traits {:?}",
270             def_id, auto_traits
271         );
272         auto_traits
273     }
274
275     fn get_auto_trait_impl_for<F>(
276         &self,
277         def_id: DefId,
278         name: Option<String>,
279         generics: ty::Generics,
280         def_ctor: &F,
281         trait_def_id: DefId,
282     ) -> Option<Item>
283     where F: Fn(DefId) -> Def {
284         if !self.cx
285             .generated_synthetics
286             .borrow_mut()
287             .insert((def_id, trait_def_id))
288         {
289             debug!(
290                 "get_auto_trait_impl_for(def_id={:?}, generics={:?}, def_ctor=..., \
291                  trait_def_id={:?}): already generated, aborting",
292                 def_id, generics, trait_def_id
293             );
294             return None;
295         }
296
297         let result = self.find_auto_trait_generics(def_id, trait_def_id, &generics);
298
299         if result.is_auto() {
300             let trait_ = hir::TraitRef {
301                 path: get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait),
302                 ref_id: ast::DUMMY_NODE_ID,
303             };
304
305             let polarity;
306
307             let new_generics = match result {
308                 AutoTraitResult::PositiveImpl(new_generics) => {
309                     polarity = None;
310                     new_generics
311                 }
312                 AutoTraitResult::NegativeImpl => {
313                     polarity = Some(ImplPolarity::Negative);
314
315                     // For negative impls, we use the generic params, but *not* the predicates,
316                     // from the original type. Otherwise, the displayed impl appears to be a
317                     // conditional negative impl, when it's really unconditional.
318                     //
319                     // For example, consider the struct Foo<T: Copy>(*mut T). Using
320                     // the original predicates in our impl would cause us to generate
321                     // `impl !Send for Foo<T: Copy>`, which makes it appear that Foo
322                     // implements Send where T is not copy.
323                     //
324                     // Instead, we generate `impl !Send for Foo<T>`, which better
325                     // expresses the fact that `Foo<T>` never implements `Send`,
326                     // regardless of the choice of `T`.
327                     let real_generics = (&generics, &Default::default());
328
329                     // Clean the generics, but ignore the '?Sized' bounds generated
330                     // by the `Clean` impl
331                     let clean_generics = real_generics.clean(self.cx);
332
333                     Generics {
334                         params: clean_generics.params,
335                         where_predicates: Vec::new(),
336                     }
337                 }
338                 _ => unreachable!(),
339             };
340             let real_name = name.map(|name| Ident::from_str(&name));
341             let ty = self.get_real_ty(def_id, def_ctor, &real_name, &generics);
342
343             return Some(Item {
344                 source: Span::empty(),
345                 name: None,
346                 attrs: Default::default(),
347                 visibility: None,
348                 def_id: self.next_def_id(def_id.krate),
349                 stability: None,
350                 deprecation: None,
351                 inner: ImplItem(Impl {
352                     unsafety: hir::Unsafety::Normal,
353                     generics: new_generics,
354                     provided_trait_methods: FxHashSet(),
355                     trait_: Some(trait_.clean(self.cx)),
356                     for_: ty.clean(self.cx),
357                     items: Vec::new(),
358                     polarity,
359                     synthetic: true,
360                     blanket_impl: None,
361                 }),
362             });
363         }
364         None
365     }
366
367     fn generics_to_path_params(&self, generics: ty::Generics) -> hir::GenericArgs {
368         let mut args = vec![];
369
370         for param in generics.params.iter() {
371             match param.kind {
372                 ty::GenericParamDefKind::Lifetime => {
373                     let name = if param.name == "" {
374                         hir::ParamName::Plain(keywords::StaticLifetime.ident())
375                     } else {
376                         hir::ParamName::Plain(ast::Ident::from_interned_str(param.name))
377                     };
378
379                     args.push(hir::GenericArg::Lifetime(hir::Lifetime {
380                         id: ast::DUMMY_NODE_ID,
381                         span: DUMMY_SP,
382                         name: hir::LifetimeName::Param(name),
383                     }));
384                 }
385                 ty::GenericParamDefKind::Type {..} => {
386                     args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
387                 }
388             }
389         }
390
391         hir::GenericArgs {
392             args: HirVec::from_vec(args),
393             bindings: HirVec::new(),
394             parenthesized: false,
395         }
396     }
397
398     fn ty_param_to_ty(&self, param: ty::GenericParamDef) -> hir::Ty {
399         debug!("ty_param_to_ty({:?}) {:?}", param, param.def_id);
400         hir::Ty {
401             id: ast::DUMMY_NODE_ID,
402             node: hir::TyKind::Path(hir::QPath::Resolved(
403                 None,
404                 P(hir::Path {
405                     span: DUMMY_SP,
406                     def: Def::TyParam(param.def_id),
407                     segments: HirVec::from_vec(vec![
408                         hir::PathSegment::from_ident(Ident::from_interned_str(param.name))
409                     ]),
410                 }),
411             )),
412             span: DUMMY_SP,
413             hir_id: hir::DUMMY_HIR_ID,
414         }
415     }
416
417     fn find_auto_trait_generics(
418         &self,
419         did: DefId,
420         trait_did: DefId,
421         generics: &ty::Generics,
422     ) -> AutoTraitResult {
423         match self.f.find_auto_trait_generics(did, trait_did, generics,
424                 |infcx, mut info| {
425                     let region_data = info.region_data;
426                     let names_map =
427                         info.names_map
428                             .drain()
429                             .map(|name| (name.clone(), Lifetime(name)))
430                             .collect();
431                     let lifetime_predicates =
432                         self.handle_lifetimes(&region_data, &names_map);
433                     let new_generics = self.param_env_to_generics(
434                         infcx.tcx,
435                         did,
436                         info.full_user_env,
437                         generics.clone(),
438                         lifetime_predicates,
439                         info.vid_to_region,
440                     );
441
442                     debug!(
443                         "find_auto_trait_generics(did={:?}, trait_did={:?}, generics={:?}): \
444                          finished with {:?}",
445                         did, trait_did, generics, new_generics
446                     );
447
448                     new_generics
449                 }) {
450             auto::AutoTraitResult::ExplicitImpl => AutoTraitResult::ExplicitImpl,
451             auto::AutoTraitResult::NegativeImpl => AutoTraitResult::NegativeImpl,
452             auto::AutoTraitResult::PositiveImpl(res) => AutoTraitResult::PositiveImpl(res),
453         }
454     }
455
456     fn get_lifetime(&self, region: Region, names_map: &FxHashMap<String, Lifetime>) -> Lifetime {
457         self.region_name(region)
458             .map(|name| {
459                 names_map.get(&name).unwrap_or_else(|| {
460                     panic!("Missing lifetime with name {:?} for {:?}", name, region)
461                 })
462             })
463             .unwrap_or(&Lifetime::statik())
464             .clone()
465     }
466
467     fn region_name(&self, region: Region) -> Option<String> {
468         match region {
469             &ty::ReEarlyBound(r) => Some(r.name.to_string()),
470             _ => None,
471         }
472     }
473
474     // This method calculates two things: Lifetime constraints of the form 'a: 'b,
475     // and region constraints of the form ReVar: 'a
476     //
477     // This is essentially a simplified version of lexical_region_resolve. However,
478     // handle_lifetimes determines what *needs be* true in order for an impl to hold.
479     // lexical_region_resolve, along with much of the rest of the compiler, is concerned
480     // with determining if a given set up constraints/predicates *are* met, given some
481     // starting conditions (e.g. user-provided code). For this reason, it's easier
482     // to perform the calculations we need on our own, rather than trying to make
483     // existing inference/solver code do what we want.
484     fn handle_lifetimes<'cx>(
485         &self,
486         regions: &RegionConstraintData<'cx>,
487         names_map: &FxHashMap<String, Lifetime>,
488     ) -> Vec<WherePredicate> {
489         // Our goal is to 'flatten' the list of constraints by eliminating
490         // all intermediate RegionVids. At the end, all constraints should
491         // be between Regions (aka region variables). This gives us the information
492         // we need to create the Generics.
493         let mut finished = FxHashMap();
494
495         let mut vid_map: FxHashMap<RegionTarget, RegionDeps> = FxHashMap();
496
497         // Flattening is done in two parts. First, we insert all of the constraints
498         // into a map. Each RegionTarget (either a RegionVid or a Region) maps
499         // to its smaller and larger regions. Note that 'larger' regions correspond
500         // to sub-regions in Rust code (e.g. in 'a: 'b, 'a is the larger region).
501         for constraint in regions.constraints.keys() {
502             match constraint {
503                 &Constraint::VarSubVar(r1, r2) => {
504                     {
505                         let deps1 = vid_map
506                             .entry(RegionTarget::RegionVid(r1))
507                             .or_insert_with(|| Default::default());
508                         deps1.larger.insert(RegionTarget::RegionVid(r2));
509                     }
510
511                     let deps2 = vid_map
512                         .entry(RegionTarget::RegionVid(r2))
513                         .or_insert_with(|| Default::default());
514                     deps2.smaller.insert(RegionTarget::RegionVid(r1));
515                 }
516                 &Constraint::RegSubVar(region, vid) => {
517                     let deps = vid_map
518                         .entry(RegionTarget::RegionVid(vid))
519                         .or_insert_with(|| Default::default());
520                     deps.smaller.insert(RegionTarget::Region(region));
521                 }
522                 &Constraint::VarSubReg(vid, region) => {
523                     let deps = vid_map
524                         .entry(RegionTarget::RegionVid(vid))
525                         .or_insert_with(|| Default::default());
526                     deps.larger.insert(RegionTarget::Region(region));
527                 }
528                 &Constraint::RegSubReg(r1, r2) => {
529                     // The constraint is already in the form that we want, so we're done with it
530                     // Desired order is 'larger, smaller', so flip then
531                     if self.region_name(r1) != self.region_name(r2) {
532                         finished
533                             .entry(self.region_name(r2).unwrap())
534                             .or_insert_with(|| Vec::new())
535                             .push(r1);
536                     }
537                 }
538             }
539         }
540
541         // Here, we 'flatten' the map one element at a time.
542         // All of the element's sub and super regions are connected
543         // to each other. For example, if we have a graph that looks like this:
544         //
545         // (A, B) - C - (D, E)
546         // Where (A, B) are subregions, and (D,E) are super-regions
547         //
548         // then after deleting 'C', the graph will look like this:
549         //  ... - A - (D, E ...)
550         //  ... - B - (D, E, ...)
551         //  (A, B, ...) - D - ...
552         //  (A, B, ...) - E - ...
553         //
554         //  where '...' signifies the existing sub and super regions of an entry
555         //  When two adjacent ty::Regions are encountered, we've computed a final
556         //  constraint, and add it to our list. Since we make sure to never re-add
557         //  deleted items, this process will always finish.
558         while !vid_map.is_empty() {
559             let target = vid_map.keys().next().expect("Keys somehow empty").clone();
560             let deps = vid_map.remove(&target).expect("Entry somehow missing");
561
562             for smaller in deps.smaller.iter() {
563                 for larger in deps.larger.iter() {
564                     match (smaller, larger) {
565                         (&RegionTarget::Region(r1), &RegionTarget::Region(r2)) => {
566                             if self.region_name(r1) != self.region_name(r2) {
567                                 finished
568                                     .entry(self.region_name(r2).unwrap())
569                                     .or_insert_with(|| Vec::new())
570                                     .push(r1) // Larger, smaller
571                             }
572                         }
573                         (&RegionTarget::RegionVid(_), &RegionTarget::Region(_)) => {
574                             if let Entry::Occupied(v) = vid_map.entry(*smaller) {
575                                 let smaller_deps = v.into_mut();
576                                 smaller_deps.larger.insert(*larger);
577                                 smaller_deps.larger.remove(&target);
578                             }
579                         }
580                         (&RegionTarget::Region(_), &RegionTarget::RegionVid(_)) => {
581                             if let Entry::Occupied(v) = vid_map.entry(*larger) {
582                                 let deps = v.into_mut();
583                                 deps.smaller.insert(*smaller);
584                                 deps.smaller.remove(&target);
585                             }
586                         }
587                         (&RegionTarget::RegionVid(_), &RegionTarget::RegionVid(_)) => {
588                             if let Entry::Occupied(v) = vid_map.entry(*smaller) {
589                                 let smaller_deps = v.into_mut();
590                                 smaller_deps.larger.insert(*larger);
591                                 smaller_deps.larger.remove(&target);
592                             }
593
594                             if let Entry::Occupied(v) = vid_map.entry(*larger) {
595                                 let larger_deps = v.into_mut();
596                                 larger_deps.smaller.insert(*smaller);
597                                 larger_deps.smaller.remove(&target);
598                             }
599                         }
600                     }
601                 }
602             }
603         }
604
605         let lifetime_predicates = names_map
606             .iter()
607             .flat_map(|(name, lifetime)| {
608                 let empty = Vec::new();
609                 let bounds: FxHashSet<GenericBound> = finished.get(name).unwrap_or(&empty).iter()
610                     .map(|region| GenericBound::Outlives(self.get_lifetime(region, names_map)))
611                     .collect();
612
613                 if bounds.is_empty() {
614                     return None;
615                 }
616                 Some(WherePredicate::RegionPredicate {
617                     lifetime: lifetime.clone(),
618                     bounds: bounds.into_iter().collect(),
619                 })
620             })
621             .collect();
622
623         lifetime_predicates
624     }
625
626     fn extract_for_generics<'b, 'c, 'd>(
627         &self,
628         tcx: TyCtxt<'b, 'c, 'd>,
629         pred: ty::Predicate<'d>,
630     ) -> FxHashSet<GenericParamDef> {
631         pred.walk_tys()
632             .flat_map(|t| {
633                 let mut regions = FxHashSet();
634                 tcx.collect_regions(&t, &mut regions);
635
636                 regions.into_iter().flat_map(|r| {
637                     match r {
638                         // We only care about late bound regions, as we need to add them
639                         // to the 'for<>' section
640                         &ty::ReLateBound(_, ty::BoundRegion::BrNamed(_, name)) => {
641                             Some(GenericParamDef {
642                                 name: name.to_string(),
643                                 kind: GenericParamDefKind::Lifetime,
644                             })
645                         },
646                         &ty::ReVar(_) | &ty::ReEarlyBound(_) | &ty::ReStatic => None,
647                         _ => panic!("Unexpected region type {:?}", r),
648                     }
649                 })
650             })
651             .collect()
652     }
653
654     fn make_final_bounds<'b, 'c, 'cx>(
655         &self,
656         ty_to_bounds: FxHashMap<Type, FxHashSet<GenericBound>>,
657         ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)>,
658         lifetime_to_bounds: FxHashMap<Lifetime, FxHashSet<GenericBound>>,
659     ) -> Vec<WherePredicate> {
660         ty_to_bounds
661             .into_iter()
662             .flat_map(|(ty, mut bounds)| {
663                 if let Some(data) = ty_to_fn.get(&ty) {
664                     let (poly_trait, output) =
665                         (data.0.as_ref().unwrap().clone(), data.1.as_ref().cloned());
666                     let new_ty = match &poly_trait.trait_ {
667                         &Type::ResolvedPath {
668                             ref path,
669                             ref typarams,
670                             ref did,
671                             ref is_generic,
672                         } => {
673                             let mut new_path = path.clone();
674                             let last_segment = new_path.segments.pop().unwrap();
675
676                             let (old_input, old_output) = match last_segment.args {
677                                 GenericArgs::AngleBracketed { types, .. } => (types, None),
678                                 GenericArgs::Parenthesized { inputs, output, .. } => {
679                                     (inputs, output)
680                                 }
681                             };
682
683                             if old_output.is_some() && old_output != output {
684                                 panic!(
685                                     "Output mismatch for {:?} {:?} {:?}",
686                                     ty, old_output, data.1
687                                 );
688                             }
689
690                             let new_params = GenericArgs::Parenthesized {
691                                 inputs: old_input,
692                                 output,
693                             };
694
695                             new_path.segments.push(PathSegment {
696                                 name: last_segment.name,
697                                 args: new_params,
698                             });
699
700                             Type::ResolvedPath {
701                                 path: new_path,
702                                 typarams: typarams.clone(),
703                                 did: did.clone(),
704                                 is_generic: *is_generic,
705                             }
706                         }
707                         _ => panic!("Unexpected data: {:?}, {:?}", ty, data),
708                     };
709                     bounds.insert(GenericBound::TraitBound(
710                         PolyTrait {
711                             trait_: new_ty,
712                             generic_params: poly_trait.generic_params,
713                         },
714                         hir::TraitBoundModifier::None,
715                     ));
716                 }
717                 if bounds.is_empty() {
718                     return None;
719                 }
720
721                 let mut bounds_vec = bounds.into_iter().collect();
722                 self.sort_where_bounds(&mut bounds_vec);
723
724                 Some(WherePredicate::BoundPredicate {
725                     ty,
726                     bounds: bounds_vec,
727                 })
728             })
729             .chain(
730                 lifetime_to_bounds
731                     .into_iter()
732                     .filter(|&(_, ref bounds)| !bounds.is_empty())
733                     .map(|(lifetime, bounds)| {
734                         let mut bounds_vec = bounds.into_iter().collect();
735                         self.sort_where_bounds(&mut bounds_vec);
736                         WherePredicate::RegionPredicate {
737                             lifetime,
738                             bounds: bounds_vec,
739                         }
740                     }),
741             )
742             .collect()
743     }
744
745     // Converts the calculated ParamEnv and lifetime information to a clean::Generics, suitable for
746     // display on the docs page. Cleaning the Predicates produces sub-optimal WherePredicate's,
747     // so we fix them up:
748     //
749     // * Multiple bounds for the same type are coalesced into one: e.g. 'T: Copy', 'T: Debug'
750     // becomes 'T: Copy + Debug'
751     // * Fn bounds are handled specially - instead of leaving it as 'T: Fn(), <T as Fn::Output> =
752     // K', we use the dedicated syntax 'T: Fn() -> K'
753     // * We explcitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type
754     fn param_env_to_generics<'b, 'c, 'cx>(
755         &self,
756         tcx: TyCtxt<'b, 'c, 'cx>,
757         did: DefId,
758         param_env: ty::ParamEnv<'cx>,
759         type_generics: ty::Generics,
760         mut existing_predicates: Vec<WherePredicate>,
761         vid_to_region: FxHashMap<ty::RegionVid, ty::Region<'cx>>,
762     ) -> Generics {
763         debug!(
764             "param_env_to_generics(did={:?}, param_env={:?}, type_generics={:?}, \
765              existing_predicates={:?})",
766             did, param_env, type_generics, existing_predicates
767         );
768
769         // The `Sized` trait must be handled specially, since we only only display it when
770         // it is *not* required (i.e. '?Sized')
771         let sized_trait = self.cx
772             .tcx
773             .require_lang_item(lang_items::SizedTraitLangItem);
774
775         let mut replacer = RegionReplacer {
776             vid_to_region: &vid_to_region,
777             tcx,
778         };
779
780         let orig_bounds: FxHashSet<_> = self.cx.tcx.param_env(did).caller_bounds.iter().collect();
781         let clean_where_predicates = param_env
782             .caller_bounds
783             .iter()
784             .filter(|p| {
785                 !orig_bounds.contains(p) || match p {
786                     &&ty::Predicate::Trait(pred) => pred.def_id() == sized_trait,
787                     _ => false,
788                 }
789             })
790             .map(|p| {
791                 let replaced = p.fold_with(&mut replacer);
792                 (replaced.clone(), replaced.clean(self.cx))
793             });
794
795         let full_generics = (&type_generics, &tcx.predicates_of(did));
796         let Generics {
797             params: mut generic_params,
798             ..
799         } = full_generics.clean(self.cx);
800
801         let mut has_sized = FxHashSet();
802         let mut ty_to_bounds = FxHashMap();
803         let mut lifetime_to_bounds = FxHashMap();
804         let mut ty_to_traits: FxHashMap<Type, FxHashSet<Type>> = FxHashMap();
805
806         let mut ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)> = FxHashMap();
807
808         for (orig_p, p) in clean_where_predicates {
809             match p {
810                 WherePredicate::BoundPredicate { ty, mut bounds } => {
811                     // Writing a projection trait bound of the form
812                     // <T as Trait>::Name : ?Sized
813                     // is illegal, because ?Sized bounds can only
814                     // be written in the (here, nonexistant) definition
815                     // of the type.
816                     // Therefore, we make sure that we never add a ?Sized
817                     // bound for projections
818                     match &ty {
819                         &Type::QPath { .. } => {
820                             has_sized.insert(ty.clone());
821                         }
822                         _ => {}
823                     }
824
825                     if bounds.is_empty() {
826                         continue;
827                     }
828
829                     let mut for_generics = self.extract_for_generics(tcx, orig_p.clone());
830
831                     assert!(bounds.len() == 1);
832                     let mut b = bounds.pop().unwrap();
833
834                     if b.is_sized_bound(self.cx) {
835                         has_sized.insert(ty.clone());
836                     } else if !b.get_trait_type()
837                         .and_then(|t| {
838                             ty_to_traits
839                                 .get(&ty)
840                                 .map(|bounds| bounds.contains(&strip_type(t.clone())))
841                         })
842                         .unwrap_or(false)
843                     {
844                         // If we've already added a projection bound for the same type, don't add
845                         // this, as it would be a duplicate
846
847                         // Handle any 'Fn/FnOnce/FnMut' bounds specially,
848                         // as we want to combine them with any 'Output' qpaths
849                         // later
850
851                         let is_fn = match &mut b {
852                             &mut GenericBound::TraitBound(ref mut p, _) => {
853                                 // Insert regions into the for_generics hash map first, to ensure
854                                 // that we don't end up with duplicate bounds (e.g. for<'b, 'b>)
855                                 for_generics.extend(p.generic_params.clone());
856                                 p.generic_params = for_generics.into_iter().collect();
857                                 self.is_fn_ty(&tcx, &p.trait_)
858                             }
859                             _ => false,
860                         };
861
862                         let poly_trait = b.get_poly_trait().unwrap();
863
864                         if is_fn {
865                             ty_to_fn
866                                 .entry(ty.clone())
867                                 .and_modify(|e| *e = (Some(poly_trait.clone()), e.1.clone()))
868                                 .or_insert(((Some(poly_trait.clone())), None));
869
870                             ty_to_bounds
871                                 .entry(ty.clone())
872                                 .or_insert_with(|| FxHashSet());
873                         } else {
874                             ty_to_bounds
875                                 .entry(ty.clone())
876                                 .or_insert_with(|| FxHashSet())
877                                 .insert(b.clone());
878                         }
879                     }
880                 }
881                 WherePredicate::RegionPredicate { lifetime, bounds } => {
882                     lifetime_to_bounds
883                         .entry(lifetime)
884                         .or_insert_with(|| FxHashSet())
885                         .extend(bounds);
886                 }
887                 WherePredicate::EqPredicate { lhs, rhs } => {
888                     match &lhs {
889                         &Type::QPath {
890                             name: ref left_name,
891                             ref self_type,
892                             ref trait_,
893                         } => {
894                             let ty = &*self_type;
895                             match **trait_ {
896                                 Type::ResolvedPath {
897                                     path: ref trait_path,
898                                     ref typarams,
899                                     ref did,
900                                     ref is_generic,
901                                 } => {
902                                     let mut new_trait_path = trait_path.clone();
903
904                                     if self.is_fn_ty(&tcx, trait_) && left_name == FN_OUTPUT_NAME {
905                                         ty_to_fn
906                                             .entry(*ty.clone())
907                                             .and_modify(|e| *e = (e.0.clone(), Some(rhs.clone())))
908                                             .or_insert((None, Some(rhs)));
909                                         continue;
910                                     }
911
912                                     // FIXME: Remove this scope when NLL lands
913                                     {
914                                         let args =
915                                             &mut new_trait_path.segments.last_mut().unwrap().args;
916
917                                         match args {
918                                             // Convert somethiung like '<T as Iterator::Item> = u8'
919                                             // to 'T: Iterator<Item=u8>'
920                                             &mut GenericArgs::AngleBracketed {
921                                                 ref mut bindings,
922                                                 ..
923                                             } => {
924                                                 bindings.push(TypeBinding {
925                                                     name: left_name.clone(),
926                                                     ty: rhs,
927                                                 });
928                                             }
929                                             &mut GenericArgs::Parenthesized { .. } => {
930                                                 existing_predicates.push(
931                                                     WherePredicate::EqPredicate {
932                                                         lhs: lhs.clone(),
933                                                         rhs,
934                                                     },
935                                                 );
936                                                 continue; // If something other than a Fn ends up
937                                                           // with parenthesis, leave it alone
938                                             }
939                                         }
940                                     }
941
942                                     let bounds = ty_to_bounds
943                                         .entry(*ty.clone())
944                                         .or_insert_with(|| FxHashSet());
945
946                                     bounds.insert(GenericBound::TraitBound(
947                                         PolyTrait {
948                                             trait_: Type::ResolvedPath {
949                                                 path: new_trait_path,
950                                                 typarams: typarams.clone(),
951                                                 did: did.clone(),
952                                                 is_generic: *is_generic,
953                                             },
954                                             generic_params: Vec::new(),
955                                         },
956                                         hir::TraitBoundModifier::None,
957                                     ));
958
959                                     // Remove any existing 'plain' bound (e.g. 'T: Iterator`) so
960                                     // that we don't see a
961                                     // duplicate bound like `T: Iterator + Iterator<Item=u8>`
962                                     // on the docs page.
963                                     bounds.remove(&GenericBound::TraitBound(
964                                         PolyTrait {
965                                             trait_: *trait_.clone(),
966                                             generic_params: Vec::new(),
967                                         },
968                                         hir::TraitBoundModifier::None,
969                                     ));
970                                     // Avoid creating any new duplicate bounds later in the outer
971                                     // loop
972                                     ty_to_traits
973                                         .entry(*ty.clone())
974                                         .or_insert_with(|| FxHashSet())
975                                         .insert(*trait_.clone());
976                                 }
977                                 _ => panic!("Unexpected trait {:?} for {:?}", trait_, did),
978                             }
979                         }
980                         _ => panic!("Unexpected LHS {:?} for {:?}", lhs, did),
981                     }
982                 }
983             };
984         }
985
986         let final_bounds = self.make_final_bounds(ty_to_bounds, ty_to_fn, lifetime_to_bounds);
987
988         existing_predicates.extend(final_bounds);
989
990         for param in generic_params.iter_mut() {
991             match param.kind {
992                 GenericParamDefKind::Type { ref mut default, ref mut bounds, .. } => {
993                     // We never want something like `impl<T=Foo>`.
994                     default.take();
995                     let generic_ty = Type::Generic(param.name.clone());
996                     if !has_sized.contains(&generic_ty) {
997                         bounds.insert(0, GenericBound::maybe_sized(self.cx));
998                     }
999                 }
1000                 GenericParamDefKind::Lifetime => {}
1001             }
1002         }
1003
1004         self.sort_where_predicates(&mut existing_predicates);
1005
1006         Generics {
1007             params: generic_params,
1008             where_predicates: existing_predicates,
1009         }
1010     }
1011
1012     // Ensure that the predicates are in a consistent order. The precise
1013     // ordering doesn't actually matter, but it's important that
1014     // a given set of predicates always appears in the same order -
1015     // both for visual consistency between 'rustdoc' runs, and to
1016     // make writing tests much easier
1017     #[inline]
1018     fn sort_where_predicates(&self, mut predicates: &mut Vec<WherePredicate>) {
1019         // We should never have identical bounds - and if we do,
1020         // they're visually identical as well. Therefore, using
1021         // an unstable sort is fine.
1022         self.unstable_debug_sort(&mut predicates);
1023     }
1024
1025     // Ensure that the bounds are in a consistent order. The precise
1026     // ordering doesn't actually matter, but it's important that
1027     // a given set of bounds always appears in the same order -
1028     // both for visual consistency between 'rustdoc' runs, and to
1029     // make writing tests much easier
1030     #[inline]
1031     fn sort_where_bounds(&self, mut bounds: &mut Vec<GenericBound>) {
1032         // We should never have identical bounds - and if we do,
1033         // they're visually identical as well. Therefore, using
1034         // an unstable sort is fine.
1035         self.unstable_debug_sort(&mut bounds);
1036     }
1037
1038     // This might look horrendously hacky, but it's actually not that bad.
1039     //
1040     // For performance reasons, we use several different FxHashMaps
1041     // in the process of computing the final set of where predicates.
1042     // However, the iteration order of a HashMap is completely unspecified.
1043     // In fact, the iteration of an FxHashMap can even vary between platforms,
1044     // since FxHasher has different behavior for 32-bit and 64-bit platforms.
1045     //
1046     // Obviously, it's extremely undesireable for documentation rendering
1047     // to be depndent on the platform it's run on. Apart from being confusing
1048     // to end users, it makes writing tests much more difficult, as predicates
1049     // can appear in any order in the final result.
1050     //
1051     // To solve this problem, we sort WherePredicates and GenericBounds
1052     // by their Debug string. The thing to keep in mind is that we don't really
1053     // care what the final order is - we're synthesizing an impl or bound
1054     // ourselves, so any order can be considered equally valid. By sorting the
1055     // predicates and bounds, however, we ensure that for a given codebase, all
1056     // auto-trait impls always render in exactly the same way.
1057     //
1058     // Using the Debug impementation for sorting prevents us from needing to
1059     // write quite a bit of almost entirely useless code (e.g. how should two
1060     // Types be sorted relative to each other). It also allows us to solve the
1061     // problem for both WherePredicates and GenericBounds at the same time. This
1062     // approach is probably somewhat slower, but the small number of items
1063     // involved (impls rarely have more than a few bounds) means that it
1064     // shouldn't matter in practice.
1065     fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) {
1066         vec.sort_by_cached_key(|x| format!("{:?}", x))
1067     }
1068
1069     fn is_fn_ty(&self, tcx: &TyCtxt, ty: &Type) -> bool {
1070         match &ty {
1071             &&Type::ResolvedPath { ref did, .. } => {
1072                 *did == tcx.require_lang_item(lang_items::FnTraitLangItem)
1073                     || *did == tcx.require_lang_item(lang_items::FnMutTraitLangItem)
1074                     || *did == tcx.require_lang_item(lang_items::FnOnceTraitLangItem)
1075             }
1076             _ => false,
1077         }
1078     }
1079
1080     // This is an ugly hack, but it's the simplest way to handle synthetic impls without greatly
1081     // refactoring either librustdoc or librustc. In particular, allowing new DefIds to be
1082     // registered after the AST is constructed would require storing the defid mapping in a
1083     // RefCell, decreasing the performance for normal compilation for very little gain.
1084     //
1085     // Instead, we construct 'fake' def ids, which start immediately after the last DefId in
1086     // DefIndexAddressSpace::Low. In the Debug impl for clean::Item, we explicitly check for fake
1087     // def ids, as we'll end up with a panic if we use the DefId Debug impl for fake DefIds
1088     fn next_def_id(&self, crate_num: CrateNum) -> DefId {
1089         let start_def_id = {
1090             let next_id = if crate_num == LOCAL_CRATE {
1091                 self.cx
1092                     .tcx
1093                     .hir
1094                     .definitions()
1095                     .def_path_table()
1096                     .next_id(DefIndexAddressSpace::Low)
1097             } else {
1098                 self.cx
1099                     .cstore
1100                     .def_path_table(crate_num)
1101                     .next_id(DefIndexAddressSpace::Low)
1102             };
1103
1104             DefId {
1105                 krate: crate_num,
1106                 index: next_id,
1107             }
1108         };
1109
1110         let mut fake_ids = self.cx.fake_def_ids.borrow_mut();
1111
1112         let def_id = fake_ids.entry(crate_num).or_insert(start_def_id).clone();
1113         fake_ids.insert(
1114             crate_num,
1115             DefId {
1116                 krate: crate_num,
1117                 index: DefIndex::from_array_index(
1118                     def_id.index.as_array_index() + 1,
1119                     def_id.index.address_space(),
1120                 ),
1121             },
1122         );
1123
1124         MAX_DEF_ID.with(|m| {
1125             m.borrow_mut()
1126                 .entry(def_id.krate.clone())
1127                 .or_insert(start_def_id);
1128         });
1129
1130         self.cx.all_fake_def_ids.borrow_mut().insert(def_id);
1131
1132         def_id.clone()
1133     }
1134 }
1135
1136 // Replaces all ReVars in a type with ty::Region's, using the provided map
1137 struct RegionReplacer<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
1138     vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
1139     tcx: TyCtxt<'a, 'gcx, 'tcx>,
1140 }
1141
1142 impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
1143     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
1144         self.tcx
1145     }
1146
1147     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
1148         (match r {
1149             &ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(),
1150             _ => None,
1151         }).unwrap_or_else(|| r.super_fold_with(self))
1152     }
1153 }