1
Fork 0

Rollup merge of #70478 - lcnr:refactor-type_of, r=varkor

Refactor type_of for constants

If I have to look at this function for a few hours I want it to at least look good.

r? @varkor
This commit is contained in:
Mazdak Farrokhzad 2020-03-27 22:39:41 +01:00 committed by GitHub
commit 5b68f9c46a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -216,93 +216,87 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
| Node::Expr(&Expr { kind: ExprKind::Path(_), .. }) | Node::Expr(&Expr { kind: ExprKind::Path(_), .. })
| Node::TraitRef(..) => { | Node::TraitRef(..) => {
let path = match parent_node { let path = match parent_node {
Node::Ty(&Ty { Node::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. })
kind: TyKind::Path(QPath::Resolved(_, ref path)), ..
})
| Node::Expr(&Expr { | Node::Expr(&Expr {
kind: ExprKind::Path(QPath::Resolved(_, ref path)), kind:
ExprKind::Path(QPath::Resolved(_, path))
| ExprKind::Struct(&QPath::Resolved(_, path), ..),
.. ..
}) => Some(&**path), })
Node::Expr(&Expr { kind: ExprKind::Struct(ref path, ..), .. }) => { | Node::TraitRef(&TraitRef { path, .. }) => &*path,
if let QPath::Resolved(_, ref path) = **path { _ => {
Some(&**path) tcx.sess.delay_span_bug(
} else { DUMMY_SP,
None &format!("unexpected const parent path {:?}", parent_node),
} );
return tcx.types.err;
} }
Node::TraitRef(&TraitRef { ref path, .. }) => Some(&**path),
_ => None,
}; };
if let Some(path) = path { // We've encountered an `AnonConst` in some path, so we need to
// We've encountered an `AnonConst` in some path, so we need to // figure out which generic parameter it corresponds to and return
// figure out which generic parameter it corresponds to and return // the relevant type.
// the relevant type.
let (arg_index, segment) = path let (arg_index, segment) = path
.segments .segments
.iter() .iter()
.filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg))) .filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg)))
.find_map(|(args, seg)| { .find_map(|(args, seg)| {
args.iter() args.iter()
.filter(|arg| arg.is_const()) .filter(|arg| arg.is_const())
.enumerate() .enumerate()
.filter(|(_, arg)| arg.id() == hir_id) .filter(|(_, arg)| arg.id() == hir_id)
.map(|(index, _)| (index, seg)) .map(|(index, _)| (index, seg))
.next() .next()
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
bug!("no arg matching AnonConst in path"); bug!("no arg matching AnonConst in path");
}); });
// Try to use the segment resolution if it is valid, otherwise we // Try to use the segment resolution if it is valid, otherwise we
// default to the path resolution. // default to the path resolution.
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
let generics = match res { let generics = match res {
Res::Def(DefKind::Ctor(..), def_id) => { Res::Def(DefKind::Ctor(..), def_id) => {
tcx.generics_of(tcx.parent(def_id).unwrap()) tcx.generics_of(tcx.parent(def_id).unwrap())
}
Res::Def(_, def_id) => tcx.generics_of(def_id),
res => {
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!(
"unexpected anon const res {:?} in path: {:?}",
res, path,
),
);
return tcx.types.err;
}
};
let ty = generics
.params
.iter()
.filter(|param| {
if let ty::GenericParamDefKind::Const = param.kind {
true
} else {
false
} }
Res::Def(_, def_id) => tcx.generics_of(def_id), })
res => { .nth(arg_index)
tcx.sess.delay_span_bug( .map(|param| tcx.type_of(param.def_id));
DUMMY_SP,
&format!(
"unexpected anon const res {:?} in path: {:?}",
res, path,
),
);
return tcx.types.err;
}
};
generics if let Some(ty) = ty {
.params ty
.iter()
.filter(|param| {
if let ty::GenericParamDefKind::Const = param.kind {
true
} else {
false
}
})
.nth(arg_index)
.map(|param| tcx.type_of(param.def_id))
// This is no generic parameter associated with the arg. This is
// probably from an extra arg where one is not needed.
.unwrap_or_else(|| {
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!(
"missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}",
parent_node, res
),
);
tcx.types.err
})
} else { } else {
// This is no generic parameter associated with the arg. This is
// probably from an extra arg where one is not needed.
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
DUMMY_SP, DUMMY_SP,
&format!("unexpected const parent path {:?}", parent_node,), &format!(
"missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}",
parent_node, res
),
); );
tcx.types.err tcx.types.err
} }