2013-10-03 10:24:40 -07:00
|
|
|
//! HTML formatting module
|
|
|
|
//!
|
2015-02-05 15:04:07 +03:00
|
|
|
//! This module contains a large number of `fmt::Display` implementations for
|
2013-10-03 10:24:40 -07:00
|
|
|
//! various types in `rustdoc::clean`. These implementations all currently
|
|
|
|
//! assume that HTML output is desired, although it may be possible to redesign
|
|
|
|
//! them in the future to instead emit any format desired.
|
|
|
|
|
2019-02-05 10:12:43 -05:00
|
|
|
use std::borrow::Cow;
|
2013-09-18 22:18:38 -07:00
|
|
|
use std::fmt;
|
|
|
|
|
2016-11-29 08:15:16 +02:00
|
|
|
use rustc::hir::def_id::DefId;
|
2018-04-25 19:30:39 +03:00
|
|
|
use rustc_target::spec::abi::Abi;
|
2016-03-29 08:50:44 +03:00
|
|
|
use rustc::hir;
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2016-08-23 18:48:10 -04:00
|
|
|
use clean::{self, PrimitiveType};
|
2016-04-17 08:54:48 +02:00
|
|
|
use core::DocAccessLevels;
|
2014-04-09 16:49:31 +09:00
|
|
|
use html::item_type::ItemType;
|
Remove hoedown from rustdoc
Is it really time? Have our months, no, *years* of suffering come to an end? Are we finally able to cast off the pall of Hoedown? The weight which has dragged us down for so long?
-----
So, timeline for those who need to catch up:
* Way back in December 2016, [we decided we wanted to switch out the markdown renderer](https://github.com/rust-lang/rust/issues/38400). However, this was put on hold because the build system at the time made it difficult to pull in dependencies from crates.io.
* A few months later, in March 2017, [the first PR was done, to switch out the renderers entirely](https://github.com/rust-lang/rust/pull/40338). The PR itself was fraught with CI and build system issues, but eventually landed.
* However, not all was well in the Rustdoc world. During the PR and shortly after, we noticed [some differences in the way the two parsers handled some things](https://github.com/rust-lang/rust/issues/40912), and some of these differences were major enough to break the docs for some crates.
* A couple weeks afterward, [Hoedown was put back in](https://github.com/rust-lang/rust/pull/41290), at this point just to catch tests that Pulldown was "spuriously" running. This would at least provide some warning about spurious tests, rather than just breaking spontaneously.
* However, the problems had created enough noise by this point that just a few days after that, [Hoedown was switched back to the default](https://github.com/rust-lang/rust/pull/41431) while we came up with a solution for properly warning about the differences.
* That solution came a few weeks later, [as a series of warnings when the HTML emitted by the two parsers was semantically different](https://github.com/rust-lang/rust/pull/41991). But that came at a cost, as now rustdoc needed proc-macro support (the new crate needed some custom derives farther down its dependency tree), and the build system was not equipped to handle it at the time. It was worked on for three months as the issue stumped more and more people.
* In that time, [bootstrap was completely reworked](https://github.com/rust-lang/rust/pull/43059) to change how it ordered compilation, and [the method by which it built rustdoc would change](https://github.com/rust-lang/rust/pull/43482), as well. This allowed it to only be built after stage1, when proc-macros would be available, allowing the "rendering differences" PR to finally land.
* The warnings were not perfect, and revealed a few [spurious](https://github.com/rust-lang/rust/pull/44368) [differences](https://github.com/rust-lang/rust/pull/45421) between how we handled the renderers.
* Once these were handled, [we flipped the switch to turn on the "rendering difference" warnings all the time](https://github.com/rust-lang/rust/pull/45324), in October 2017. This began the "warning cycle" for this change, and landed in stable in 1.23, on 2018-01-04.
* Once those warnings hit stable, and after a couple weeks of seeing whether we would get any more reports than what we got from sitting on nightly/beta, [we switched the renderers](https://github.com/rust-lang/rust/pull/47398), making Pulldown the default but still offering the option to use Hoedown.
And that brings us to the present. We haven't received more new issues from this in the meantime, and the "switch by default" is now on beta. Our reasoning is that, at this point, anyone who would have been affected by this has run into it already.
2018-02-16 15:09:19 +01:00
|
|
|
use html::render::{self, cache, CURRENT_LOCATION_KEY};
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2013-10-03 10:24:40 -07:00
|
|
|
/// Helper to render an optional visibility with a space after it (if the
|
|
|
|
/// visibility is preset)
|
2015-03-30 09:40:52 -04:00
|
|
|
#[derive(Copy, Clone)]
|
2016-04-11 08:15:14 +00:00
|
|
|
pub struct VisSpace<'a>(pub &'a Option<clean::Visibility>);
|
2014-04-06 18:04:40 -07:00
|
|
|
/// Similarly to VisSpace, this structure is used to render a function style with a
|
2013-10-03 10:24:40 -07:00
|
|
|
/// space after it.
|
2015-03-30 09:40:52 -04:00
|
|
|
#[derive(Copy, Clone)]
|
2015-07-31 00:04:06 -07:00
|
|
|
pub struct UnsafetySpace(pub hir::Unsafety);
|
2015-02-25 22:05:07 +02:00
|
|
|
/// Similarly to VisSpace, this structure is used to render a function constness
|
|
|
|
/// with a space after it.
|
2015-05-05 08:47:04 -04:00
|
|
|
#[derive(Copy, Clone)]
|
2015-07-31 00:04:06 -07:00
|
|
|
pub struct ConstnessSpace(pub hir::Constness);
|
2018-05-17 14:47:52 -07:00
|
|
|
/// Similarly to VisSpace, this structure is used to render a function asyncness
|
|
|
|
/// with a space after it.
|
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct AsyncSpace(pub hir::IsAsync);
|
2014-06-05 17:20:59 -07:00
|
|
|
/// Similar to VisSpace, but used for mutability
|
2015-03-30 09:40:52 -04:00
|
|
|
#[derive(Copy, Clone)]
|
2014-06-05 17:20:59 -07:00
|
|
|
pub struct MutableSpace(pub clean::Mutability);
|
2014-07-11 11:35:02 +02:00
|
|
|
/// Similar to VisSpace, but used for mutability
|
2015-03-30 09:40:52 -04:00
|
|
|
#[derive(Copy, Clone)]
|
2014-07-11 11:35:02 +02:00
|
|
|
pub struct RawMutableSpace(pub clean::Mutability);
|
2014-09-25 02:01:42 -07:00
|
|
|
/// Wrapper struct for emitting type parameter bounds.
|
2018-06-14 12:08:58 +01:00
|
|
|
pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]);
|
2015-01-07 14:58:31 -08:00
|
|
|
/// Wrapper struct for emitting a comma-separated list of items
|
|
|
|
pub struct CommaSep<'a, T: 'a>(pub &'a [T]);
|
2015-04-07 14:22:55 -07:00
|
|
|
pub struct AbiSpace(pub Abi);
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2019-02-05 10:12:43 -05:00
|
|
|
/// Wrapper struct for properly emitting a function or method declaration.
|
|
|
|
pub struct Function<'a> {
|
2017-04-04 10:31:57 -05:00
|
|
|
/// The declaration to emit.
|
|
|
|
pub decl: &'a clean::FnDecl,
|
2019-02-06 11:46:41 -05:00
|
|
|
/// The length of the function header and name. In other words, the number of characters in the
|
|
|
|
/// function declaration up to but not including the parentheses.
|
|
|
|
///
|
|
|
|
/// Used to determine line-wrapping.
|
|
|
|
pub header_len: usize,
|
2017-04-04 10:31:57 -05:00
|
|
|
/// The number of spaces to indent each successive line with, if line-wrapping is necessary.
|
|
|
|
pub indent: usize,
|
2019-02-05 10:12:43 -05:00
|
|
|
/// Whether the function is async or not.
|
|
|
|
pub asyncness: hir::IsAsync,
|
2017-04-04 10:31:57 -05:00
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Wrapper struct for emitting a where-clause from Generics.
|
2017-03-31 18:04:42 -05:00
|
|
|
pub struct WhereClause<'a>{
|
2019-02-08 14:53:55 +01:00
|
|
|
/// The Generics from which to emit a where-clause.
|
2017-03-31 18:04:42 -05:00
|
|
|
pub gens: &'a clean::Generics,
|
2017-04-04 10:31:57 -05:00
|
|
|
/// The number of spaces to indent each line with.
|
2017-03-31 18:04:42 -05:00
|
|
|
pub indent: usize,
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Whether the where-clause needs to add a comma and newline after the last bound.
|
2017-03-31 18:04:42 -05:00
|
|
|
pub end_newline: bool,
|
|
|
|
}
|
|
|
|
|
2016-04-25 08:24:50 +02:00
|
|
|
pub struct HRef<'a> {
|
|
|
|
pub did: DefId,
|
|
|
|
pub text: &'a str,
|
|
|
|
}
|
|
|
|
|
2016-03-25 06:08:11 +00:00
|
|
|
impl<'a> VisSpace<'a> {
|
2016-04-11 08:15:14 +00:00
|
|
|
pub fn get(self) -> &'a Option<clean::Visibility> {
|
2016-03-25 06:08:11 +00:00
|
|
|
let VisSpace(v) = self; v
|
2013-11-01 18:06:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-09 10:36:46 -05:00
|
|
|
impl UnsafetySpace {
|
2015-07-31 00:04:06 -07:00
|
|
|
pub fn get(&self) -> hir::Unsafety {
|
2014-12-09 10:36:46 -05:00
|
|
|
let UnsafetySpace(v) = *self; v
|
2013-11-01 18:06:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 22:05:07 +02:00
|
|
|
impl ConstnessSpace {
|
2015-07-31 00:04:06 -07:00
|
|
|
pub fn get(&self) -> hir::Constness {
|
2015-02-25 22:05:07 +02:00
|
|
|
let ConstnessSpace(v) = *self; v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> {
|
2015-01-07 14:58:31 -08:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
for (i, item) in self.0.iter().enumerate() {
|
2016-03-22 22:01:37 -05:00
|
|
|
if i != 0 { write!(f, ", ")?; }
|
2016-09-26 16:02:21 -05:00
|
|
|
fmt::Display::fmt(item, f)?;
|
2015-01-07 14:58:31 -08:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-14 12:08:58 +01:00
|
|
|
impl<'a> fmt::Display for GenericBounds<'a> {
|
2014-09-25 02:01:42 -07:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2018-06-14 12:08:58 +01:00
|
|
|
let &GenericBounds(bounds) = self;
|
2014-09-25 02:01:42 -07:00
|
|
|
for (i, bound) in bounds.iter().enumerate() {
|
|
|
|
if i > 0 {
|
2016-03-22 22:01:37 -05:00
|
|
|
f.write_str(" + ")?;
|
2014-09-25 02:01:42 -07:00
|
|
|
}
|
2016-09-26 16:02:21 -05:00
|
|
|
fmt::Display::fmt(bound, f)?;
|
2014-09-25 02:01:42 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-12 17:53:29 +01:00
|
|
|
impl fmt::Display for clean::GenericParamDef {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2018-05-27 16:56:01 +01:00
|
|
|
match self.kind {
|
|
|
|
clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name),
|
|
|
|
clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => {
|
|
|
|
f.write_str(&self.name)?;
|
2013-09-18 22:18:38 -07:00
|
|
|
|
2018-05-27 16:56:01 +01:00
|
|
|
if !bounds.is_empty() {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
2018-06-14 12:08:58 +01:00
|
|
|
write!(f, ": {:#}", GenericBounds(bounds))?;
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2018-06-14 12:08:58 +01:00
|
|
|
write!(f, ": {}", GenericBounds(bounds))?;
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2014-06-21 05:03:33 -07:00
|
|
|
|
2018-05-27 16:56:01 +01:00
|
|
|
if let Some(ref ty) = default {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, " = {:#}", ty)?;
|
|
|
|
} else {
|
|
|
|
write!(f, " = {}", ty)?;
|
|
|
|
}
|
2017-10-16 21:07:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2019-02-15 22:24:00 +00:00
|
|
|
clean::GenericParamDefKind::Const { ref ty, .. } => {
|
|
|
|
f.write_str("const ")?;
|
|
|
|
f.write_str(&self.name)?;
|
|
|
|
|
|
|
|
if f.alternate() {
|
|
|
|
write!(f, ": {:#}", ty)
|
|
|
|
} else {
|
|
|
|
write!(f, ": {}", ty)
|
|
|
|
}
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2017-10-16 21:07:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for clean::Generics {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2018-03-24 11:03:06 +09:00
|
|
|
let real_params = self.params
|
|
|
|
.iter()
|
|
|
|
.filter(|p| !p.is_synthetic_type_param())
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
if real_params.is_empty() {
|
|
|
|
return Ok(());
|
|
|
|
}
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
2018-03-24 11:03:06 +09:00
|
|
|
write!(f, "<{:#}>", CommaSep(&real_params))
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2018-03-24 11:03:06 +09:00
|
|
|
write!(f, "<{}>", CommaSep(&real_params))
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl<'a> fmt::Display for WhereClause<'a> {
|
2014-09-25 02:01:42 -07:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-04-05 10:02:37 -05:00
|
|
|
let &WhereClause { gens, indent, end_newline } = self;
|
2015-03-24 16:53:34 -07:00
|
|
|
if gens.where_predicates.is_empty() {
|
2014-09-25 02:01:42 -07:00
|
|
|
return Ok(());
|
|
|
|
}
|
2016-10-13 10:17:25 -05:00
|
|
|
let mut clause = String::new();
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
2017-03-31 18:04:42 -05:00
|
|
|
clause.push_str(" where");
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2017-03-31 18:04:42 -05:00
|
|
|
if end_newline {
|
2017-04-06 14:19:45 -05:00
|
|
|
clause.push_str(" <span class=\"where fmt-newline\">where");
|
2017-03-31 18:04:42 -05:00
|
|
|
} else {
|
2017-04-06 14:19:45 -05:00
|
|
|
clause.push_str(" <span class=\"where\">where");
|
2017-03-31 18:04:42 -05:00
|
|
|
}
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2014-09-25 02:01:42 -07:00
|
|
|
for (i, pred) in gens.where_predicates.iter().enumerate() {
|
2017-03-31 18:04:42 -05:00
|
|
|
if f.alternate() {
|
|
|
|
clause.push(' ');
|
|
|
|
} else {
|
|
|
|
clause.push_str("<br>");
|
2014-09-25 02:01:42 -07:00
|
|
|
}
|
2017-03-31 18:04:42 -05:00
|
|
|
|
2014-12-23 01:08:00 -08:00
|
|
|
match pred {
|
2014-12-24 00:58:21 -08:00
|
|
|
&clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
|
2015-02-01 21:53:25 -05:00
|
|
|
let bounds = bounds;
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
2018-06-14 12:08:58 +01:00
|
|
|
clause.push_str(&format!("{:#}: {:#}", ty, GenericBounds(bounds)));
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2018-06-14 12:08:58 +01:00
|
|
|
clause.push_str(&format!("{}: {}", ty, GenericBounds(bounds)));
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2014-12-24 00:58:21 -08:00
|
|
|
}
|
2014-12-23 01:08:00 -08:00
|
|
|
&clean::WherePredicate::RegionPredicate { ref lifetime,
|
|
|
|
ref bounds } => {
|
2016-10-13 10:17:25 -05:00
|
|
|
clause.push_str(&format!("{}: ", lifetime));
|
2014-12-23 01:08:00 -08:00
|
|
|
for (i, lifetime) in bounds.iter().enumerate() {
|
|
|
|
if i > 0 {
|
2016-10-13 10:17:25 -05:00
|
|
|
clause.push_str(" + ");
|
2014-12-23 01:08:00 -08:00
|
|
|
}
|
|
|
|
|
2018-07-27 11:11:18 +02:00
|
|
|
clause.push_str(&lifetime.to_string());
|
2014-12-23 01:08:00 -08:00
|
|
|
}
|
2014-12-24 00:58:21 -08:00
|
|
|
}
|
2015-01-10 23:50:46 -08:00
|
|
|
&clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
2016-10-13 10:17:25 -05:00
|
|
|
clause.push_str(&format!("{:#} == {:#}", lhs, rhs));
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2016-10-13 10:17:25 -05:00
|
|
|
clause.push_str(&format!("{} == {}", lhs, rhs));
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2014-12-23 01:08:00 -08:00
|
|
|
}
|
|
|
|
}
|
2017-03-31 18:04:42 -05:00
|
|
|
|
|
|
|
if i < gens.where_predicates.len() - 1 || end_newline {
|
|
|
|
clause.push(',');
|
|
|
|
}
|
2014-09-25 02:01:42 -07:00
|
|
|
}
|
2017-04-06 18:36:14 -05:00
|
|
|
|
|
|
|
if end_newline {
|
2017-08-28 22:40:09 +02:00
|
|
|
// add a space so stripping <br> tags and breaking spaces still renders properly
|
2017-04-06 18:36:14 -05:00
|
|
|
if f.alternate() {
|
|
|
|
clause.push(' ');
|
|
|
|
} else {
|
|
|
|
clause.push_str(" ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-26 16:02:21 -05:00
|
|
|
if !f.alternate() {
|
2016-10-13 13:58:04 -05:00
|
|
|
clause.push_str("</span>");
|
2018-04-01 13:48:15 +09:00
|
|
|
let padding = " ".repeat(indent + 4);
|
2017-03-31 18:04:42 -05:00
|
|
|
clause = clause.replace("<br>", &format!("<br>{}", padding));
|
2018-04-01 13:48:15 +09:00
|
|
|
clause.insert_str(0, &" ".repeat(indent.saturating_sub(1)));
|
2017-04-06 18:36:14 -05:00
|
|
|
if !end_newline {
|
2017-03-31 18:04:42 -05:00
|
|
|
clause.insert_str(0, "<br>");
|
2016-10-13 10:17:25 -05:00
|
|
|
}
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2016-10-13 10:17:25 -05:00
|
|
|
write!(f, "{}", clause)
|
2014-09-25 02:01:42 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::Lifetime {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-03-22 22:01:37 -05:00
|
|
|
f.write_str(self.get_ref())?;
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::PolyTrait {
|
2014-12-16 08:50:52 -08:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-10-16 21:07:26 +02:00
|
|
|
if !self.generic_params.is_empty() {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
2017-10-16 21:07:26 +02:00
|
|
|
write!(f, "for<{:#}> ", CommaSep(&self.generic_params))?;
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2017-10-16 21:07:26 +02:00
|
|
|
write!(f, "for<{}> ", CommaSep(&self.generic_params))?;
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{:#}", self.trait_)
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", self.trait_)
|
2014-12-16 08:50:52 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-14 12:08:58 +01:00
|
|
|
impl fmt::Display for clean::GenericBound {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2018-06-14 12:23:46 +01:00
|
|
|
clean::GenericBound::Outlives(ref lt) => {
|
2014-10-05 07:35:04 -07:00
|
|
|
write!(f, "{}", *lt)
|
|
|
|
}
|
2018-06-14 12:23:46 +01:00
|
|
|
clean::GenericBound::TraitBound(ref ty, modifier) => {
|
2014-12-24 22:34:57 +13:00
|
|
|
let modifier_str = match modifier {
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::TraitBoundModifier::None => "",
|
|
|
|
hir::TraitBoundModifier::Maybe => "?",
|
2014-12-24 22:34:57 +13:00
|
|
|
};
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{}{:#}", modifier_str, *ty)
|
|
|
|
} else {
|
|
|
|
write!(f, "{}{}", modifier_str, *ty)
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-13 11:32:37 +00:00
|
|
|
impl fmt::Display for clean::GenericArgs {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2014-12-16 12:40:43 -08:00
|
|
|
match *self {
|
2018-02-13 11:32:37 +00:00
|
|
|
clean::GenericArgs::AngleBracketed {
|
2015-01-07 16:10:40 -08:00
|
|
|
ref lifetimes, ref types, ref bindings
|
|
|
|
} => {
|
2015-03-24 16:54:09 -07:00
|
|
|
if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
f.write_str("<")?;
|
|
|
|
} else {
|
|
|
|
f.write_str("<")?;
|
|
|
|
}
|
2014-12-16 12:40:43 -08:00
|
|
|
let mut comma = false;
|
2015-01-31 12:20:46 -05:00
|
|
|
for lifetime in lifetimes {
|
2014-12-16 12:40:43 -08:00
|
|
|
if comma {
|
2016-09-26 16:02:21 -05:00
|
|
|
f.write_str(", ")?;
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
|
|
|
comma = true;
|
2016-03-22 22:01:37 -05:00
|
|
|
write!(f, "{}", *lifetime)?;
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2015-01-31 12:20:46 -05:00
|
|
|
for ty in types {
|
2014-12-16 12:40:43 -08:00
|
|
|
if comma {
|
2016-09-26 16:02:21 -05:00
|
|
|
f.write_str(", ")?;
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
|
|
|
comma = true;
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{:#}", *ty)?;
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", *ty)?;
|
|
|
|
}
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
2015-01-31 12:20:46 -05:00
|
|
|
for binding in bindings {
|
2015-01-07 16:10:40 -08:00
|
|
|
if comma {
|
2016-09-26 16:02:21 -05:00
|
|
|
f.write_str(", ")?;
|
2015-01-07 16:10:40 -08:00
|
|
|
}
|
|
|
|
comma = true;
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{:#}", *binding)?;
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", *binding)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if f.alternate() {
|
|
|
|
f.write_str(">")?;
|
|
|
|
} else {
|
|
|
|
f.write_str(">")?;
|
2015-01-07 16:10:40 -08:00
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
2018-02-13 11:32:37 +00:00
|
|
|
clean::GenericArgs::Parenthesized { ref inputs, ref output } => {
|
2016-03-22 22:01:37 -05:00
|
|
|
f.write_str("(")?;
|
2014-12-16 12:40:43 -08:00
|
|
|
let mut comma = false;
|
2015-01-31 12:20:46 -05:00
|
|
|
for ty in inputs {
|
2014-01-30 11:30:21 -08:00
|
|
|
if comma {
|
2016-03-22 22:01:37 -05:00
|
|
|
f.write_str(", ")?;
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2013-10-29 06:03:32 -04:00
|
|
|
comma = true;
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{:#}", *ty)?;
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", *ty)?;
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
f.write_str(")")?;
|
2014-12-16 12:40:43 -08:00
|
|
|
if let Some(ref ty) = *output {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, " -> {:#}", ty)?;
|
|
|
|
} else {
|
|
|
|
write!(f, " -> {}", ty)?;
|
|
|
|
}
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::PathSegment {
|
2014-12-16 12:40:43 -08:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-03-22 22:01:37 -05:00
|
|
|
f.write_str(&self.name)?;
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
2018-02-23 17:48:54 +00:00
|
|
|
write!(f, "{:#}", self.args)
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2018-02-23 17:48:54 +00:00
|
|
|
write!(f, "{}", self.args)
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::Path {
|
2014-12-16 12:40:43 -08:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
if self.global {
|
2016-03-22 22:01:37 -05:00
|
|
|
f.write_str("::")?
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i, seg) in self.segments.iter().enumerate() {
|
|
|
|
if i > 0 {
|
2016-03-22 22:01:37 -05:00
|
|
|
f.write_str("::")?
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{:#}", seg)?;
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", seg)?;
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-16 06:32:28 -04:00
|
|
|
pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
|
2015-04-06 17:56:35 -07:00
|
|
|
let cache = cache();
|
2016-04-24 14:11:26 +02:00
|
|
|
if !did.is_local() && !cache.access_levels.is_doc_reachable(did) {
|
|
|
|
return None
|
|
|
|
}
|
|
|
|
|
2015-04-06 17:56:35 -07:00
|
|
|
let loc = CURRENT_LOCATION_KEY.with(|l| l.borrow().clone());
|
2016-07-09 14:07:37 +01:00
|
|
|
let (fqp, shortty, mut url) = match cache.paths.get(&did) {
|
|
|
|
Some(&(ref fqp, shortty)) => {
|
2018-04-01 13:48:15 +09:00
|
|
|
(fqp, shortty, "../".repeat(loc.len()))
|
2016-07-09 14:07:37 +01:00
|
|
|
}
|
2017-12-08 17:32:04 -08:00
|
|
|
None => {
|
|
|
|
let &(ref fqp, shortty) = cache.external_paths.get(&did)?;
|
|
|
|
(fqp, shortty, match cache.extern_locations[&did.krate] {
|
|
|
|
(.., render::Remote(ref s)) => s.to_string(),
|
2018-04-01 13:48:15 +09:00
|
|
|
(.., render::Local) => "../".repeat(loc.len()),
|
2017-12-08 17:32:04 -08:00
|
|
|
(.., render::Unknown) => return None,
|
|
|
|
})
|
2015-04-06 17:56:35 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
for component in &fqp[..fqp.len() - 1] {
|
|
|
|
url.push_str(component);
|
|
|
|
url.push_str("/");
|
|
|
|
}
|
|
|
|
match shortty {
|
|
|
|
ItemType::Module => {
|
|
|
|
url.push_str(fqp.last().unwrap());
|
|
|
|
url.push_str("/index.html");
|
|
|
|
}
|
|
|
|
_ => {
|
2016-08-03 13:14:59 +12:00
|
|
|
url.push_str(shortty.css_class());
|
2015-04-06 17:56:35 -07:00
|
|
|
url.push_str(".");
|
|
|
|
url.push_str(fqp.last().unwrap());
|
|
|
|
url.push_str(".html");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some((url, shortty, fqp.to_vec()))
|
|
|
|
}
|
|
|
|
|
2013-10-03 10:24:40 -07:00
|
|
|
/// Used when rendering a `ResolvedPath` structure. This invokes the `path`
|
|
|
|
/// rendering function with the necessary arguments for linking to a local path.
|
2015-08-16 06:32:28 -04:00
|
|
|
fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
|
2017-05-31 18:02:35 +01:00
|
|
|
print_all: bool, use_absolute: bool) -> fmt::Result {
|
2017-06-11 18:20:48 +01:00
|
|
|
let last = path.segments.last().unwrap();
|
2013-09-24 13:56:52 -07:00
|
|
|
|
2014-04-28 20:36:08 -07:00
|
|
|
if print_all {
|
2017-12-28 17:49:36 +00:00
|
|
|
for seg in &path.segments[..path.segments.len() - 1] {
|
|
|
|
write!(w, "{}::", seg.name)?;
|
2014-04-28 20:36:08 -07:00
|
|
|
}
|
|
|
|
}
|
2016-09-26 16:02:21 -05:00
|
|
|
if w.alternate() {
|
2018-02-23 17:48:54 +00:00
|
|
|
write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.args)?;
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2017-05-31 18:02:35 +01:00
|
|
|
let path = if use_absolute {
|
|
|
|
match href(did) {
|
|
|
|
Some((_, _, fqp)) => {
|
|
|
|
format!("{}::{}",
|
|
|
|
fqp[..fqp.len() - 1].join("::"),
|
2017-06-11 18:20:48 +01:00
|
|
|
HRef::new(did, fqp.last().unwrap()))
|
2017-03-10 16:21:07 +01:00
|
|
|
}
|
2018-07-27 11:11:18 +02:00
|
|
|
None => HRef::new(did, &last.name).to_string(),
|
2017-05-31 18:02:35 +01:00
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
} else {
|
2018-07-27 11:11:18 +02:00
|
|
|
HRef::new(did, &last.name).to_string()
|
2017-05-31 18:02:35 +01:00
|
|
|
};
|
2018-02-23 17:48:54 +00:00
|
|
|
write!(w, "{}{}", path, last.args)?;
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2014-04-28 20:36:08 -07:00
|
|
|
Ok(())
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
|
2014-05-28 19:53:37 -07:00
|
|
|
fn primitive_link(f: &mut fmt::Formatter,
|
2014-09-11 17:07:49 +12:00
|
|
|
prim: clean::PrimitiveType,
|
2014-05-28 19:53:37 -07:00
|
|
|
name: &str) -> fmt::Result {
|
2014-11-14 14:20:57 -08:00
|
|
|
let m = cache();
|
2014-05-28 19:53:37 -07:00
|
|
|
let mut needs_termination = false;
|
2016-09-26 16:02:21 -05:00
|
|
|
if !f.alternate() {
|
|
|
|
match m.primitive_locations.get(&prim) {
|
2016-11-29 08:15:16 +02:00
|
|
|
Some(&def_id) if def_id.is_local() => {
|
2016-09-26 16:02:21 -05:00
|
|
|
let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len());
|
|
|
|
let len = if len == 0 {0} else {len - 1};
|
2017-02-28 00:27:19 +01:00
|
|
|
write!(f, "<a class=\"primitive\" href=\"{}primitive.{}.html\">",
|
2018-04-01 13:48:15 +09:00
|
|
|
"../".repeat(len),
|
2016-07-03 14:38:37 -07:00
|
|
|
prim.to_url_str())?;
|
|
|
|
needs_termination = true;
|
2014-05-28 19:53:37 -07:00
|
|
|
}
|
2016-11-29 08:15:16 +02:00
|
|
|
Some(&def_id) => {
|
|
|
|
let loc = match m.extern_locations[&def_id.krate] {
|
|
|
|
(ref cname, _, render::Remote(ref s)) => {
|
|
|
|
Some((cname, s.to_string()))
|
|
|
|
}
|
|
|
|
(ref cname, _, render::Local) => {
|
2016-09-26 16:02:21 -05:00
|
|
|
let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len());
|
2018-04-01 13:48:15 +09:00
|
|
|
Some((cname, "../".repeat(len)))
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2016-11-29 08:15:16 +02:00
|
|
|
(.., render::Unknown) => None,
|
2016-09-26 16:02:21 -05:00
|
|
|
};
|
|
|
|
if let Some((cname, root)) = loc {
|
2017-02-28 00:27:19 +01:00
|
|
|
write!(f, "<a class=\"primitive\" href=\"{}{}/primitive.{}.html\">",
|
2016-09-26 16:02:21 -05:00
|
|
|
root,
|
|
|
|
cname,
|
|
|
|
prim.to_url_str())?;
|
|
|
|
needs_termination = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {}
|
2014-05-28 19:53:37 -07:00
|
|
|
}
|
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
write!(f, "{}", name)?;
|
2014-05-28 19:53:37 -07:00
|
|
|
if needs_termination {
|
2016-03-22 22:01:37 -05:00
|
|
|
write!(f, "</a>")?;
|
2014-05-28 19:53:37 -07:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2013-10-03 10:24:40 -07:00
|
|
|
/// Helper to render type parameters
|
2014-05-10 14:05:06 -07:00
|
|
|
fn tybounds(w: &mut fmt::Formatter,
|
2018-06-14 12:08:58 +01:00
|
|
|
typarams: &Option<Vec<clean::GenericBound>>) -> fmt::Result {
|
2013-10-02 15:39:32 -07:00
|
|
|
match *typarams {
|
|
|
|
Some(ref params) => {
|
2015-01-31 12:20:46 -05:00
|
|
|
for param in params {
|
2016-03-22 22:01:37 -05:00
|
|
|
write!(w, " + ")?;
|
2016-09-26 16:02:21 -05:00
|
|
|
fmt::Display::fmt(param, w)?;
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
None => Ok(())
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-25 08:24:50 +02:00
|
|
|
impl<'a> HRef<'a> {
|
|
|
|
pub fn new(did: DefId, text: &'a str) -> HRef<'a> {
|
|
|
|
HRef { did: did, text: text }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> fmt::Display for HRef<'a> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match href(self.did) {
|
2016-09-26 16:02:21 -05:00
|
|
|
Some((url, shortty, fqp)) => if !f.alternate() {
|
2017-02-28 00:27:19 +01:00
|
|
|
write!(f, "<a class=\"{}\" href=\"{}\" title=\"{} {}\">{}</a>",
|
2017-02-09 11:02:01 -07:00
|
|
|
shortty, url, shortty, fqp.join("::"), self.text)
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
|
|
|
write!(f, "{}", self.text)
|
|
|
|
},
|
2016-04-25 08:24:50 +02:00
|
|
|
_ => write!(f, "{}", self.text),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 18:02:35 +01:00
|
|
|
fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt::Result {
|
2016-12-15 23:13:00 -08:00
|
|
|
match *t {
|
|
|
|
clean::Generic(ref name) => {
|
|
|
|
f.write_str(name)
|
|
|
|
}
|
|
|
|
clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => {
|
2018-10-15 00:48:57 +01:00
|
|
|
if typarams.is_some() {
|
|
|
|
f.write_str("dyn ")?;
|
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
// Paths like T::Output and Self::Output should be rendered with all segments
|
2017-05-31 18:02:35 +01:00
|
|
|
resolved_path(f, did, path, is_generic, use_absolute)?;
|
|
|
|
tybounds(f, typarams)
|
2016-12-15 23:13:00 -08:00
|
|
|
}
|
|
|
|
clean::Infer => write!(f, "_"),
|
2017-05-31 18:02:35 +01:00
|
|
|
clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()),
|
2016-12-15 23:13:00 -08:00
|
|
|
clean::BareFunction(ref decl) => {
|
|
|
|
if f.alternate() {
|
2017-11-28 12:05:53 +01:00
|
|
|
write!(f, "{}{:#}fn{:#}{:#}",
|
2016-12-15 23:13:00 -08:00
|
|
|
UnsafetySpace(decl.unsafety),
|
|
|
|
AbiSpace(decl.abi),
|
2017-10-16 21:07:26 +02:00
|
|
|
CommaSep(&decl.generic_params),
|
2016-12-15 23:13:00 -08:00
|
|
|
decl.decl)
|
|
|
|
} else {
|
2017-07-28 12:55:30 -05:00
|
|
|
write!(f, "{}{}", UnsafetySpace(decl.unsafety), AbiSpace(decl.abi))?;
|
|
|
|
primitive_link(f, PrimitiveType::Fn, "fn")?;
|
2017-10-16 21:07:26 +02:00
|
|
|
write!(f, "{}{}", CommaSep(&decl.generic_params), decl.decl)
|
2016-12-15 23:13:00 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
clean::Tuple(ref typs) => {
|
|
|
|
match &typs[..] {
|
2017-10-17 23:03:50 -07:00
|
|
|
&[] => primitive_link(f, PrimitiveType::Unit, "()"),
|
2017-05-31 18:02:35 +01:00
|
|
|
&[ref one] => {
|
2016-12-15 23:13:00 -08:00
|
|
|
primitive_link(f, PrimitiveType::Tuple, "(")?;
|
|
|
|
//carry f.alternate() into this display w/o branching manually
|
|
|
|
fmt::Display::fmt(one, f)?;
|
|
|
|
primitive_link(f, PrimitiveType::Tuple, ",)")
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2017-05-31 18:02:35 +01:00
|
|
|
many => {
|
2016-12-15 23:13:00 -08:00
|
|
|
primitive_link(f, PrimitiveType::Tuple, "(")?;
|
2018-03-23 22:06:28 +09:00
|
|
|
fmt::Display::fmt(&CommaSep(many), f)?;
|
2016-12-15 23:13:00 -08:00
|
|
|
primitive_link(f, PrimitiveType::Tuple, ")")
|
2016-01-22 23:15:47 +05:30
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
}
|
2017-05-31 14:39:30 +01:00
|
|
|
clean::Slice(ref t) => {
|
2017-05-04 14:17:23 +02:00
|
|
|
primitive_link(f, PrimitiveType::Slice, "[")?;
|
2016-12-15 23:13:00 -08:00
|
|
|
fmt::Display::fmt(t, f)?;
|
2017-05-04 14:17:23 +02:00
|
|
|
primitive_link(f, PrimitiveType::Slice, "]")
|
2016-12-15 23:13:00 -08:00
|
|
|
}
|
2017-08-05 12:27:28 +03:00
|
|
|
clean::Array(ref t, ref n) => {
|
2016-12-15 23:13:00 -08:00
|
|
|
primitive_link(f, PrimitiveType::Array, "[")?;
|
|
|
|
fmt::Display::fmt(t, f)?;
|
2017-05-31 14:39:30 +01:00
|
|
|
primitive_link(f, PrimitiveType::Array, &format!("; {}]", n))
|
2016-12-15 23:13:00 -08:00
|
|
|
}
|
2017-11-28 09:38:19 +08:00
|
|
|
clean::Never => primitive_link(f, PrimitiveType::Never, "!"),
|
2016-12-15 23:13:00 -08:00
|
|
|
clean::RawPointer(m, ref t) => {
|
|
|
|
match **t {
|
2017-05-31 18:02:35 +01:00
|
|
|
clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => {
|
2016-12-15 23:13:00 -08:00
|
|
|
if f.alternate() {
|
2016-08-23 18:51:56 -04:00
|
|
|
primitive_link(f, clean::PrimitiveType::RawPointer,
|
2016-12-15 23:13:00 -08:00
|
|
|
&format!("*{}{:#}", RawMutableSpace(m), t))
|
|
|
|
} else {
|
|
|
|
primitive_link(f, clean::PrimitiveType::RawPointer,
|
|
|
|
&format!("*{}{}", RawMutableSpace(m), t))
|
2016-01-23 15:01:17 +05:30
|
|
|
}
|
|
|
|
}
|
2017-05-31 18:02:35 +01:00
|
|
|
_ => {
|
2016-12-15 23:13:00 -08:00
|
|
|
primitive_link(f, clean::PrimitiveType::RawPointer,
|
|
|
|
&format!("*{}", RawMutableSpace(m)))?;
|
|
|
|
fmt::Display::fmt(t, f)
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
}
|
|
|
|
clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
|
|
|
|
let lt = match *l {
|
|
|
|
Some(ref l) => format!("{} ", *l),
|
2018-08-23 10:14:52 +02:00
|
|
|
_ => String::new(),
|
2016-12-15 23:13:00 -08:00
|
|
|
};
|
|
|
|
let m = MutableSpace(mutability);
|
2017-07-30 14:59:08 -05:00
|
|
|
let amp = if f.alternate() {
|
|
|
|
"&".to_string()
|
|
|
|
} else {
|
|
|
|
"&".to_string()
|
|
|
|
};
|
2016-12-15 23:13:00 -08:00
|
|
|
match **ty {
|
2017-05-31 14:39:30 +01:00
|
|
|
clean::Slice(ref bt) => { // BorrowedRef{ ... Slice(T) } is &[T]
|
2016-12-15 23:13:00 -08:00
|
|
|
match **bt {
|
2017-05-31 18:02:35 +01:00
|
|
|
clean::Generic(_) => {
|
2016-12-15 23:13:00 -08:00
|
|
|
if f.alternate() {
|
|
|
|
primitive_link(f, PrimitiveType::Slice,
|
2017-07-30 14:59:08 -05:00
|
|
|
&format!("{}{}{}[{:#}]", amp, lt, m, **bt))
|
2016-12-15 23:13:00 -08:00
|
|
|
} else {
|
|
|
|
primitive_link(f, PrimitiveType::Slice,
|
2017-07-30 14:59:08 -05:00
|
|
|
&format!("{}{}{}[{}]", amp, lt, m, **bt))
|
2017-02-26 18:33:42 +01:00
|
|
|
}
|
|
|
|
}
|
2017-05-31 18:02:35 +01:00
|
|
|
_ => {
|
2017-07-30 14:59:08 -05:00
|
|
|
primitive_link(f, PrimitiveType::Slice,
|
|
|
|
&format!("{}{}{}[", amp, lt, m))?;
|
2016-12-15 23:13:00 -08:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{:#}", **bt)?;
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", **bt)?;
|
2014-09-28 00:15:31 +08:00
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
primitive_link(f, PrimitiveType::Slice, "]")
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2014-09-28 00:15:31 +08:00
|
|
|
}
|
|
|
|
}
|
2017-05-31 18:02:35 +01:00
|
|
|
clean::ResolvedPath { typarams: Some(ref v), .. } if !v.is_empty() => {
|
2017-07-30 14:59:08 -05:00
|
|
|
write!(f, "{}{}{}(", amp, lt, m)?;
|
2017-05-31 18:02:35 +01:00
|
|
|
fmt_type(&ty, f, use_absolute)?;
|
|
|
|
write!(f, ")")
|
|
|
|
}
|
2017-07-30 14:59:08 -05:00
|
|
|
clean::Generic(..) => {
|
|
|
|
primitive_link(f, PrimitiveType::Reference,
|
|
|
|
&format!("{}{}{}", amp, lt, m))?;
|
|
|
|
fmt_type(&ty, f, use_absolute)
|
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
_ => {
|
2017-07-30 14:59:08 -05:00
|
|
|
write!(f, "{}{}{}", amp, lt, m)?;
|
|
|
|
fmt_type(&ty, f, use_absolute)
|
2014-12-16 08:50:52 -08:00
|
|
|
}
|
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
}
|
|
|
|
clean::ImplTrait(ref bounds) => {
|
2019-02-06 11:46:41 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "impl {:#}", GenericBounds(bounds))
|
|
|
|
} else {
|
|
|
|
write!(f, "impl {}", GenericBounds(bounds))
|
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
}
|
|
|
|
clean::QPath { ref name, ref self_type, ref trait_ } => {
|
2017-04-12 18:14:54 +02:00
|
|
|
let should_show_cast = match *trait_ {
|
2017-06-11 18:20:48 +01:00
|
|
|
box clean::ResolvedPath { ref path, .. } => {
|
|
|
|
!path.segments.is_empty() && !self_type.is_self_type()
|
2017-04-12 18:14:54 +02:00
|
|
|
}
|
|
|
|
_ => true,
|
|
|
|
};
|
2016-12-15 23:13:00 -08:00
|
|
|
if f.alternate() {
|
2017-05-31 18:02:35 +01:00
|
|
|
if should_show_cast {
|
|
|
|
write!(f, "<{:#} as {:#}>::", self_type, trait_)?
|
2017-02-28 00:27:19 +01:00
|
|
|
} else {
|
2017-05-31 18:02:35 +01:00
|
|
|
write!(f, "{:#}::", self_type)?
|
2017-02-28 00:27:19 +01:00
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
} else {
|
2017-05-31 18:02:35 +01:00
|
|
|
if should_show_cast {
|
|
|
|
write!(f, "<{} as {}>::", self_type, trait_)?
|
2017-02-26 18:33:42 +01:00
|
|
|
} else {
|
2017-05-31 18:02:35 +01:00
|
|
|
write!(f, "{}::", self_type)?
|
2017-04-12 18:14:54 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
match *trait_ {
|
|
|
|
// It's pretty unsightly to look at `<A as B>::C` in output, and
|
|
|
|
// we've got hyperlinking on our side, so try to avoid longer
|
|
|
|
// notation as much as possible by making `C` a hyperlink to trait
|
|
|
|
// `B` to disambiguate.
|
|
|
|
//
|
|
|
|
// FIXME: this is still a lossy conversion and there should probably
|
|
|
|
// be a better way of representing this in general? Most of
|
|
|
|
// the ugliness comes from inlining across crates where
|
|
|
|
// everything comes in as a fully resolved QPath (hard to
|
|
|
|
// look at).
|
|
|
|
box clean::ResolvedPath { did, ref typarams, .. } => {
|
2017-06-11 18:20:48 +01:00
|
|
|
match href(did) {
|
|
|
|
Some((ref url, _, ref path)) if !f.alternate() => {
|
|
|
|
write!(f,
|
|
|
|
"<a class=\"type\" href=\"{url}#{shortty}.{name}\" \
|
|
|
|
title=\"type {path}::{name}\">{name}</a>",
|
|
|
|
url = url,
|
|
|
|
shortty = ItemType::AssociatedType,
|
|
|
|
name = name,
|
|
|
|
path = path.join("::"))?;
|
|
|
|
}
|
|
|
|
_ => write!(f, "{}", name)?,
|
|
|
|
}
|
2017-04-12 18:14:54 +02:00
|
|
|
|
|
|
|
// FIXME: `typarams` are not rendered, and this seems bad?
|
|
|
|
drop(typarams);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
write!(f, "{}", name)
|
2017-02-26 18:33:42 +01:00
|
|
|
}
|
2014-07-25 09:31:20 -07:00
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2016-12-15 23:13:00 -08:00
|
|
|
clean::Unique(..) => {
|
|
|
|
panic!("should have been cleaned")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for clean::Type {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-05-31 18:02:35 +01:00
|
|
|
fmt_type(self, f, false)
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-22 23:20:22 -08:00
|
|
|
fn fmt_impl(i: &clean::Impl,
|
|
|
|
f: &mut fmt::Formatter,
|
|
|
|
link_trait: bool,
|
|
|
|
use_absolute: bool) -> fmt::Result {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "impl{:#} ", i.generics)?;
|
|
|
|
} else {
|
|
|
|
write!(f, "impl{} ", i.generics)?;
|
|
|
|
}
|
2016-10-15 09:46:43 -05:00
|
|
|
|
2016-03-29 01:11:08 +09:00
|
|
|
if let Some(ref ty) = i.trait_ {
|
2016-10-15 09:46:43 -05:00
|
|
|
if i.polarity == Some(clean::ImplPolarity::Negative) {
|
|
|
|
write!(f, "!")?;
|
|
|
|
}
|
|
|
|
|
2016-03-29 01:11:08 +09:00
|
|
|
if link_trait {
|
2016-09-26 16:02:21 -05:00
|
|
|
fmt::Display::fmt(ty, f)?;
|
2016-03-29 01:11:08 +09:00
|
|
|
} else {
|
2016-05-12 18:23:11 +01:00
|
|
|
match *ty {
|
2016-12-15 23:13:00 -08:00
|
|
|
clean::ResolvedPath { typarams: None, ref path, is_generic: false, .. } => {
|
2016-05-12 18:23:11 +01:00
|
|
|
let last = path.segments.last().unwrap();
|
2016-09-26 16:02:21 -05:00
|
|
|
fmt::Display::fmt(&last.name, f)?;
|
2018-02-23 17:48:54 +00:00
|
|
|
fmt::Display::fmt(&last.args, f)?;
|
2016-05-12 18:23:11 +01:00
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
2016-03-29 01:11:08 +09:00
|
|
|
}
|
|
|
|
write!(f, " for ")?;
|
|
|
|
}
|
2016-10-15 09:46:43 -05:00
|
|
|
|
2018-07-27 22:59:16 +02:00
|
|
|
if let Some(ref ty) = i.blanket_impl {
|
|
|
|
fmt_type(ty, f, use_absolute)?;
|
|
|
|
} else {
|
|
|
|
fmt_type(&i.for_, f, use_absolute)?;
|
|
|
|
}
|
2016-10-15 09:46:43 -05:00
|
|
|
|
2017-04-05 10:02:37 -05:00
|
|
|
fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?;
|
2016-03-29 01:11:08 +09:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-07-18 02:02:57 -04:00
|
|
|
impl fmt::Display for clean::Impl {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-12-15 23:13:00 -08:00
|
|
|
fmt_impl(self, f, true, false)
|
2015-07-18 02:02:57 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-29 01:11:08 +09:00
|
|
|
// The difference from above is that trait is not hyperlinked.
|
2016-12-15 23:13:00 -08:00
|
|
|
pub fn fmt_impl_for_trait_page(i: &clean::Impl,
|
|
|
|
f: &mut fmt::Formatter,
|
2016-12-22 23:20:22 -08:00
|
|
|
use_absolute: bool) -> fmt::Result {
|
|
|
|
fmt_impl(i, f, false, use_absolute)
|
2016-03-29 01:11:08 +09:00
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::Arguments {
|
2014-02-13 06:41:34 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
for (i, input) in self.values.iter().enumerate() {
|
2015-03-24 16:54:09 -07:00
|
|
|
if !input.name.is_empty() {
|
2016-03-22 22:01:37 -05:00
|
|
|
write!(f, "{}: ", input.name)?;
|
2014-02-13 06:41:34 +11:00
|
|
|
}
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{:#}", input.type_)?;
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", input.type_)?;
|
|
|
|
}
|
2016-09-26 18:47:09 -05:00
|
|
|
if i + 1 < self.values.len() { write!(f, ", ")?; }
|
2014-02-13 06:41:34 +11:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::FunctionRetTy {
|
2014-11-09 16:14:15 +01:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
clean::Return(clean::Tuple(ref tys)) if tys.is_empty() => Ok(()),
|
2016-09-26 16:02:21 -05:00
|
|
|
clean::Return(ref ty) if f.alternate() => write!(f, " -> {:#}", ty),
|
2014-11-09 16:14:15 +01:00
|
|
|
clean::Return(ref ty) => write!(f, " -> {}", ty),
|
2015-01-18 22:49:19 +09:00
|
|
|
clean::DefaultReturn => Ok(()),
|
2014-11-09 16:14:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::FnDecl {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-08-20 18:27:53 +01:00
|
|
|
if self.variadic {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "({args:#}, ...){arrow:#}", args = self.inputs, arrow = self.output)
|
|
|
|
} else {
|
|
|
|
write!(f, "({args}, ...){arrow}", args = self.inputs, arrow = self.output)
|
|
|
|
}
|
2015-08-20 18:27:53 +01:00
|
|
|
} else {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "({args:#}){arrow:#}", args = self.inputs, arrow = self.output)
|
|
|
|
} else {
|
|
|
|
write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output)
|
|
|
|
}
|
2015-08-20 18:27:53 +01:00
|
|
|
}
|
2013-11-28 02:23:12 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-05 10:12:43 -05:00
|
|
|
impl<'a> fmt::Display for Function<'a> {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2019-02-06 11:46:41 -05:00
|
|
|
let &Function { decl, header_len, indent, asyncness } = self;
|
2016-09-26 16:02:21 -05:00
|
|
|
let amp = if f.alternate() { "&" } else { "&" };
|
2014-05-22 16:57:53 -07:00
|
|
|
let mut args = String::new();
|
2016-09-26 16:02:21 -05:00
|
|
|
let mut args_plain = String::new();
|
2016-05-08 21:19:29 +03:00
|
|
|
for (i, input) in decl.inputs.values.iter().enumerate() {
|
2017-03-28 16:49:05 -05:00
|
|
|
if i == 0 {
|
|
|
|
args.push_str("<br>");
|
|
|
|
}
|
|
|
|
|
2016-05-08 21:19:29 +03:00
|
|
|
if let Some(selfty) = input.to_self() {
|
|
|
|
match selfty {
|
2016-09-26 16:02:21 -05:00
|
|
|
clean::SelfValue => {
|
|
|
|
args.push_str("self");
|
|
|
|
args_plain.push_str("self");
|
|
|
|
}
|
2016-05-08 21:19:29 +03:00
|
|
|
clean::SelfBorrowed(Some(ref lt), mtbl) => {
|
2016-09-26 18:47:09 -05:00
|
|
|
args.push_str(&format!("{}{} {}self", amp, *lt, MutableSpace(mtbl)));
|
|
|
|
args_plain.push_str(&format!("&{} {}self", *lt, MutableSpace(mtbl)));
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
|
|
|
clean::SelfBorrowed(None, mtbl) => {
|
2016-09-26 18:47:09 -05:00
|
|
|
args.push_str(&format!("{}{}self", amp, MutableSpace(mtbl)));
|
|
|
|
args_plain.push_str(&format!("&{}self", MutableSpace(mtbl)));
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
|
|
|
clean::SelfExplicit(ref typ) => {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
args.push_str(&format!("self: {:#}", *typ));
|
|
|
|
} else {
|
|
|
|
args.push_str(&format!("self: {}", *typ));
|
|
|
|
}
|
|
|
|
args_plain.push_str(&format!("self: {:#}", *typ));
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2016-09-26 16:02:21 -05:00
|
|
|
if i > 0 {
|
2017-03-31 19:02:00 -05:00
|
|
|
args.push_str(" <br>");
|
2016-09-26 18:47:09 -05:00
|
|
|
args_plain.push_str(" ");
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2016-05-08 21:19:29 +03:00
|
|
|
if !input.name.is_empty() {
|
|
|
|
args.push_str(&format!("{}: ", input.name));
|
2016-09-26 16:02:21 -05:00
|
|
|
args_plain.push_str(&format!("{}: ", input.name));
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
2016-09-26 18:47:09 -05:00
|
|
|
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
|
|
|
args.push_str(&format!("{:#}", input.type_));
|
|
|
|
} else {
|
2018-07-27 11:11:18 +02:00
|
|
|
args.push_str(&input.type_.to_string());
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
|
|
|
args_plain.push_str(&format!("{:#}", input.type_));
|
|
|
|
}
|
|
|
|
if i + 1 < decl.inputs.values.len() {
|
2017-03-28 16:49:05 -05:00
|
|
|
args.push(',');
|
|
|
|
args_plain.push(',');
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
2016-09-26 16:02:21 -05:00
|
|
|
|
2019-02-06 11:46:41 -05:00
|
|
|
let mut args_plain = format!("({})", args_plain);
|
|
|
|
|
2016-09-26 18:47:09 -05:00
|
|
|
if decl.variadic {
|
|
|
|
args.push_str(",<br> ...");
|
|
|
|
args_plain.push_str(", ...");
|
|
|
|
}
|
|
|
|
|
2019-02-05 10:12:43 -05:00
|
|
|
let output = if let hir::IsAsync::Async = asyncness {
|
|
|
|
Cow::Owned(decl.sugared_async_return_type())
|
|
|
|
} else {
|
|
|
|
Cow::Borrowed(&decl.output)
|
|
|
|
};
|
|
|
|
|
|
|
|
let arrow_plain = format!("{:#}", &output);
|
2016-09-26 16:02:21 -05:00
|
|
|
let arrow = if f.alternate() {
|
2019-02-05 10:12:43 -05:00
|
|
|
format!("{:#}", &output)
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2019-02-05 10:12:43 -05:00
|
|
|
output.to_string()
|
2016-09-26 16:02:21 -05:00
|
|
|
};
|
|
|
|
|
2019-02-06 11:46:41 -05:00
|
|
|
let declaration_len = header_len + args_plain.len() + arrow_plain.len();
|
|
|
|
let output = if declaration_len > 80 {
|
2018-04-01 13:48:15 +09:00
|
|
|
let full_pad = format!("<br>{}", " ".repeat(indent + 4));
|
|
|
|
let close_pad = format!("<br>{}", " ".repeat(indent));
|
2017-04-04 10:31:57 -05:00
|
|
|
format!("({args}{close}){arrow}",
|
|
|
|
args = args.replace("<br>", &full_pad),
|
|
|
|
close = close_pad,
|
|
|
|
arrow = arrow)
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2017-03-28 16:49:05 -05:00
|
|
|
format!("({args}){arrow}", args = args.replace("<br>", ""), arrow = arrow)
|
|
|
|
};
|
2016-09-26 16:02:21 -05:00
|
|
|
|
2016-10-15 09:46:43 -05:00
|
|
|
if f.alternate() {
|
|
|
|
write!(f, "{}", output.replace("<br>", "\n"))
|
|
|
|
} else {
|
|
|
|
write!(f, "{}", output)
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-25 06:08:11 +00:00
|
|
|
impl<'a> fmt::Display for VisSpace<'a> {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-03-25 06:08:11 +00:00
|
|
|
match *self.get() {
|
2018-05-12 18:25:09 +01:00
|
|
|
Some(clean::Public) => f.write_str("pub "),
|
|
|
|
Some(clean::Inherited) | None => Ok(()),
|
|
|
|
Some(clean::Visibility::Crate) => write!(f, "pub(crate) "),
|
|
|
|
Some(clean::Visibility::Restricted(did, ref path)) => {
|
|
|
|
f.write_str("pub(")?;
|
|
|
|
if path.segments.len() != 1
|
|
|
|
|| (path.segments[0].name != "self" && path.segments[0].name != "super")
|
|
|
|
{
|
|
|
|
f.write_str("in ")?;
|
|
|
|
}
|
|
|
|
resolved_path(f, did, path, true, false)?;
|
|
|
|
f.write_str(") ")
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-23 20:38:17 -07:00
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for UnsafetySpace {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.get() {
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::Unsafety::Unsafe => write!(f, "unsafe "),
|
|
|
|
hir::Unsafety::Normal => Ok(())
|
2013-09-23 20:38:17 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-24 13:56:52 -07:00
|
|
|
|
2015-02-25 22:05:07 +02:00
|
|
|
impl fmt::Display for ConstnessSpace {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.get() {
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::Constness::Const => write!(f, "const "),
|
|
|
|
hir::Constness::NotConst => Ok(())
|
2015-02-25 22:05:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-17 14:47:52 -07:00
|
|
|
impl fmt::Display for AsyncSpace {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.0 {
|
|
|
|
hir::IsAsync::Async => write!(f, "async "),
|
|
|
|
hir::IsAsync::NotAsync => Ok(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-21 11:56:00 -08:00
|
|
|
impl fmt::Display for clean::Import {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
2016-10-01 17:35:53 -04:00
|
|
|
clean::Import::Simple(ref name, ref src) => {
|
2016-03-29 01:11:08 +09:00
|
|
|
if *name == src.path.last_name() {
|
2014-05-10 14:05:06 -07:00
|
|
|
write!(f, "use {};", *src)
|
2013-09-24 13:56:52 -07:00
|
|
|
} else {
|
2014-08-18 08:29:44 -07:00
|
|
|
write!(f, "use {} as {};", *src, *name)
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
}
|
2016-10-01 17:35:53 -04:00
|
|
|
clean::Import::Glob(ref src) => {
|
2017-06-24 18:16:39 +01:00
|
|
|
if src.path.segments.is_empty() {
|
|
|
|
write!(f, "use *;")
|
|
|
|
} else {
|
|
|
|
write!(f, "use {}::*;", *src)
|
|
|
|
}
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::ImportSource {
|
2014-02-05 23:55:13 +11:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.did {
|
2017-05-31 18:02:35 +01:00
|
|
|
Some(did) => resolved_path(f, did, &self.path, true, false),
|
2013-09-24 13:56:52 -07:00
|
|
|
_ => {
|
2014-02-05 23:55:13 +11:00
|
|
|
for (i, seg) in self.path.segments.iter().enumerate() {
|
2014-01-30 11:30:21 -08:00
|
|
|
if i > 0 {
|
2016-03-22 22:01:37 -05:00
|
|
|
write!(f, "::")?
|
2014-01-30 11:30:21 -08:00
|
|
|
}
|
2016-03-22 22:01:37 -05:00
|
|
|
write!(f, "{}", seg.name)?;
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
2014-01-30 11:30:21 -08:00
|
|
|
Ok(())
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for clean::TypeBinding {
|
2015-01-07 16:10:40 -08:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-09-26 16:02:21 -05:00
|
|
|
if f.alternate() {
|
2017-03-20 22:41:19 +01:00
|
|
|
write!(f, "{} = {:#}", self.name, self.ty)
|
2016-09-26 16:02:21 -05:00
|
|
|
} else {
|
2017-03-20 22:41:19 +01:00
|
|
|
write!(f, "{} = {}", self.name, self.ty)
|
2016-09-26 16:02:21 -05:00
|
|
|
}
|
2015-01-07 16:10:40 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for MutableSpace {
|
2014-06-05 17:20:59 -07:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
MutableSpace(clean::Immutable) => Ok(()),
|
|
|
|
MutableSpace(clean::Mutable) => write!(f, "mut "),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-06-26 11:37:39 -07:00
|
|
|
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for RawMutableSpace {
|
2014-07-11 11:35:02 +02:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
RawMutableSpace(clean::Immutable) => write!(f, "const "),
|
|
|
|
RawMutableSpace(clean::Mutable) => write!(f, "mut "),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-07 14:22:55 -07:00
|
|
|
impl fmt::Display for AbiSpace {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-09-26 16:02:21 -05:00
|
|
|
let quot = if f.alternate() { "\"" } else { """ };
|
2015-04-07 14:22:55 -07:00
|
|
|
match self.0 {
|
|
|
|
Abi::Rust => Ok(()),
|
2016-09-26 16:02:21 -05:00
|
|
|
abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()),
|
2015-04-07 14:22:55 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|