parent
5e13d3aa00
commit
54831f128f
@ -641,11 +641,27 @@ impl Clean<Option<Lifetime>> for ty::Region {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone, Encodable, Decodable, PartialEq)]
|
||||||
|
pub struct WherePredicate {
|
||||||
|
pub name: String,
|
||||||
|
pub bounds: Vec<TyParamBound>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clean<WherePredicate> for ast::WherePredicate {
|
||||||
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
||||||
|
WherePredicate {
|
||||||
|
name: self.ident.clean(cx),
|
||||||
|
bounds: self.bounds.clean(cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// maybe use a Generic enum and use ~[Generic]?
|
// maybe use a Generic enum and use ~[Generic]?
|
||||||
#[deriving(Clone, Encodable, Decodable, PartialEq)]
|
#[deriving(Clone, Encodable, Decodable, PartialEq)]
|
||||||
pub struct Generics {
|
pub struct Generics {
|
||||||
pub lifetimes: Vec<Lifetime>,
|
pub lifetimes: Vec<Lifetime>,
|
||||||
pub type_params: Vec<TyParam>,
|
pub type_params: Vec<TyParam>,
|
||||||
|
pub where_predicates: Vec<WherePredicate>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clean<Generics> for ast::Generics {
|
impl Clean<Generics> for ast::Generics {
|
||||||
@ -653,6 +669,7 @@ impl Clean<Generics> for ast::Generics {
|
|||||||
Generics {
|
Generics {
|
||||||
lifetimes: self.lifetimes.clean(cx),
|
lifetimes: self.lifetimes.clean(cx),
|
||||||
type_params: self.ty_params.clean(cx),
|
type_params: self.ty_params.clean(cx),
|
||||||
|
where_predicates: self.where_clause.predicates.clean(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -663,6 +680,7 @@ impl<'a> Clean<Generics> for (&'a ty::Generics, subst::ParamSpace) {
|
|||||||
Generics {
|
Generics {
|
||||||
type_params: me.types.get_slice(space).to_vec().clean(cx),
|
type_params: me.types.get_slice(space).to_vec().clean(cx),
|
||||||
lifetimes: me.regions.get_slice(space).to_vec().clean(cx),
|
lifetimes: me.regions.get_slice(space).to_vec().clean(cx),
|
||||||
|
where_predicates: vec![]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1260,7 +1278,9 @@ impl Clean<Type> for ty::t {
|
|||||||
ty::ty_bare_fn(ref fty) => BareFunction(box BareFunctionDecl {
|
ty::ty_bare_fn(ref fty) => BareFunction(box BareFunctionDecl {
|
||||||
fn_style: fty.fn_style,
|
fn_style: fty.fn_style,
|
||||||
generics: Generics {
|
generics: Generics {
|
||||||
lifetimes: Vec::new(), type_params: Vec::new()
|
lifetimes: Vec::new(),
|
||||||
|
type_params: Vec::new(),
|
||||||
|
where_predicates: Vec::new()
|
||||||
},
|
},
|
||||||
decl: (ast_util::local_def(0), &fty.sig).clean(cx),
|
decl: (ast_util::local_def(0), &fty.sig).clean(cx),
|
||||||
abi: fty.abi.to_string(),
|
abi: fty.abi.to_string(),
|
||||||
@ -1670,6 +1690,7 @@ impl Clean<BareFunctionDecl> for ast::BareFnTy {
|
|||||||
generics: Generics {
|
generics: Generics {
|
||||||
lifetimes: self.lifetimes.clean(cx),
|
lifetimes: self.lifetimes.clean(cx),
|
||||||
type_params: Vec::new(),
|
type_params: Vec::new(),
|
||||||
|
where_predicates: Vec::new()
|
||||||
},
|
},
|
||||||
decl: self.decl.clean(cx),
|
decl: self.decl.clean(cx),
|
||||||
abi: self.abi.to_string(),
|
abi: self.abi.to_string(),
|
||||||
@ -2172,6 +2193,7 @@ impl Clean<Item> for ast::Typedef {
|
|||||||
generics: Generics {
|
generics: Generics {
|
||||||
lifetimes: Vec::new(),
|
lifetimes: Vec::new(),
|
||||||
type_params: Vec::new(),
|
type_params: Vec::new(),
|
||||||
|
where_predicates: Vec::new()
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
visibility: None,
|
visibility: None,
|
||||||
|
@ -44,6 +44,11 @@ pub struct RawMutableSpace(pub clean::Mutability);
|
|||||||
pub struct Stability<'a>(pub &'a Option<clean::Stability>);
|
pub struct Stability<'a>(pub &'a Option<clean::Stability>);
|
||||||
/// Wrapper struct for emitting the stability level concisely.
|
/// Wrapper struct for emitting the stability level concisely.
|
||||||
pub struct ConciseStability<'a>(pub &'a Option<clean::Stability>);
|
pub struct ConciseStability<'a>(pub &'a Option<clean::Stability>);
|
||||||
|
/// Wrapper struct for emitting a where clause from Generics.
|
||||||
|
pub struct WhereClause<'a>(pub &'a clean::Generics);
|
||||||
|
|
||||||
|
/// Wrapper struct for emitting type parameter bounds.
|
||||||
|
struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
|
||||||
|
|
||||||
impl VisSpace {
|
impl VisSpace {
|
||||||
pub fn get(&self) -> Option<ast::Visibility> {
|
pub fn get(&self) -> Option<ast::Visibility> {
|
||||||
@ -57,6 +62,19 @@ impl FnStyleSpace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> fmt::Show for TyParamBounds<'a> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let &TyParamBounds(bounds) = self;
|
||||||
|
for (i, bound) in bounds.iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
try!(f.write(" + ".as_bytes()));
|
||||||
|
}
|
||||||
|
try!(write!(f, "{}", *bound));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Show for clean::Generics {
|
impl fmt::Show for clean::Generics {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) }
|
if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) }
|
||||||
@ -73,7 +91,6 @@ impl fmt::Show for clean::Generics {
|
|||||||
if self.lifetimes.len() > 0 {
|
if self.lifetimes.len() > 0 {
|
||||||
try!(f.write(", ".as_bytes()));
|
try!(f.write(", ".as_bytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, tp) in self.type_params.iter().enumerate() {
|
for (i, tp) in self.type_params.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
try!(f.write(", ".as_bytes()))
|
try!(f.write(", ".as_bytes()))
|
||||||
@ -81,13 +98,7 @@ impl fmt::Show for clean::Generics {
|
|||||||
try!(f.write(tp.name.as_bytes()));
|
try!(f.write(tp.name.as_bytes()));
|
||||||
|
|
||||||
if tp.bounds.len() > 0 {
|
if tp.bounds.len() > 0 {
|
||||||
try!(f.write(": ".as_bytes()));
|
try!(write!(f, ": {}", TyParamBounds(tp.bounds.as_slice())));
|
||||||
for (i, bound) in tp.bounds.iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
try!(f.write(" + ".as_bytes()));
|
|
||||||
}
|
|
||||||
try!(write!(f, "{}", *bound));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match tp.default {
|
match tp.default {
|
||||||
@ -101,6 +112,24 @@ impl fmt::Show for clean::Generics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> fmt::Show for WhereClause<'a> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let &WhereClause(gens) = self;
|
||||||
|
if gens.where_predicates.len() == 0 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
try!(f.write(" where ".as_bytes()));
|
||||||
|
for (i, pred) in gens.where_predicates.iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
try!(f.write(", ".as_bytes()));
|
||||||
|
}
|
||||||
|
let bounds = pred.bounds.as_slice();
|
||||||
|
try!(write!(f, "{}: {}", pred.name, TyParamBounds(bounds)));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Show for clean::Lifetime {
|
impl fmt::Show for clean::Lifetime {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
try!(f.write(self.get_ref().as_bytes()));
|
try!(f.write(self.get_ref().as_bytes()));
|
||||||
|
@ -56,7 +56,7 @@ use clean;
|
|||||||
use doctree;
|
use doctree;
|
||||||
use fold::DocFolder;
|
use fold::DocFolder;
|
||||||
use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace, Stability};
|
use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace, Stability};
|
||||||
use html::format::{ConciseStability};
|
use html::format::{ConciseStability, WhereClause};
|
||||||
use html::highlight;
|
use html::highlight;
|
||||||
use html::item_type::{ItemType, shortty};
|
use html::item_type::{ItemType, shortty};
|
||||||
use html::item_type;
|
use html::item_type;
|
||||||
@ -1609,11 +1609,12 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||||||
fn item_function(w: &mut fmt::Formatter, it: &clean::Item,
|
fn item_function(w: &mut fmt::Formatter, it: &clean::Item,
|
||||||
f: &clean::Function) -> fmt::Result {
|
f: &clean::Function) -> fmt::Result {
|
||||||
try!(write!(w, "<pre class='rust fn'>{vis}{fn_style}fn \
|
try!(write!(w, "<pre class='rust fn'>{vis}{fn_style}fn \
|
||||||
{name}{generics}{decl}</pre>",
|
{name}{generics}{decl}{where_clause}</pre>",
|
||||||
vis = VisSpace(it.visibility),
|
vis = VisSpace(it.visibility),
|
||||||
fn_style = FnStyleSpace(f.fn_style),
|
fn_style = FnStyleSpace(f.fn_style),
|
||||||
name = it.name.get_ref().as_slice(),
|
name = it.name.get_ref().as_slice(),
|
||||||
generics = f.generics,
|
generics = f.generics,
|
||||||
|
where_clause = WhereClause(&f.generics),
|
||||||
decl = f.decl));
|
decl = f.decl));
|
||||||
document(w, it)
|
document(w, it)
|
||||||
}
|
}
|
||||||
@ -1630,11 +1631,12 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Output the trait definition
|
// Output the trait definition
|
||||||
try!(write!(w, "<pre class='rust trait'>{}trait {}{}{} ",
|
try!(write!(w, "<pre class='rust trait'>{}trait {}{}{}{} ",
|
||||||
VisSpace(it.visibility),
|
VisSpace(it.visibility),
|
||||||
it.name.get_ref().as_slice(),
|
it.name.get_ref().as_slice(),
|
||||||
t.generics,
|
t.generics,
|
||||||
bounds));
|
bounds,
|
||||||
|
WhereClause(&t.generics)));
|
||||||
let required = t.items.iter()
|
let required = t.items.iter()
|
||||||
.filter(|m| {
|
.filter(|m| {
|
||||||
match **m {
|
match **m {
|
||||||
@ -1718,9 +1720,9 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
|
|||||||
match cache.implementors.find(&it.def_id) {
|
match cache.implementors.find(&it.def_id) {
|
||||||
Some(implementors) => {
|
Some(implementors) => {
|
||||||
for i in implementors.iter() {
|
for i in implementors.iter() {
|
||||||
try!(writeln!(w, "<li>{}<code>impl{} {} for {}</code></li>",
|
try!(writeln!(w, "<li>{}<code>impl{} {} for {}{}</code></li>",
|
||||||
ConciseStability(&i.stability),
|
ConciseStability(&i.stability),
|
||||||
i.generics, i.trait_, i.for_));
|
i.generics, i.trait_, i.for_, WhereClause(&i.generics)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
@ -1746,7 +1748,7 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
|
|||||||
g: &clean::Generics, selfty: &clean::SelfTy,
|
g: &clean::Generics, selfty: &clean::SelfTy,
|
||||||
d: &clean::FnDecl) -> fmt::Result {
|
d: &clean::FnDecl) -> fmt::Result {
|
||||||
write!(w, "{}fn <a href='#{ty}.{name}' class='fnname'>{name}</a>\
|
write!(w, "{}fn <a href='#{ty}.{name}' class='fnname'>{name}</a>\
|
||||||
{generics}{decl}",
|
{generics}{decl}{where_clause}",
|
||||||
match fn_style {
|
match fn_style {
|
||||||
ast::UnsafeFn => "unsafe ",
|
ast::UnsafeFn => "unsafe ",
|
||||||
_ => "",
|
_ => "",
|
||||||
@ -1754,7 +1756,8 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
|
|||||||
ty = shortty(it),
|
ty = shortty(it),
|
||||||
name = it.name.get_ref().as_slice(),
|
name = it.name.get_ref().as_slice(),
|
||||||
generics = *g,
|
generics = *g,
|
||||||
decl = Method(selfty, d))
|
decl = Method(selfty, d),
|
||||||
|
where_clause = WhereClause(g))
|
||||||
}
|
}
|
||||||
match meth.inner {
|
match meth.inner {
|
||||||
clean::TyMethodItem(ref m) => {
|
clean::TyMethodItem(ref m) => {
|
||||||
@ -1809,10 +1812,11 @@ fn item_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
|||||||
|
|
||||||
fn item_enum(w: &mut fmt::Formatter, it: &clean::Item,
|
fn item_enum(w: &mut fmt::Formatter, it: &clean::Item,
|
||||||
e: &clean::Enum) -> fmt::Result {
|
e: &clean::Enum) -> fmt::Result {
|
||||||
try!(write!(w, "<pre class='rust enum'>{}enum {}{}",
|
try!(write!(w, "<pre class='rust enum'>{}enum {}{}{}",
|
||||||
VisSpace(it.visibility),
|
VisSpace(it.visibility),
|
||||||
it.name.get_ref().as_slice(),
|
it.name.get_ref().as_slice(),
|
||||||
e.generics));
|
e.generics,
|
||||||
|
WhereClause(&e.generics)));
|
||||||
if e.variants.len() == 0 && !e.variants_stripped {
|
if e.variants.len() == 0 && !e.variants_stripped {
|
||||||
try!(write!(w, " {{}}"));
|
try!(write!(w, " {{}}"));
|
||||||
} else {
|
} else {
|
||||||
@ -1916,7 +1920,7 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
|
|||||||
if structhead {"struct "} else {""},
|
if structhead {"struct "} else {""},
|
||||||
it.name.get_ref().as_slice()));
|
it.name.get_ref().as_slice()));
|
||||||
match g {
|
match g {
|
||||||
Some(g) => try!(write!(w, "{}", *g)),
|
Some(g) => try!(write!(w, "{}{}", *g, WhereClause(g))),
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
match ty {
|
match ty {
|
||||||
@ -2008,7 +2012,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
|
|||||||
Some(ref ty) => try!(write!(w, "{} for ", *ty)),
|
Some(ref ty) => try!(write!(w, "{} for ", *ty)),
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
try!(write!(w, "{}</code></h3>", i.impl_.for_));
|
try!(write!(w, "{}{}</code></h3>", i.impl_.for_, WhereClause(&i.impl_.generics)));
|
||||||
match i.dox {
|
match i.dox {
|
||||||
Some(ref dox) => {
|
Some(ref dox) => {
|
||||||
try!(write!(w, "<div class='docblock'>{}</div>",
|
try!(write!(w, "<div class='docblock'>{}</div>",
|
||||||
|
6
src/test/run-make/rustdoc-where/Makefile
Normal file
6
src/test/run-make/rustdoc-where/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-include ../tools.mk
|
||||||
|
|
||||||
|
all: verify.sh foo.rs
|
||||||
|
$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
|
||||||
|
cp verify.sh $(TMPDIR)
|
||||||
|
$(call RUN,verify.sh) $(TMPDIR)
|
26
src/test/run-make/rustdoc-where/foo.rs
Normal file
26
src/test/run-make/rustdoc-where/foo.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
pub trait MyTrait {}
|
||||||
|
|
||||||
|
pub struct Alpha<A> where A: MyTrait;
|
||||||
|
pub trait Bravo<B> where B: MyTrait {}
|
||||||
|
pub fn charlie<C>() where C: MyTrait {}
|
||||||
|
|
||||||
|
pub struct Delta<D>;
|
||||||
|
impl<D> Delta<D> where D: MyTrait {
|
||||||
|
pub fn delta() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Echo<E>;
|
||||||
|
impl<E> MyTrait for Echo<E> where E: MyTrait {}
|
||||||
|
|
||||||
|
pub enum Foxtrot<F> {}
|
||||||
|
impl<F> MyTrait for Foxtrot<F> where F: MyTrait {}
|
23
src/test/run-make/rustdoc-where/verify.sh
Executable file
23
src/test/run-make/rustdoc-where/verify.sh
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# $1 is the TMPDIR
|
||||||
|
DOC=$1/doc/foo
|
||||||
|
|
||||||
|
grep "Alpha.*where.*A:.*MyTrait" $DOC/struct.Alpha.html > /dev/null
|
||||||
|
echo "Alpha"
|
||||||
|
grep "Bravo.*where.*B:.*MyTrait" $DOC/trait.Bravo.html > /dev/null
|
||||||
|
echo "Bravo"
|
||||||
|
grep "charlie.*where.*C:.*MyTrait" $DOC/fn.charlie.html > /dev/null
|
||||||
|
echo "Charlie"
|
||||||
|
grep "impl.*Delta.*where.*D:.*MyTrait" $DOC/struct.Delta.html > /dev/null
|
||||||
|
echo "Delta"
|
||||||
|
grep "impl.*MyTrait.*for.*Echo.*where.*E:.*MyTrait" $DOC/struct.Echo.html > /dev/null
|
||||||
|
echo "Echo"
|
||||||
|
grep "impl.*MyTrait.*for.*Foxtrot.*where.*F:.*MyTrait" $DOC/enum.Foxtrot.html > /dev/null
|
||||||
|
echo "Foxtrot"
|
||||||
|
|
||||||
|
# check "Implementors" section of MyTrait
|
||||||
|
grep "impl.*MyTrait.*for.*Echo.*where.*E:.*MyTrait" $DOC/trait.MyTrait.html > /dev/null
|
||||||
|
grep "impl.*MyTrait.*for.*Foxtrot.*where.*F:.*MyTrait" $DOC/trait.MyTrait.html > /dev/null
|
||||||
|
echo "Implementors OK"
|
Loading…
Reference in New Issue
Block a user