Skip to content

Commit

Permalink
Rollup merge of rust-lang#59004 - GuillaumeGomez:generics-handling, r…
Browse files Browse the repository at this point in the history
…=QuietMisdreavus

[rustdoc] Improve "in parameters" search and search more generally

Fixes rust-lang#58230.

r? @QuietMisdreavus
  • Loading branch information
GuillaumeGomez authored Mar 26, 2019
2 parents fbd34ef + befe9ca commit f131f04
Show file tree
Hide file tree
Showing 6 changed files with 308 additions and 40 deletions.
68 changes: 59 additions & 9 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1134,20 +1134,43 @@ 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()
}

/// Same as [`type_of`] but returns [`Option`] instead of failing.
///
/// If you want to fail anyway, you can set the `fail` parameter to true, but in this case,
/// you'd better just call [`type_of`] directly.
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 @@ -1229,6 +1252,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 @@ -1267,7 +1293,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 @@ -1345,6 +1371,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 @@ -1360,24 +1389,37 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
for param in &generics.params {
if let ty::GenericParamDefKind::Const = param.kind {
if param_index == arg_index {
return tcx.type_of(param.def_id);
return Some(tcx.type_of(param.def_id));
}
param_index += 1;
}
}
// This is no generic parameter associated with the arg. This is
// probably from an extra arg where one is not needed.
return tcx.types.err;
return Some(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 @@ -1388,13 +1430,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
Original file line number Diff line number Diff line change
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
11 changes: 8 additions & 3 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,20 @@ 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, ret_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,
ret_types,
}
}

Expand Down
Loading

0 comments on commit f131f04

Please sign in to comment.