Skip to content

Commit

Permalink
Rustdoc-Json: Add Path type for traits.
Browse files Browse the repository at this point in the history
Closes #100106
  • Loading branch information
aDotInTheVoid committed Aug 10, 2022
1 parent 6d3f1be commit 86bdb3e
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 94 deletions.
58 changes: 29 additions & 29 deletions src/etc/check_missing_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def check_generic_bound(bound):
if "trait_bound" in bound:
for param in bound["trait_bound"]["generic_params"]:
check_generic_param(param)
check_type(bound["trait_bound"]["trait"])
check_path(bound["trait_bound"]["trait"])


def check_decl(decl):
Expand All @@ -66,35 +66,35 @@ def check_decl(decl):
if decl["output"]:
check_type(decl["output"])

def check_path(path):
args = path["args"]
if args:
if "angle_bracketed" in args:
for arg in args["angle_bracketed"]["args"]:
if "type" in arg:
check_type(arg["type"])
elif "const" in arg:
check_type(arg["const"]["type"])
for binding in args["angle_bracketed"]["bindings"]:
if "equality" in binding["binding"]:
term = binding["binding"]["equality"]
if "type" in term: check_type(term["type"])
elif "const" in term: check_type(term["const"])
elif "constraint" in binding["binding"]:
for bound in binding["binding"]["constraint"]:
check_generic_bound(bound)
elif "parenthesized" in args:
for input_ty in args["parenthesized"]["inputs"]:
check_type(input_ty)
if args["parenthesized"]["output"]:
check_type(args["parenthesized"]["output"])
if not valid_id(path["id"]):
print("Type contained an invalid ID:", path["id"])
sys.exit(1)

def check_type(ty):
if ty["kind"] == "resolved_path":
for bound in ty["inner"]["param_names"]:
check_generic_bound(bound)
args = ty["inner"]["args"]
if args:
if "angle_bracketed" in args:
for arg in args["angle_bracketed"]["args"]:
if "type" in arg:
check_type(arg["type"])
elif "const" in arg:
check_type(arg["const"]["type"])
for binding in args["angle_bracketed"]["bindings"]:
if "equality" in binding["binding"]:
term = binding["binding"]["equality"]
if "type" in term: check_type(term["type"])
elif "const" in term: check_type(term["const"])
elif "constraint" in binding["binding"]:
for bound in binding["binding"]["constraint"]:
check_generic_bound(bound)
elif "parenthesized" in args:
for input_ty in args["parenthesized"]["inputs"]:
check_type(input_ty)
if args["parenthesized"]["output"]:
check_type(args["parenthesized"]["output"])
if not valid_id(ty["inner"]["id"]):
print("Type contained an invalid ID:", ty["inner"]["id"])
sys.exit(1)
check_path(ty["inner"])
elif ty["kind"] == "tuple":
for ty in ty["inner"]:
check_type(ty)
Expand All @@ -111,7 +111,7 @@ def check_type(ty):
check_decl(ty["inner"]["decl"])
elif ty["kind"] == "qualified_path":
check_type(ty["inner"]["self_type"])
check_type(ty["inner"]["trait"])
check_path(ty["inner"]["trait"])


work_list = set([crate["root"]])
Expand Down Expand Up @@ -174,7 +174,7 @@ def check_type(ty):
elif item["kind"] == "impl":
check_generics(item["inner"]["generics"])
if item["inner"]["trait"]:
check_type(item["inner"]["trait"])
check_path(item["inner"]["trait"])
if item["inner"]["blanket_impl"]:
check_type(item["inner"]["blanket_impl"])
check_type(item["inner"]["for"])
Expand Down
46 changes: 20 additions & 26 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,8 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
use clean::GenericBound::*;
match bound {
TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => {
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
GenericBound::TraitBound {
trait_,
trait_: trait_.into_tcx(tcx),
generic_params: generic_params.into_tcx(tcx),
modifier: from_trait_bound_modifier(modifier),
}
Expand Down Expand Up @@ -460,12 +458,7 @@ impl FromWithTcx<clean::Type> for Type {
};

match ty {
clean::Type::Path { path } => Type::ResolvedPath {
name: path.whole_name(),
id: from_item_id(path.def_id().into(), tcx),
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
param_names: Vec::new(),
},
clean::Type::Path { path } => Type::ResolvedPath(path.into_tcx(tcx)),
clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait {
lifetime: lt.map(convert_lifetime),
traits: bounds.into_tcx(tcx),
Expand All @@ -487,16 +480,22 @@ impl FromWithTcx<clean::Type> for Type {
mutable: mutability == ast::Mutability::Mut,
type_: Box::new((*type_).into_tcx(tcx)),
},
QPath { assoc, self_type, trait_, .. } => {
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
Type::QualifiedPath {
name: assoc.name.to_string(),
args: Box::new(assoc.args.clone().into_tcx(tcx)),
self_type: Box::new((*self_type).into_tcx(tcx)),
trait_: Box::new(trait_),
}
}
QPath { assoc, self_type, trait_, .. } => Type::QualifiedPath {
name: assoc.name.to_string(),
args: Box::new(assoc.args.clone().into_tcx(tcx)),
self_type: Box::new((*self_type).into_tcx(tcx)),
trait_: trait_.into_tcx(tcx),
},
}
}
}

impl FromWithTcx<clean::Path> for Path {
fn from_tcx(path: clean::Path, tcx: TyCtxt<'_>) -> Path {
Path {
name: path.whole_name(),
id: from_item_id(path.def_id().into(), tcx),
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
}
}
}
Expand Down Expand Up @@ -565,19 +564,14 @@ impl FromWithTcx<clean::PolyTrait> for PolyTrait {
clean::PolyTrait { trait_, generic_params }: clean::PolyTrait,
tcx: TyCtxt<'_>,
) -> Self {
PolyTrait {
trait_: clean::Type::Path { path: trait_ }.into_tcx(tcx),
generic_params: generic_params.into_tcx(tcx),
}
PolyTrait { trait_: trait_.into_tcx(tcx), generic_params: generic_params.into_tcx(tcx) }
}
}

impl FromWithTcx<clean::Impl> for Impl {
fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
let provided_trait_methods = impl_.provided_trait_methods(tcx);
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
let trait_ = trait_.map(|path| clean::Type::Path { path }.into_tcx(tcx));
// FIXME: use something like ImplKind in JSON?
let (synthetic, blanket_impl) = match kind {
clean::ImplKind::Normal | clean::ImplKind::FakeVaradic => (false, None),
Expand All @@ -595,7 +589,7 @@ impl FromWithTcx<clean::Impl> for Impl {
.into_iter()
.map(|x| x.to_string())
.collect(),
trait_,
trait_: trait_.map(|path| path.into_tcx(tcx)),
for_: for_.into_tcx(tcx),
items: ids(items, tcx),
negative: negative_polarity,
Expand Down
31 changes: 20 additions & 11 deletions src/rustdoc-json-types/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};

/// rustdoc format-version.
pub const FORMAT_VERSION: u32 = 17;
pub const FORMAT_VERSION: u32 = 18;

/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
/// about the language items in the local crate, as well as info about external items to allow
Expand Down Expand Up @@ -133,7 +133,7 @@ pub struct DynTrait {
/// A trait and potential HRTBs
pub struct PolyTrait {
#[serde(rename = "trait")]
pub trait_: Type,
pub trait_: Path,
/// Used for Higher-Rank Trait Bounds (HRTBs)
/// ```text
/// dyn for<'a> Fn() -> &'a i32"
Expand Down Expand Up @@ -447,7 +447,7 @@ pub enum WherePredicate {
pub enum GenericBound {
TraitBound {
#[serde(rename = "trait")]
trait_: Type,
trait_: Path,
/// Used for Higher-Rank Trait Bounds (HRTBs)
/// ```text
/// where F: for<'a, 'b> Fn(&'a u8, &'b u8)
Expand Down Expand Up @@ -481,12 +481,7 @@ pub enum Term {
#[serde(tag = "kind", content = "inner")]
pub enum Type {
/// Structs, enums, and traits
ResolvedPath {
name: String,
id: Id,
args: Option<Box<GenericArgs>>,
param_names: Vec<GenericBound>,
},
ResolvedPath(Path),
DynTrait(DynTrait),
/// Parameterized types
Generic(String),
Expand Down Expand Up @@ -527,10 +522,24 @@ pub enum Type {
args: Box<GenericArgs>,
self_type: Box<Type>,
#[serde(rename = "trait")]
trait_: Box<Type>,
trait_: Path,
},
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Path {
pub name: String,
pub id: Id,
/// Generic arguments to the type
/// ```test
/// std::borrow::Cow<'static, str>
/// ^^^^^^^^^^^^^^
/// |
/// this part
/// ```
pub args: Option<Box<GenericArgs>>,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct FunctionPointer {
pub decl: FnDecl,
Expand Down Expand Up @@ -574,7 +583,7 @@ pub struct Impl {
pub generics: Generics,
pub provided_trait_methods: Vec<String>,
#[serde(rename = "trait")]
pub trait_: Option<Type>,
pub trait_: Option<Path>,
#[serde(rename = "for")]
pub for_: Type,
pub items: Vec<Id>,
Expand Down
12 changes: 6 additions & 6 deletions src/test/rustdoc-json/fns/generic_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub trait GenericFoo<'a> {}
// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].name" '"F"'
// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.default" 'null'
// @count - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[*]" 1
// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" '$foo'
// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" '$foo'
// @count - "$.index[*][?(@.name=='generics')].inner.decl.inputs[*]" 1
// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][0]" '"f"'
// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].kind" '"generic"'
Expand All @@ -24,12 +24,12 @@ pub fn generics<F: Foo>(f: F) {}
// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.where_predicates" "[]"
// @count - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[*]" 1
// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].name" '"impl Foo"'
// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $foo
// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $foo
// @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[*]" 1
// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][0]" '"f"'
// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].kind" '"impl_trait"'
// @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[*]" 1
// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $foo
// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $foo
pub fn impl_trait(f: impl Foo) {}

// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.params[*]" 3
Expand All @@ -43,11 +43,11 @@ pub fn impl_trait(f: impl Foo) {}

// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F", "kind": "generic"}'
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[*]" 1
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.id" $foo

// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.type" '{"inner": "G", "kind": "generic"}'
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[*]" 1
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.inner.id" $generic_foo
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.id" $generic_foo
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\"
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
Expand All @@ -57,7 +57,7 @@ pub fn impl_trait(f: impl Foo) {}
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.lifetime" \"\'b\"
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.type" '{"inner": "H", "kind": "generic"}'
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[*]" 1
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.id" $foo
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]"
// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[*]" 1
// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\"
Expand Down
2 changes: 1 addition & 1 deletion src/test/rustdoc-json/fns/generic_returns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub trait Foo {}
// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.inputs" []
// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.kind" '"impl_trait"'
// @count - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[*]" 1
// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.inner.id" $foo
// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.id" $foo
pub fn get_foo() -> impl Foo {
Fooer {}
}
Expand Down
6 changes: 3 additions & 3 deletions src/test/rustdoc-json/fns/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ pub trait Wham {}
// @count - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
pub fn one_generic_param_fn<T: Wham>(w: T) {}

// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $wham_id
// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $wham_id
pub fn one_synthetic_generic_param_fn(w: impl Wham) {}
10 changes: 5 additions & 5 deletions src/test/rustdoc-json/traits/supertrait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ pub trait Loud {}

// @set very_loud_id = - "$.index[*][?(@.name=='VeryLoud')].id"
// @count - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[*]" 1
// @is - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.inner.id" $loud_id
// @is - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.id" $loud_id
pub trait VeryLoud: Loud {}

// @set sounds_good_id = - "$.index[*][?(@.name=='SoundsGood')].id"
pub trait SoundsGood {}

// @count - "$.index[*][?(@.name=='MetalBand')].inner.bounds[*]" 2
// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.inner.id" $very_loud_id
// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.inner.id" $sounds_good_id
// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.id" $very_loud_id
// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.id" $sounds_good_id
pub trait MetalBand: VeryLoud + SoundsGood {}

// @count - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[*]" 2
// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.inner.id" $very_loud_id
// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.inner.id" $sounds_good_id
// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.id" $very_loud_id
// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.id" $sounds_good_id
pub trait DnabLatem: SoundsGood + VeryLoud {}
Loading

0 comments on commit 86bdb3e

Please sign in to comment.