Rollup merge of #59170 - varkor:const-generics-rustdoc, r=QuietMisdreavus,eddyb
Add const generics to rustdoc Split out from #53645. This work is a collaborative effort with @yodaldevoid. The `FIXME`s are waiting on a refactor to `LazyConst`. I'll address these in a follow up, but I thought it would be better to implement the rest now to avoid bitrot. r? @QuietMisdreavus
This commit is contained in:
commit
4c79967760
@ -591,12 +591,12 @@ impl<'a> State<'a> {
|
|||||||
self.s.word(";")?;
|
self.s.word(";")?;
|
||||||
self.end()?; // end the outer cbox
|
self.end()?; // end the outer cbox
|
||||||
}
|
}
|
||||||
hir::ItemKind::Fn(ref decl, header, ref typarams, body) => {
|
hir::ItemKind::Fn(ref decl, header, ref param_names, body) => {
|
||||||
self.head("")?;
|
self.head("")?;
|
||||||
self.print_fn(decl,
|
self.print_fn(decl,
|
||||||
header,
|
header,
|
||||||
Some(item.ident.name),
|
Some(item.ident.name),
|
||||||
typarams,
|
param_names,
|
||||||
&item.vis,
|
&item.vis,
|
||||||
&[],
|
&[],
|
||||||
Some(body))?;
|
Some(body))?;
|
||||||
|
@ -435,7 +435,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||||||
let new_ty = match &poly_trait.trait_ {
|
let new_ty = match &poly_trait.trait_ {
|
||||||
&Type::ResolvedPath {
|
&Type::ResolvedPath {
|
||||||
ref path,
|
ref path,
|
||||||
ref typarams,
|
ref param_names,
|
||||||
ref did,
|
ref did,
|
||||||
ref is_generic,
|
ref is_generic,
|
||||||
} => {
|
} => {
|
||||||
@ -444,7 +444,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||||||
.expect("segments were empty");
|
.expect("segments were empty");
|
||||||
|
|
||||||
let (old_input, old_output) = match last_segment.args {
|
let (old_input, old_output) = match last_segment.args {
|
||||||
GenericArgs::AngleBracketed { types, .. } => (types, None),
|
GenericArgs::AngleBracketed { args, .. } => {
|
||||||
|
let types = args.iter().filter_map(|arg| match arg {
|
||||||
|
GenericArg::Type(ty) => Some(ty.clone()),
|
||||||
|
_ => None,
|
||||||
|
}).collect();
|
||||||
|
(types, None)
|
||||||
|
}
|
||||||
GenericArgs::Parenthesized { inputs, output, .. } => {
|
GenericArgs::Parenthesized { inputs, output, .. } => {
|
||||||
(inputs, output)
|
(inputs, output)
|
||||||
}
|
}
|
||||||
@ -469,7 +475,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||||||
|
|
||||||
Type::ResolvedPath {
|
Type::ResolvedPath {
|
||||||
path: new_path,
|
path: new_path,
|
||||||
typarams: typarams.clone(),
|
param_names: param_names.clone(),
|
||||||
did: did.clone(),
|
did: did.clone(),
|
||||||
is_generic: *is_generic,
|
is_generic: *is_generic,
|
||||||
}
|
}
|
||||||
@ -669,7 +675,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||||||
match **trait_ {
|
match **trait_ {
|
||||||
Type::ResolvedPath {
|
Type::ResolvedPath {
|
||||||
path: ref trait_path,
|
path: ref trait_path,
|
||||||
ref typarams,
|
ref param_names,
|
||||||
ref did,
|
ref did,
|
||||||
ref is_generic,
|
ref is_generic,
|
||||||
} => {
|
} => {
|
||||||
@ -724,7 +730,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||||||
PolyTrait {
|
PolyTrait {
|
||||||
trait_: Type::ResolvedPath {
|
trait_: Type::ResolvedPath {
|
||||||
path: new_trait_path,
|
path: new_trait_path,
|
||||||
typarams: typarams.clone(),
|
param_names: param_names.clone(),
|
||||||
did: did.clone(),
|
did: did.clone(),
|
||||||
is_generic: *is_generic,
|
is_generic: *is_generic,
|
||||||
},
|
},
|
||||||
|
@ -17,11 +17,11 @@ use rustc::middle::resolve_lifetime as rl;
|
|||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
use rustc::middle::stability;
|
use rustc::middle::stability;
|
||||||
use rustc::mir::interpret::{GlobalId, ConstValue};
|
use rustc::mir::interpret::{GlobalId, ConstValue};
|
||||||
use rustc::hir::{self, GenericArg, HirVec};
|
use rustc::hir::{self, HirVec};
|
||||||
use rustc::hir::def::{self, Def, CtorKind};
|
use rustc::hir::def::{self, Def, CtorKind};
|
||||||
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use rustc::hir::map::DisambiguatedDefPathData;
|
use rustc::hir::map::DisambiguatedDefPathData;
|
||||||
use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef};
|
use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef, UnpackedKind};
|
||||||
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
|
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
|
||||||
use rustc::ty::fold::TypeFolder;
|
use rustc::ty::fold::TypeFolder;
|
||||||
use rustc::ty::layout::VariantIdx;
|
use rustc::ty::layout::VariantIdx;
|
||||||
@ -1057,7 +1057,7 @@ impl GenericBound {
|
|||||||
GenericBound::TraitBound(PolyTrait {
|
GenericBound::TraitBound(PolyTrait {
|
||||||
trait_: ResolvedPath {
|
trait_: ResolvedPath {
|
||||||
path,
|
path,
|
||||||
typarams: None,
|
param_names: None,
|
||||||
did,
|
did,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
},
|
},
|
||||||
@ -1101,24 +1101,37 @@ impl Clean<GenericBound> for hir::GenericBound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn external_generic_args(cx: &DocContext<'_>, trait_did: Option<DefId>, has_self: bool,
|
fn external_generic_args(
|
||||||
bindings: Vec<TypeBinding>, substs: SubstsRef<'_>) -> GenericArgs {
|
cx: &DocContext<'_>,
|
||||||
let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect();
|
trait_did: Option<DefId>,
|
||||||
let types = substs.types().skip(has_self as usize).collect::<Vec<_>>();
|
has_self: bool,
|
||||||
|
bindings: Vec<TypeBinding>,
|
||||||
|
substs: SubstsRef<'_>,
|
||||||
|
) -> GenericArgs {
|
||||||
|
let mut skip_self = has_self;
|
||||||
|
let mut ty_sty = None;
|
||||||
|
let args: Vec<_> = substs.iter().filter_map(|kind| match kind.unpack() {
|
||||||
|
UnpackedKind::Lifetime(lt) => {
|
||||||
|
lt.clean(cx).and_then(|lt| Some(GenericArg::Lifetime(lt)))
|
||||||
|
}
|
||||||
|
UnpackedKind::Type(_) if skip_self => {
|
||||||
|
skip_self = false;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
UnpackedKind::Type(ty) => {
|
||||||
|
ty_sty = Some(&ty.sty);
|
||||||
|
Some(GenericArg::Type(ty.clean(cx)))
|
||||||
|
}
|
||||||
|
UnpackedKind::Const(ct) => Some(GenericArg::Const(ct.clean(cx))),
|
||||||
|
}).collect();
|
||||||
|
|
||||||
match trait_did {
|
match trait_did {
|
||||||
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
|
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
|
||||||
Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => {
|
Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => {
|
||||||
assert_eq!(types.len(), 1);
|
assert!(ty_sty.is_some());
|
||||||
let inputs = match types[0].sty {
|
let inputs = match ty_sty {
|
||||||
ty::Tuple(ref tys) => tys.iter().map(|t| t.clean(cx)).collect(),
|
Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.clean(cx)).collect(),
|
||||||
_ => {
|
_ => return GenericArgs::AngleBracketed { args, bindings },
|
||||||
return GenericArgs::AngleBracketed {
|
|
||||||
lifetimes,
|
|
||||||
types: types.clean(cx),
|
|
||||||
bindings,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let output = None;
|
let output = None;
|
||||||
// FIXME(#20299) return type comes from a projection now
|
// FIXME(#20299) return type comes from a projection now
|
||||||
@ -1126,17 +1139,10 @@ fn external_generic_args(cx: &DocContext<'_>, trait_did: Option<DefId>, has_self
|
|||||||
// ty::Tuple(ref v) if v.is_empty() => None, // -> ()
|
// ty::Tuple(ref v) if v.is_empty() => None, // -> ()
|
||||||
// _ => Some(types[1].clean(cx))
|
// _ => Some(types[1].clean(cx))
|
||||||
// };
|
// };
|
||||||
GenericArgs::Parenthesized {
|
GenericArgs::Parenthesized { inputs, output }
|
||||||
inputs,
|
|
||||||
output,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
GenericArgs::AngleBracketed {
|
GenericArgs::AngleBracketed { args, bindings }
|
||||||
lifetimes,
|
|
||||||
types: types.clean(cx),
|
|
||||||
bindings,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1188,7 +1194,7 @@ impl<'a, 'tcx> Clean<GenericBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>
|
|||||||
PolyTrait {
|
PolyTrait {
|
||||||
trait_: ResolvedPath {
|
trait_: ResolvedPath {
|
||||||
path,
|
path,
|
||||||
typarams: None,
|
param_names: None,
|
||||||
did: trait_ref.def_id,
|
did: trait_ref.def_id,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
},
|
},
|
||||||
@ -1474,14 +1480,14 @@ impl GenericParamDef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<GenericParamDef> for ty::GenericParamDef {
|
impl Clean<GenericParamDef> for ty::GenericParamDef {
|
||||||
fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
|
fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
|
||||||
let (name, kind) = match self.kind {
|
let (name, kind) = match self.kind {
|
||||||
ty::GenericParamDefKind::Lifetime => {
|
ty::GenericParamDefKind::Lifetime => {
|
||||||
(self.name.to_string(), GenericParamDefKind::Lifetime)
|
(self.name.to_string(), GenericParamDefKind::Lifetime)
|
||||||
}
|
}
|
||||||
ty::GenericParamDefKind::Type { has_default, .. } => {
|
ty::GenericParamDefKind::Type { has_default, .. } => {
|
||||||
cx.renderinfo.borrow_mut().external_typarams
|
cx.renderinfo.borrow_mut().external_param_names
|
||||||
.insert(self.def_id, self.name.clean(cx));
|
.insert(self.def_id, self.name.clean(cx));
|
||||||
let default = if has_default {
|
let default = if has_default {
|
||||||
Some(cx.tcx.type_of(self.def_id).clean(cx))
|
Some(cx.tcx.type_of(self.def_id).clean(cx))
|
||||||
@ -1496,7 +1502,10 @@ impl<'tcx> Clean<GenericParamDef> for ty::GenericParamDef {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
ty::GenericParamDefKind::Const { .. } => {
|
ty::GenericParamDefKind::Const { .. } => {
|
||||||
unimplemented!() // FIXME(const_generics)
|
(self.name.clean(cx), GenericParamDefKind::Const {
|
||||||
|
did: self.def_id,
|
||||||
|
ty: cx.tcx.type_of(self.def_id).clean(cx),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1697,9 +1706,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
|||||||
.flat_map(|param| match param.kind {
|
.flat_map(|param| match param.kind {
|
||||||
ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
|
ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
|
||||||
ty::GenericParamDefKind::Type { .. } => None,
|
ty::GenericParamDefKind::Type { .. } => None,
|
||||||
ty::GenericParamDefKind::Const { .. } => {
|
ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)),
|
||||||
unimplemented!() // FIXME(const_generics)
|
|
||||||
}
|
|
||||||
}).chain(simplify::ty_params(stripped_typarams).into_iter())
|
}).chain(simplify::ty_params(stripped_typarams).into_iter())
|
||||||
.collect(),
|
.collect(),
|
||||||
where_predicates: simplify::where_clauses(cx, where_predicates),
|
where_predicates: simplify::where_clauses(cx, where_predicates),
|
||||||
@ -2260,7 +2267,7 @@ pub enum Type {
|
|||||||
/// Structs/enums/traits (most that'd be an `hir::TyKind::Path`).
|
/// Structs/enums/traits (most that'd be an `hir::TyKind::Path`).
|
||||||
ResolvedPath {
|
ResolvedPath {
|
||||||
path: Path,
|
path: Path,
|
||||||
typarams: Option<Vec<GenericBound>>,
|
param_names: Option<Vec<GenericBound>>,
|
||||||
did: DefId,
|
did: DefId,
|
||||||
/// `true` if is a `T::Name` path for associated types.
|
/// `true` if is a `T::Name` path for associated types.
|
||||||
is_generic: bool,
|
is_generic: bool,
|
||||||
@ -2381,12 +2388,15 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generics(&self) -> Option<&[Type]> {
|
pub fn generics(&self) -> Option<Vec<Type>> {
|
||||||
match *self {
|
match *self {
|
||||||
ResolvedPath { ref path, .. } => {
|
ResolvedPath { ref path, .. } => {
|
||||||
path.segments.last().and_then(|seg| {
|
path.segments.last().and_then(|seg| {
|
||||||
if let GenericArgs::AngleBracketed { ref types, .. } = seg.args {
|
if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
|
||||||
Some(&**types)
|
Some(args.iter().filter_map(|arg| match arg {
|
||||||
|
GenericArg::Type(ty) => Some(ty.clone()),
|
||||||
|
_ => None,
|
||||||
|
}).collect())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -2722,7 +2732,7 @@ impl Clean<Type> for hir::Ty {
|
|||||||
}
|
}
|
||||||
TyKind::TraitObject(ref bounds, ref lifetime) => {
|
TyKind::TraitObject(ref bounds, ref lifetime) => {
|
||||||
match bounds[0].clean(cx).trait_ {
|
match bounds[0].clean(cx).trait_ {
|
||||||
ResolvedPath { path, typarams: None, did, is_generic } => {
|
ResolvedPath { path, param_names: None, did, is_generic } => {
|
||||||
let mut bounds: Vec<self::GenericBound> = bounds[1..].iter().map(|bound| {
|
let mut bounds: Vec<self::GenericBound> = bounds[1..].iter().map(|bound| {
|
||||||
self::GenericBound::TraitBound(bound.clean(cx),
|
self::GenericBound::TraitBound(bound.clean(cx),
|
||||||
hir::TraitBoundModifier::None)
|
hir::TraitBoundModifier::None)
|
||||||
@ -2730,7 +2740,7 @@ impl Clean<Type> for hir::Ty {
|
|||||||
if !lifetime.is_elided() {
|
if !lifetime.is_elided() {
|
||||||
bounds.push(self::GenericBound::Outlives(lifetime.clean(cx)));
|
bounds.push(self::GenericBound::Outlives(lifetime.clean(cx)));
|
||||||
}
|
}
|
||||||
ResolvedPath { path, typarams: Some(bounds), did, is_generic, }
|
ResolvedPath { path, param_names: Some(bounds), did, is_generic, }
|
||||||
}
|
}
|
||||||
_ => Infer // shouldn't happen
|
_ => Infer // shouldn't happen
|
||||||
}
|
}
|
||||||
@ -2797,7 +2807,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||||||
None, false, vec![], substs);
|
None, false, vec![], substs);
|
||||||
ResolvedPath {
|
ResolvedPath {
|
||||||
path,
|
path,
|
||||||
typarams: None,
|
param_names: None,
|
||||||
did,
|
did,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
}
|
}
|
||||||
@ -2808,7 +2818,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||||||
None, false, vec![], InternalSubsts::empty());
|
None, false, vec![], InternalSubsts::empty());
|
||||||
ResolvedPath {
|
ResolvedPath {
|
||||||
path: path,
|
path: path,
|
||||||
typarams: None,
|
param_names: None,
|
||||||
did: did,
|
did: did,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
}
|
}
|
||||||
@ -2829,8 +2839,8 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||||||
|
|
||||||
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
||||||
|
|
||||||
let mut typarams = vec![];
|
let mut param_names = vec![];
|
||||||
reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
|
reg.clean(cx).map(|b| param_names.push(GenericBound::Outlives(b)));
|
||||||
for did in dids {
|
for did in dids {
|
||||||
let empty = cx.tcx.intern_substs(&[]);
|
let empty = cx.tcx.intern_substs(&[]);
|
||||||
let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
|
let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
|
||||||
@ -2839,13 +2849,13 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||||||
let bound = GenericBound::TraitBound(PolyTrait {
|
let bound = GenericBound::TraitBound(PolyTrait {
|
||||||
trait_: ResolvedPath {
|
trait_: ResolvedPath {
|
||||||
path,
|
path,
|
||||||
typarams: None,
|
param_names: None,
|
||||||
did,
|
did,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
},
|
},
|
||||||
generic_params: Vec::new(),
|
generic_params: Vec::new(),
|
||||||
}, hir::TraitBoundModifier::None);
|
}, hir::TraitBoundModifier::None);
|
||||||
typarams.push(bound);
|
param_names.push(bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut bindings = vec![];
|
let mut bindings = vec![];
|
||||||
@ -2860,7 +2870,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||||||
false, bindings, substs);
|
false, bindings, substs);
|
||||||
ResolvedPath {
|
ResolvedPath {
|
||||||
path,
|
path,
|
||||||
typarams: Some(typarams),
|
param_names: Some(param_names),
|
||||||
did,
|
did,
|
||||||
is_generic: false,
|
is_generic: false,
|
||||||
}
|
}
|
||||||
@ -2937,6 +2947,15 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
|
||||||
|
fn clean(&self, cx: &DocContext<'_>) -> Constant {
|
||||||
|
Constant {
|
||||||
|
type_: self.ty.clean(cx),
|
||||||
|
expr: format!("{:?}", self.val), // FIXME(const_generics)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Clean<Item> for hir::StructField {
|
impl Clean<Item> for hir::StructField {
|
||||||
fn clean(&self, cx: &DocContext<'_>) -> Item {
|
fn clean(&self, cx: &DocContext<'_>) -> Item {
|
||||||
let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
|
let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
|
||||||
@ -3244,11 +3263,27 @@ impl Clean<Path> for hir::Path {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||||
|
pub enum GenericArg {
|
||||||
|
Lifetime(Lifetime),
|
||||||
|
Type(Type),
|
||||||
|
Const(Constant),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for GenericArg {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
GenericArg::Lifetime(lt) => lt.fmt(f),
|
||||||
|
GenericArg::Type(ty) => ty.fmt(f),
|
||||||
|
GenericArg::Const(ct) => ct.fmt(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||||
pub enum GenericArgs {
|
pub enum GenericArgs {
|
||||||
AngleBracketed {
|
AngleBracketed {
|
||||||
lifetimes: Vec<Lifetime>,
|
args: Vec<GenericArg>,
|
||||||
types: Vec<Type>,
|
|
||||||
bindings: Vec<TypeBinding>,
|
bindings: Vec<TypeBinding>,
|
||||||
},
|
},
|
||||||
Parenthesized {
|
Parenthesized {
|
||||||
@ -3266,27 +3301,19 @@ impl Clean<GenericArgs> for hir::GenericArgs {
|
|||||||
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
|
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let (mut lifetimes, mut types) = (vec![], vec![]);
|
let elide_lifetimes = self.args.iter().all(|arg| match arg {
|
||||||
let mut elided_lifetimes = true;
|
hir::GenericArg::Lifetime(lt) => lt.is_elided(),
|
||||||
for arg in &self.args {
|
_ => true,
|
||||||
match arg {
|
});
|
||||||
GenericArg::Lifetime(lt) => {
|
|
||||||
if !lt.is_elided() {
|
|
||||||
elided_lifetimes = false;
|
|
||||||
}
|
|
||||||
lifetimes.push(lt.clean(cx));
|
|
||||||
}
|
|
||||||
GenericArg::Type(ty) => {
|
|
||||||
types.push(ty.clean(cx));
|
|
||||||
}
|
|
||||||
GenericArg::Const(..) => {
|
|
||||||
unimplemented!() // FIXME(const_generics)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GenericArgs::AngleBracketed {
|
GenericArgs::AngleBracketed {
|
||||||
lifetimes: if elided_lifetimes { vec![] } else { lifetimes },
|
args: self.args.iter().filter_map(|arg| match arg {
|
||||||
types,
|
hir::GenericArg::Lifetime(lt) if !elide_lifetimes => {
|
||||||
|
Some(GenericArg::Lifetime(lt.clean(cx)))
|
||||||
|
}
|
||||||
|
hir::GenericArg::Lifetime(_) => None,
|
||||||
|
hir::GenericArg::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
|
||||||
|
hir::GenericArg::Const(ct) => Some(GenericArg::Const(ct.clean(cx))),
|
||||||
|
}).collect(),
|
||||||
bindings: self.bindings.clean(cx),
|
bindings: self.bindings.clean(cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3310,8 +3337,8 @@ impl Clean<PathSegment> for hir::PathSegment {
|
|||||||
|
|
||||||
fn strip_type(ty: Type) -> Type {
|
fn strip_type(ty: Type) -> Type {
|
||||||
match ty {
|
match ty {
|
||||||
Type::ResolvedPath { path, typarams, did, is_generic } => {
|
Type::ResolvedPath { path, param_names, did, is_generic } => {
|
||||||
Type::ResolvedPath { path: strip_path(&path), typarams, did, is_generic }
|
Type::ResolvedPath { path: strip_path(&path), param_names, did, is_generic }
|
||||||
}
|
}
|
||||||
Type::Tuple(inner_tys) => {
|
Type::Tuple(inner_tys) => {
|
||||||
Type::Tuple(inner_tys.iter().map(|t| strip_type(t.clone())).collect())
|
Type::Tuple(inner_tys.iter().map(|t| strip_type(t.clone())).collect())
|
||||||
@ -3338,9 +3365,8 @@ fn strip_path(path: &Path) -> Path {
|
|||||||
PathSegment {
|
PathSegment {
|
||||||
name: s.name.clone(),
|
name: s.name.clone(),
|
||||||
args: GenericArgs::AngleBracketed {
|
args: GenericArgs::AngleBracketed {
|
||||||
lifetimes: Vec::new(),
|
args: vec![],
|
||||||
types: Vec::new(),
|
bindings: vec![],
|
||||||
bindings: Vec::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
@ -3491,7 +3517,7 @@ impl Clean<Item> for doctree::Static {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct Constant {
|
pub struct Constant {
|
||||||
pub type_: Type,
|
pub type_: Type,
|
||||||
pub expr: String,
|
pub expr: String,
|
||||||
@ -3971,7 +3997,7 @@ fn resolve_type(cx: &DocContext<'_>,
|
|||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
let did = register_def(&*cx, path.def);
|
let did = register_def(&*cx, path.def);
|
||||||
ResolvedPath { path: path, typarams: None, did: did, is_generic: is_generic }
|
ResolvedPath { path: path, param_names: None, did: did, is_generic: is_generic }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
|
pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
|
||||||
@ -4397,9 +4423,9 @@ impl From<GenericBound> for SimpleBound {
|
|||||||
match bound.clone() {
|
match bound.clone() {
|
||||||
GenericBound::Outlives(l) => SimpleBound::Outlives(l),
|
GenericBound::Outlives(l) => SimpleBound::Outlives(l),
|
||||||
GenericBound::TraitBound(t, mod_) => match t.trait_ {
|
GenericBound::TraitBound(t, mod_) => match t.trait_ {
|
||||||
Type::ResolvedPath { path, typarams, .. } => {
|
Type::ResolvedPath { path, param_names, .. } => {
|
||||||
SimpleBound::TraitBound(path.segments,
|
SimpleBound::TraitBound(path.segments,
|
||||||
typarams
|
param_names
|
||||||
.map_or_else(|| Vec::new(), |v| v.iter()
|
.map_or_else(|| Vec::new(), |v| v.iter()
|
||||||
.map(|p| SimpleBound::from(p.clone()))
|
.map(|p| SimpleBound::from(p.clone()))
|
||||||
.collect()),
|
.collect()),
|
||||||
|
@ -236,8 +236,16 @@ impl<'tcx> DocContext<'tcx> {
|
|||||||
ty::GenericParamDefKind::Type { .. } => {
|
ty::GenericParamDefKind::Type { .. } => {
|
||||||
args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
|
args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
|
||||||
}
|
}
|
||||||
ty::GenericParamDefKind::Const { .. } => {
|
ty::GenericParamDefKind::Const => {
|
||||||
unimplemented!() // FIXME(const_generics)
|
args.push(hir::GenericArg::Const(hir::ConstArg {
|
||||||
|
value: hir::AnonConst {
|
||||||
|
hir_id: hir::DUMMY_HIR_ID,
|
||||||
|
body: hir::BodyId {
|
||||||
|
hir_id: hir::DUMMY_HIR_ID,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
span: DUMMY_SP,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,14 @@ impl fmt::Display for clean::Lifetime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for clean::Constant {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::Display::fmt(&self.expr, f)?;
|
||||||
|
f.write_str(": ")?;
|
||||||
|
fmt::Display::fmt(&self.type_, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for clean::PolyTrait {
|
impl fmt::Display for clean::PolyTrait {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
if !self.generic_params.is_empty() {
|
if !self.generic_params.is_empty() {
|
||||||
@ -301,32 +309,23 @@ impl fmt::Display for clean::GenericBound {
|
|||||||
impl fmt::Display for clean::GenericArgs {
|
impl fmt::Display for clean::GenericArgs {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
clean::GenericArgs::AngleBracketed {
|
clean::GenericArgs::AngleBracketed { ref args, ref bindings } => {
|
||||||
ref lifetimes, ref types, ref bindings
|
if !args.is_empty() || !bindings.is_empty() {
|
||||||
} => {
|
|
||||||
if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
|
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
f.write_str("<")?;
|
f.write_str("<")?;
|
||||||
} else {
|
} else {
|
||||||
f.write_str("<")?;
|
f.write_str("<")?;
|
||||||
}
|
}
|
||||||
let mut comma = false;
|
let mut comma = false;
|
||||||
for lifetime in lifetimes {
|
for arg in args {
|
||||||
if comma {
|
|
||||||
f.write_str(", ")?;
|
|
||||||
}
|
|
||||||
comma = true;
|
|
||||||
write!(f, "{}", *lifetime)?;
|
|
||||||
}
|
|
||||||
for ty in types {
|
|
||||||
if comma {
|
if comma {
|
||||||
f.write_str(", ")?;
|
f.write_str(", ")?;
|
||||||
}
|
}
|
||||||
comma = true;
|
comma = true;
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "{:#}", *ty)?;
|
write!(f, "{:#}", *arg)?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}", *ty)?;
|
write!(f, "{}", *arg)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for binding in bindings {
|
for binding in bindings {
|
||||||
@ -522,8 +521,8 @@ fn primitive_link(f: &mut fmt::Formatter<'_>,
|
|||||||
|
|
||||||
/// Helper to render type parameters
|
/// Helper to render type parameters
|
||||||
fn tybounds(w: &mut fmt::Formatter<'_>,
|
fn tybounds(w: &mut fmt::Formatter<'_>,
|
||||||
typarams: &Option<Vec<clean::GenericBound>>) -> fmt::Result {
|
param_names: &Option<Vec<clean::GenericBound>>) -> fmt::Result {
|
||||||
match *typarams {
|
match *param_names {
|
||||||
Some(ref params) => {
|
Some(ref params) => {
|
||||||
for param in params {
|
for param in params {
|
||||||
write!(w, " + ")?;
|
write!(w, " + ")?;
|
||||||
@ -560,13 +559,13 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||||||
clean::Generic(ref name) => {
|
clean::Generic(ref name) => {
|
||||||
f.write_str(name)
|
f.write_str(name)
|
||||||
}
|
}
|
||||||
clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => {
|
clean::ResolvedPath{ did, ref param_names, ref path, is_generic } => {
|
||||||
if typarams.is_some() {
|
if param_names.is_some() {
|
||||||
f.write_str("dyn ")?;
|
f.write_str("dyn ")?;
|
||||||
}
|
}
|
||||||
// Paths like T::Output and Self::Output should be rendered with all segments
|
// Paths like T::Output and Self::Output should be rendered with all segments
|
||||||
resolved_path(f, did, path, is_generic, use_absolute)?;
|
resolved_path(f, did, path, is_generic, use_absolute)?;
|
||||||
tybounds(f, typarams)
|
tybounds(f, param_names)
|
||||||
}
|
}
|
||||||
clean::Infer => write!(f, "_"),
|
clean::Infer => write!(f, "_"),
|
||||||
clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()),
|
clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()),
|
||||||
@ -664,7 +663,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clean::ResolvedPath { typarams: Some(ref v), .. } if !v.is_empty() => {
|
clean::ResolvedPath { param_names: Some(ref v), .. } if !v.is_empty() => {
|
||||||
write!(f, "{}{}{}(", amp, lt, m)?;
|
write!(f, "{}{}{}(", amp, lt, m)?;
|
||||||
fmt_type(&ty, f, use_absolute)?;
|
fmt_type(&ty, f, use_absolute)?;
|
||||||
write!(f, ")")
|
write!(f, ")")
|
||||||
@ -718,7 +717,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||||||
// the ugliness comes from inlining across crates where
|
// the ugliness comes from inlining across crates where
|
||||||
// everything comes in as a fully resolved QPath (hard to
|
// everything comes in as a fully resolved QPath (hard to
|
||||||
// look at).
|
// look at).
|
||||||
box clean::ResolvedPath { did, ref typarams, .. } => {
|
box clean::ResolvedPath { did, ref param_names, .. } => {
|
||||||
match href(did) {
|
match href(did) {
|
||||||
Some((ref url, _, ref path)) if !f.alternate() => {
|
Some((ref url, _, ref path)) if !f.alternate() => {
|
||||||
write!(f,
|
write!(f,
|
||||||
@ -732,8 +731,8 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||||||
_ => write!(f, "{}", name)?,
|
_ => write!(f, "{}", name)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: `typarams` are not rendered, and this seems bad?
|
// FIXME: `param_names` are not rendered, and this seems bad?
|
||||||
drop(typarams);
|
drop(param_names);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -772,7 +771,7 @@ fn fmt_impl(i: &clean::Impl,
|
|||||||
fmt::Display::fmt(ty, f)?;
|
fmt::Display::fmt(ty, f)?;
|
||||||
} else {
|
} else {
|
||||||
match *ty {
|
match *ty {
|
||||||
clean::ResolvedPath { typarams: None, ref path, is_generic: false, .. } => {
|
clean::ResolvedPath { param_names: None, ref path, is_generic: false, .. } => {
|
||||||
let last = path.segments.last().unwrap();
|
let last = path.segments.last().unwrap();
|
||||||
fmt::Display::fmt(&last.name, f)?;
|
fmt::Display::fmt(&last.name, f)?;
|
||||||
fmt::Display::fmt(&last.args, f)?;
|
fmt::Display::fmt(&last.args, f)?;
|
||||||
|
@ -271,7 +271,7 @@ pub struct Cache {
|
|||||||
/// Mapping of typaram ids to the name of the type parameter. This is used
|
/// Mapping of typaram ids to the name of the type parameter. This is used
|
||||||
/// when pretty-printing a type (so pretty-printing doesn't have to
|
/// when pretty-printing a type (so pretty-printing doesn't have to
|
||||||
/// painfully maintain a context like this)
|
/// painfully maintain a context like this)
|
||||||
pub typarams: FxHashMap<DefId, String>,
|
pub param_names: FxHashMap<DefId, String>,
|
||||||
|
|
||||||
/// Maps a type ID to all known implementations for that type. This is only
|
/// Maps a type ID to all known implementations for that type. This is only
|
||||||
/// recognized for intra-crate `ResolvedPath` types, and is used to print
|
/// recognized for intra-crate `ResolvedPath` types, and is used to print
|
||||||
@ -368,7 +368,7 @@ pub struct Cache {
|
|||||||
pub struct RenderInfo {
|
pub struct RenderInfo {
|
||||||
pub inlined: FxHashSet<DefId>,
|
pub inlined: FxHashSet<DefId>,
|
||||||
pub external_paths: crate::core::ExternalPaths,
|
pub external_paths: crate::core::ExternalPaths,
|
||||||
pub external_typarams: FxHashMap<DefId, String>,
|
pub external_param_names: FxHashMap<DefId, String>,
|
||||||
pub exact_paths: FxHashMap<DefId, Vec<String>>,
|
pub exact_paths: FxHashMap<DefId, Vec<String>>,
|
||||||
pub access_levels: AccessLevels<DefId>,
|
pub access_levels: AccessLevels<DefId>,
|
||||||
pub deref_trait_did: Option<DefId>,
|
pub deref_trait_did: Option<DefId>,
|
||||||
@ -601,7 +601,7 @@ pub fn run(mut krate: clean::Crate,
|
|||||||
let RenderInfo {
|
let RenderInfo {
|
||||||
inlined: _,
|
inlined: _,
|
||||||
external_paths,
|
external_paths,
|
||||||
external_typarams,
|
external_param_names,
|
||||||
exact_paths,
|
exact_paths,
|
||||||
access_levels,
|
access_levels,
|
||||||
deref_trait_did,
|
deref_trait_did,
|
||||||
@ -635,7 +635,7 @@ pub fn run(mut krate: clean::Crate,
|
|||||||
deref_mut_trait_did,
|
deref_mut_trait_did,
|
||||||
owned_box_did,
|
owned_box_did,
|
||||||
masked_crates: mem::replace(&mut krate.masked_crates, Default::default()),
|
masked_crates: mem::replace(&mut krate.masked_crates, Default::default()),
|
||||||
typarams: external_typarams,
|
param_names: external_param_names,
|
||||||
aliases: Default::default(),
|
aliases: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1751,7 +1751,7 @@ impl<'a> Cache {
|
|||||||
clean::GenericParamDefKind::Lifetime => {}
|
clean::GenericParamDefKind::Lifetime => {}
|
||||||
clean::GenericParamDefKind::Type { did, .. } |
|
clean::GenericParamDefKind::Type { did, .. } |
|
||||||
clean::GenericParamDefKind::Const { did, .. } => {
|
clean::GenericParamDefKind::Const { did, .. } => {
|
||||||
self.typarams.insert(did, param.name.clone());
|
self.param_names.insert(did, param.name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1263,13 +1263,13 @@ impl<'a> State<'a> {
|
|||||||
self.s.word(";")?;
|
self.s.word(";")?;
|
||||||
self.end()?; // end the outer cbox
|
self.end()?; // end the outer cbox
|
||||||
}
|
}
|
||||||
ast::ItemKind::Fn(ref decl, header, ref typarams, ref body) => {
|
ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => {
|
||||||
self.head("")?;
|
self.head("")?;
|
||||||
self.print_fn(
|
self.print_fn(
|
||||||
decl,
|
decl,
|
||||||
header,
|
header,
|
||||||
Some(item.ident),
|
Some(item.ident),
|
||||||
typarams,
|
param_names,
|
||||||
&item.vis
|
&item.vis
|
||||||
)?;
|
)?;
|
||||||
self.s.word(" ")?;
|
self.s.word(" ")?;
|
||||||
|
Loading…
Reference in New Issue
Block a user