@@ -64,7 +64,7 @@ use rustc::hir;
6464use rustc:: util:: nodemap:: { FnvHashMap , FnvHashSet } ;
6565use rustc_data_structures:: flock;
6666
67- use clean:: { self , Attributes , GetDefId } ;
67+ use clean:: { self , Attributes , GetDefId , SelfTy , Mutability } ;
6868use doctree;
6969use fold:: DocFolder ;
7070use html:: escape:: Escape ;
@@ -266,6 +266,7 @@ pub struct Cache {
266266 seen_mod : bool ,
267267 stripped_mod : bool ,
268268 deref_trait_did : Option < DefId > ,
269+ deref_mut_trait_did : Option < DefId > ,
269270
270271 // In rare case where a structure is defined in one module but implemented
271272 // in another, if the implementing module is parsed before defining module,
@@ -283,6 +284,7 @@ pub struct RenderInfo {
283284 pub external_paths : :: core:: ExternalPaths ,
284285 pub external_typarams : FnvHashMap < DefId , String > ,
285286 pub deref_trait_did : Option < DefId > ,
287+ pub deref_mut_trait_did : Option < DefId > ,
286288}
287289
288290/// Helper struct to render all source code to HTML pages
@@ -508,6 +510,7 @@ pub fn run(mut krate: clean::Crate,
508510 external_paths,
509511 external_typarams,
510512 deref_trait_did,
513+ deref_mut_trait_did,
511514 } = renderinfo;
512515
513516 let external_paths = external_paths. into_iter ( )
@@ -532,6 +535,7 @@ pub fn run(mut krate: clean::Crate,
532535 orphan_impl_items : Vec :: new ( ) ,
533536 traits : mem:: replace ( & mut krate. external_traits , FnvHashMap ( ) ) ,
534537 deref_trait_did : deref_trait_did,
538+ deref_mut_trait_did : deref_mut_trait_did,
535539 typarams : external_typarams,
536540 } ;
537541
@@ -2603,7 +2607,13 @@ impl<'a> AssocItemLink<'a> {
26032607
26042608enum AssocItemRender < ' a > {
26052609 All ,
2606- DerefFor { trait_ : & ' a clean:: Type , type_ : & ' a clean:: Type } ,
2610+ DerefFor { trait_ : & ' a clean:: Type , type_ : & ' a clean:: Type , deref_mut_ : bool }
2611+ }
2612+
2613+ #[ derive( Copy , Clone , PartialEq ) ]
2614+ enum RenderMode {
2615+ Normal ,
2616+ ForDeref { mut_ : bool } ,
26072617}
26082618
26092619fn render_assoc_items ( w : & mut fmt:: Formatter ,
@@ -2620,19 +2630,19 @@ fn render_assoc_items(w: &mut fmt::Formatter,
26202630 i. inner_impl ( ) . trait_ . is_none ( )
26212631 } ) ;
26222632 if !non_trait. is_empty ( ) {
2623- let render_header = match what {
2633+ let render_mode = match what {
26242634 AssocItemRender :: All => {
26252635 write ! ( w, "<h2 id='methods'>Methods</h2>" ) ?;
2626- true
2636+ RenderMode :: Normal
26272637 }
2628- AssocItemRender :: DerefFor { trait_, type_ } => {
2638+ AssocItemRender :: DerefFor { trait_, type_, deref_mut_ } => {
26292639 write ! ( w, "<h2 id='deref-methods'>Methods from \
26302640 {}<Target={}></h2>", trait_, type_) ?;
2631- false
2641+ RenderMode :: ForDeref { mut_ : deref_mut_ }
26322642 }
26332643 } ;
26342644 for i in & non_trait {
2635- render_impl ( w, cx, i, AssocItemLink :: Anchor ( None ) , render_header ,
2645+ render_impl ( w, cx, i, AssocItemLink :: Anchor ( None ) , render_mode ,
26362646 containing_item. stable_since ( ) ) ?;
26372647 }
26382648 }
@@ -2644,29 +2654,34 @@ fn render_assoc_items(w: &mut fmt::Formatter,
26442654 t. inner_impl ( ) . trait_ . def_id ( ) == c. deref_trait_did
26452655 } ) ;
26462656 if let Some ( impl_) = deref_impl {
2647- render_deref_methods ( w, cx, impl_, containing_item) ?;
2657+ let has_deref_mut = traits. iter ( ) . find ( |t| {
2658+ t. inner_impl ( ) . trait_ . def_id ( ) == c. deref_mut_trait_did
2659+ } ) . is_some ( ) ;
2660+ render_deref_methods ( w, cx, impl_, containing_item, has_deref_mut) ?;
26482661 }
26492662 write ! ( w, "<h2 id='implementations'>Trait \
26502663 Implementations</h2>") ?;
26512664 for i in & traits {
26522665 let did = i. trait_did ( ) . unwrap ( ) ;
26532666 let assoc_link = AssocItemLink :: GotoSource ( did, & i. inner_impl ( ) . provided_trait_methods ) ;
2654- render_impl ( w, cx, i, assoc_link, true , containing_item. stable_since ( ) ) ?;
2667+ render_impl ( w, cx, i, assoc_link,
2668+ RenderMode :: Normal , containing_item. stable_since ( ) ) ?;
26552669 }
26562670 }
26572671 Ok ( ( ) )
26582672}
26592673
26602674fn render_deref_methods ( w : & mut fmt:: Formatter , cx : & Context , impl_ : & Impl ,
2661- container_item : & clean:: Item ) -> fmt:: Result {
2675+ container_item : & clean:: Item , deref_mut : bool ) -> fmt:: Result {
26622676 let deref_type = impl_. inner_impl ( ) . trait_ . as_ref ( ) . unwrap ( ) ;
26632677 let target = impl_. inner_impl ( ) . items . iter ( ) . filter_map ( |item| {
26642678 match item. inner {
26652679 clean:: TypedefItem ( ref t, true ) => Some ( & t. type_ ) ,
26662680 _ => None ,
26672681 }
26682682 } ) . next ( ) . expect ( "Expected associated type binding" ) ;
2669- let what = AssocItemRender :: DerefFor { trait_ : deref_type, type_ : target } ;
2683+ let what = AssocItemRender :: DerefFor { trait_ : deref_type, type_ : target,
2684+ deref_mut_ : deref_mut } ;
26702685 if let Some ( did) = target. def_id ( ) {
26712686 render_assoc_items ( w, cx, container_item, did, what)
26722687 } else {
@@ -2680,12 +2695,9 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
26802695 }
26812696}
26822697
2683- // Render_header is false when we are rendering a `Deref` impl and true
2684- // otherwise. If render_header is false, we will avoid rendering static
2685- // methods, since they are not accessible for the type implementing `Deref`
26862698fn render_impl ( w : & mut fmt:: Formatter , cx : & Context , i : & Impl , link : AssocItemLink ,
2687- render_header : bool , outer_version : Option < & str > ) -> fmt:: Result {
2688- if render_header {
2699+ render_mode : RenderMode , outer_version : Option < & str > ) -> fmt:: Result {
2700+ if render_mode == RenderMode :: Normal {
26892701 write ! ( w, "<h3 class='impl'><span class='in-band'><code>{}</code>" , i. inner_impl( ) ) ?;
26902702 write ! ( w, "</span><span class='out-of-band'>" ) ?;
26912703 let since = i. impl_item . stability . as_ref ( ) . map ( |s| & s. since [ ..] ) ;
@@ -2706,22 +2718,43 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
27062718 }
27072719
27082720 fn doc_impl_item ( w : & mut fmt:: Formatter , cx : & Context , item : & clean:: Item ,
2709- link : AssocItemLink , render_static : bool ,
2721+ link : AssocItemLink , render_mode : RenderMode ,
27102722 is_default_item : bool , outer_version : Option < & str > ,
27112723 trait_ : Option < & clean:: Trait > ) -> fmt:: Result {
27122724 let item_type = item_type ( item) ;
27132725 let name = item. name . as_ref ( ) . unwrap ( ) ;
27142726
2715- let is_static = match item. inner {
2716- clean:: MethodItem ( ref method) => !method. decl . has_self ( ) ,
2717- clean:: TyMethodItem ( ref method) => !method. decl . has_self ( ) ,
2718- _ => false
2727+ let render_method_item: bool = match render_mode {
2728+ RenderMode :: Normal => true ,
2729+ RenderMode :: ForDeref { mut_ : deref_mut_ } => {
2730+ let self_type_opt = match item. inner {
2731+ clean:: MethodItem ( ref method) => method. decl . self_type ( ) ,
2732+ clean:: TyMethodItem ( ref method) => method. decl . self_type ( ) ,
2733+ _ => None
2734+ } ;
2735+
2736+ if let Some ( self_ty) = self_type_opt {
2737+ let by_mut_ref = match self_ty {
2738+ SelfTy :: SelfBorrowed ( _lifetime, mutability) => {
2739+ mutability == Mutability :: Mutable
2740+ } ,
2741+ SelfTy :: SelfExplicit ( clean:: BorrowedRef { mutability, .. } ) => {
2742+ mutability == Mutability :: Mutable
2743+ } ,
2744+ _ => false ,
2745+ } ;
2746+
2747+ deref_mut_ || !by_mut_ref
2748+ } else {
2749+ false
2750+ }
2751+ } ,
27192752 } ;
27202753
27212754 match item. inner {
27222755 clean:: MethodItem ( ..) | clean:: TyMethodItem ( ..) => {
27232756 // Only render when the method is not static or we allow static methods
2724- if !is_static || render_static {
2757+ if render_method_item {
27252758 let id = derive_id ( format ! ( "{}.{}" , item_type, name) ) ;
27262759 let ns_id = derive_id ( format ! ( "{}.{}" , name, item_type. name_space( ) ) ) ;
27272760 write ! ( w, "<h4 id='{}' class='{}'>" , id, item_type) ?;
@@ -2769,7 +2802,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
27692802 _ => panic ! ( "can't make docs for trait item with name {:?}" , item. name)
27702803 }
27712804
2772- if !is_static || render_static {
2805+ if render_method_item || render_mode == RenderMode :: Normal {
27732806 if !is_default_item {
27742807 if let Some ( t) = trait_ {
27752808 // The trait item may have been stripped so we might not
@@ -2802,15 +2835,15 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
28022835
28032836 write ! ( w, "<div class='impl-items'>" ) ?;
28042837 for trait_item in & i. inner_impl ( ) . items {
2805- doc_impl_item ( w, cx, trait_item, link, render_header ,
2838+ doc_impl_item ( w, cx, trait_item, link, render_mode ,
28062839 false , outer_version, trait_) ?;
28072840 }
28082841
28092842 fn render_default_items ( w : & mut fmt:: Formatter ,
28102843 cx : & Context ,
28112844 t : & clean:: Trait ,
28122845 i : & clean:: Impl ,
2813- render_static : bool ,
2846+ render_mode : RenderMode ,
28142847 outer_version : Option < & str > ) -> fmt:: Result {
28152848 for trait_item in & t. items {
28162849 let n = trait_item. name . clone ( ) ;
@@ -2820,7 +2853,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
28202853 let did = i. trait_ . as_ref ( ) . unwrap ( ) . def_id ( ) . unwrap ( ) ;
28212854 let assoc_link = AssocItemLink :: GotoSource ( did, & i. provided_trait_methods ) ;
28222855
2823- doc_impl_item ( w, cx, trait_item, assoc_link, render_static , true ,
2856+ doc_impl_item ( w, cx, trait_item, assoc_link, render_mode , true ,
28242857 outer_version, None ) ?;
28252858 }
28262859 Ok ( ( ) )
@@ -2829,7 +2862,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
28292862 // If we've implemented a trait, then also emit documentation for all
28302863 // default items which weren't overridden in the implementation block.
28312864 if let Some ( t) = trait_ {
2832- render_default_items ( w, cx, t, & i. inner_impl ( ) , render_header , outer_version) ?;
2865+ render_default_items ( w, cx, t, & i. inner_impl ( ) , render_mode , outer_version) ?;
28332866 }
28342867 write ! ( w, "</div>" ) ?;
28352868 Ok ( ( ) )
0 commit comments