Skip to content

Commit

Permalink
Greatly improve generics handling in rustdoc search
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Mar 21, 2019
1 parent 89573b3 commit 64382f4
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 22 deletions.
60 changes: 53 additions & 7 deletions src/librustc_typeck/collect.rs
Expand Up @@ -1130,20 +1130,39 @@ fn report_assoc_ty_on_inherent_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span:
}

fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
checked_type_of(tcx, def_id, true).unwrap()
}

pub fn checked_type_of<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,
fail: bool,
) -> Option<Ty<'tcx>> {
use rustc::hir::*;

let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
let hir_id = match tcx.hir().as_local_hir_id(def_id) {
Some(hir_id) => hir_id,
None => {
if !fail {
return None;
}
bug!("invalid node");
}
};

let icx = ItemCtxt::new(tcx, def_id);

match tcx.hir().get_by_hir_id(hir_id) {
Some(match tcx.hir().get_by_hir_id(hir_id) {
Node::TraitItem(item) => match item.node {
TraitItemKind::Method(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs)
}
TraitItemKind::Const(ref ty, _) | TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
TraitItemKind::Type(_, None) => {
if !fail {
return None;
}
span_bug!(item.span, "associated type missing default");
}
},
Expand Down Expand Up @@ -1225,6 +1244,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
| ItemKind::GlobalAsm(..)
| ItemKind::ExternCrate(..)
| ItemKind::Use(..) => {
if !fail {
return None;
}
span_bug!(
item.span,
"compute_type_of_item: unexpected item type: {:?}",
Expand Down Expand Up @@ -1264,7 +1286,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
..
}) => {
if gen.is_some() {
return tcx.typeck_tables_of(def_id).node_type(hir_id);
return Some(tcx.typeck_tables_of(def_id).node_type(hir_id));
}

let substs = ty::ClosureSubsts {
Expand Down Expand Up @@ -1342,6 +1364,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
}
// Sanity check to make sure everything is as expected.
if !found_const {
if !fail {
return None;
}
bug!("no arg matching AnonConst in path")
}
match path.def {
Expand All @@ -1367,14 +1392,27 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
return tcx.types.err;
}
Def::Err => tcx.types.err,
x => bug!("unexpected const parent path def {:?}", x),
x => {
if !fail {
return None;
}
bug!("unexpected const parent path def {:?}", x);
}
}
}
x => {
if !fail {
return None;
}
bug!("unexpected const parent path {:?}", x);
}
x => bug!("unexpected const parent path {:?}", x),
}
}

x => {
if !fail {
return None;
}
bug!("unexpected const parent in type_of_def_id(): {:?}", x);
}
}
Expand All @@ -1385,13 +1423,21 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
hir::GenericParamKind::Const { ref ty, .. } => {
icx.to_ty(ty)
}
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
x => {
if !fail {
return None;
}
bug!("unexpected non-type Node::GenericParam: {:?}", x)
},
},

x => {
if !fail {
return None;
}
bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
}
}
})
}

fn find_existential_constraints<'a, 'tcx>(
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_typeck/lib.rs
Expand Up @@ -115,6 +115,8 @@ use util::common::time;

use std::iter;

pub use collect::checked_type_of;

pub struct TypeAndSubsts<'tcx> {
substs: SubstsRef<'tcx>,
ty: Ty<'tcx>,
Expand Down
10 changes: 7 additions & 3 deletions src/librustdoc/clean/inline.rs
Expand Up @@ -212,15 +212,19 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
};

let predicates = cx.tcx.predicates_of(did);
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
let decl = (did, sig).clean(cx);
let all_types = clean::get_all_types(&generics, &decl, cx);
clean::Function {
decl: (did, sig).clean(cx),
generics: (cx.tcx.generics_of(did), &predicates).clean(cx),
decl,
generics,
header: hir::FnHeader {
unsafety: sig.unsafety(),
abi: sig.abi(),
constness,
asyncness: hir::IsAsync::NotAsync,
}
},
all_types,
}
}

Expand Down

0 comments on commit 64382f4

Please sign in to comment.