diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-03-27 22:39:41 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-27 22:39:41 +0100 |
| commit | 5b68f9c46a550dec9f8ef8bafb9a815cf564af1d (patch) | |
| tree | f2051f8bf8e2a69a81052efbf168cf21ed2052d5 | |
| parent | 23d3fa266cc107ffceced3c5580eb6327662c605 (diff) | |
| parent | c339b2eb4aaa69499dc79b17575c671d3605723c (diff) | |
| download | rust-5b68f9c46a550dec9f8ef8bafb9a815cf564af1d.tar.gz rust-5b68f9c46a550dec9f8ef8bafb9a815cf564af1d.zip | |
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
| -rw-r--r-- | src/librustc_typeck/collect/type_of.rs | 148 |
1 files changed, 71 insertions, 77 deletions
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 30741ed53b5..23613caa993 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -216,93 +216,87 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { | Node::Expr(&Expr { kind: ExprKind::Path(_), .. }) | Node::TraitRef(..) => { let path = match parent_node { - Node::Ty(&Ty { - kind: TyKind::Path(QPath::Resolved(_, ref path)), .. - }) + Node::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. }) | 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, ..), .. }) => { - if let QPath::Resolved(_, ref path) = **path { - Some(&**path) - } else { - None - } + }) + | Node::TraitRef(&TraitRef { path, .. }) => &*path, + _ => { + tcx.sess.delay_span_bug( + DUMMY_SP, + &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 - // figure out which generic parameter it corresponds to and return - // the relevant type. - - let (arg_index, segment) = path - .segments - .iter() - .filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg))) - .find_map(|(args, seg)| { - args.iter() - .filter(|arg| arg.is_const()) - .enumerate() - .filter(|(_, arg)| arg.id() == hir_id) - .map(|(index, _)| (index, seg)) - .next() - }) - .unwrap_or_else(|| { - bug!("no arg matching AnonConst in path"); - }); - - // Try to use the segment resolution if it is valid, otherwise we - // default to the path resolution. - let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); - let generics = match res { - Res::Def(DefKind::Ctor(..), def_id) => { - 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; + // We've encountered an `AnonConst` in some path, so we need to + // figure out which generic parameter it corresponds to and return + // the relevant type. + + let (arg_index, segment) = path + .segments + .iter() + .filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg))) + .find_map(|(args, seg)| { + args.iter() + .filter(|arg| arg.is_const()) + .enumerate() + .filter(|(_, arg)| arg.id() == hir_id) + .map(|(index, _)| (index, seg)) + .next() + }) + .unwrap_or_else(|| { + bug!("no arg matching AnonConst in path"); + }); + + // Try to use the segment resolution if it is valid, otherwise we + // default to the path resolution. + let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); + let generics = match res { + Res::Def(DefKind::Ctor(..), def_id) => { + 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 } - }; + }) + .nth(arg_index) + .map(|param| tcx.type_of(param.def_id)); - generics - .params - .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 - }) + if let Some(ty) = ty { + ty } 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( DUMMY_SP, - &format!("unexpected const parent path {:?}", parent_node,), + &format!( + "missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}", + parent_node, res + ), ); tcx.types.err } |
