]> git.lizzy.rs Git - rust.git/commitdiff
rustdoc: Fix associated types in signatures
authorUlrik Sverdrup <root@localhost>
Mon, 25 May 2015 13:06:38 +0000 (15:06 +0200)
committerUlrik Sverdrup <root@localhost>
Mon, 25 May 2015 17:06:58 +0000 (19:06 +0200)
Functions such as `fn foo<I: Iterator>(x: I::Item)` would not
render correctly and displayed `I` instead of `I::Item`. Same thing
with `I::Item` appearing in where bounds.

This fixes the bug by using paths for generics.

Fixes #24417

src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/test/rustdoc/assoc-types.rs

index d985fa4c8cc6c127618824c221878d0f2181f087..701e99a6e3bf70a00fa7a8a5df14787a90fc985f 100644 (file)
@@ -664,6 +664,7 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
                 path: path,
                 typarams: None,
                 did: did,
+                is_generic: false,
             },
             lifetimes: vec![]
         }, ast::TraitBoundModifier::None)
@@ -706,7 +707,12 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
         }
 
         TraitBound(PolyTrait {
-            trait_: ResolvedPath { path: path, typarams: None, did: self.def_id, },
+            trait_: ResolvedPath {
+                path: path,
+                typarams: None,
+                did: self.def_id,
+                is_generic: false,
+            },
             lifetimes: late_bounds
         }, ast::TraitBoundModifier::None)
     }
@@ -1394,11 +1400,13 @@ pub struct PolyTrait {
 /// it does not preserve mutability or boxes.
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
 pub enum Type {
-    /// structs/enums/traits (anything that'd be an ast::TyPath)
+    /// structs/enums/traits (most that'd be an ast::TyPath)
     ResolvedPath {
         path: Path,
         typarams: Option<Vec<TyParamBound>>,
         did: ast::DefId,
+        /// true if is a `T::Name` path for associated types
+        is_generic: bool,
     },
     /// For parameterized types, so the consumer of the JSON don't go
     /// looking for types which don't exist anywhere.
@@ -1587,8 +1595,13 @@ fn clean(&self, cx: &DocContext) -> Type {
             TyObjectSum(ref lhs, ref bounds) => {
                 let lhs_ty = lhs.clean(cx);
                 match lhs_ty {
-                    ResolvedPath { path, typarams: None, did } => {
-                        ResolvedPath { path: path, typarams: Some(bounds.clean(cx)), did: did}
+                    ResolvedPath { path, typarams: None, did, is_generic } => {
+                        ResolvedPath {
+                            path: path,
+                            typarams: Some(bounds.clean(cx)),
+                            did: did,
+                            is_generic: is_generic,
+                        }
                     }
                     _ => {
                         lhs_ty // shouldn't happen
@@ -1668,6 +1681,7 @@ fn clean(&self, cx: &DocContext) -> Type {
                     path: path,
                     typarams: None,
                     did: did,
+                    is_generic: false,
                 }
             }
             ty::ty_trait(box ty::TyTrait { ref principal, ref bounds }) => {
@@ -1682,6 +1696,7 @@ fn clean(&self, cx: &DocContext) -> Type {
                     path: path,
                     typarams: Some(typarams),
                     did: did,
+                    is_generic: false,
                 }
             }
             ty::ty_tup(ref t) => Tuple(t.clean(cx)),
@@ -2572,10 +2587,7 @@ fn resolve_type(cx: &DocContext,
         None => panic!("unresolved id not in defmap")
     };
 
-    match def {
-        def::DefSelfTy(..) if path.segments.len() == 1 => {
-            return Generic(token::get_name(special_idents::type_self.name).to_string());
-        }
+    let is_generic = match def {
         def::DefPrimTy(p) => match p {
             ast::TyStr => return Primitive(Str),
             ast::TyBool => return Primitive(Bool),
@@ -2593,13 +2605,14 @@ fn resolve_type(cx: &DocContext,
             ast::TyFloat(ast::TyF32) => return Primitive(F32),
             ast::TyFloat(ast::TyF64) => return Primitive(F64),
         },
-        def::DefTyParam(_, _, _, n) => {
-            return Generic(token::get_name(n).to_string())
+        def::DefSelfTy(..) if path.segments.len() == 1 => {
+            return Generic(token::get_name(special_idents::type_self.name).to_string());
         }
-        _ => {}
+        def::DefSelfTy(..) | def::DefTyParam(..) => true,
+        _ => false,
     };
     let did = register_def(&*cx, def);
-    ResolvedPath { path: path, typarams: None, did: did }
+    ResolvedPath { path: path, typarams: None, did: did, is_generic: is_generic }
 }
 
 fn register_def(cx: &DocContext, def: def::Def) -> ast::DefId {
@@ -2798,6 +2811,7 @@ fn lang_struct(cx: &DocContext, did: Option<ast::DefId>,
                 }
             }],
         },
+        is_generic: false,
     }
 }
 
index bb53d532f52f725b00453ad44dda63a16e221b70..e899f668e402dba725f069f54bf71ae3fbd6b793 100644 (file)
@@ -427,9 +427,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             clean::Generic(ref name) => {
                 f.write_str(name)
             }
-            clean::ResolvedPath{ did, ref typarams, ref path } => {
-                // Paths like Self::Output should be rendered with all segments
-                try!(resolved_path(f, did, path, path.segments[0].name == "Self"));
+            clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => {
+                // Paths like T::Output and Self::Output should be rendered with all segments
+                try!(resolved_path(f, did, path, is_generic));
                 tybounds(f, typarams)
             }
             clean::Infer => write!(f, "_"),
index 20076a764943c2896ed94e856a9b3e7eda91dfaf..d5047ade062dc164f9b7a296923b13aafe3a8b8e 100644 (file)
@@ -18,3 +18,25 @@ pub trait Index<I: ?Sized> {
     //      "fn index<'a>(&'a self, index: I) -> &'a Self::Output"
     fn index<'a>(&'a self, index: I) -> &'a Self::Output;
 }
+
+// @has assoc_types/fn.use_output.html
+// @has - '//*[@class="rust fn"]' '-> &T::Output'
+pub fn use_output<T: Index<usize>>(obj: &T, index: usize) -> &T::Output {
+    obj.index(index)
+}
+
+pub trait Feed {
+    type Input;
+}
+
+// @has assoc_types/fn.use_input.html
+// @has - '//*[@class="rust fn"]' 'T::Input'
+pub fn use_input<T: Feed>(_feed: &T, _element: T::Input) { }
+
+// @has assoc_types/fn.cmp_input.html
+// @has - '//*[@class="rust fn"]' 'where T::Input: PartialEq<U::Input>'
+pub fn cmp_input<T: Feed, U: Feed>(a: &T::Input, b: &U::Input) -> bool
+    where T::Input: PartialEq<U::Input>
+{
+    a == b
+}