|
1 | 1 | //! Functions for building AST representations of higher-level values.
|
2 | 2 | use c2rust_ast_builder::mk;
|
3 | 3 | use rustc::hir;
|
| 4 | +use rustc::hir::def::DefKind; |
4 | 5 | use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
5 | 6 | use rustc::hir::map::definitions::DefPathData;
|
6 | 7 | use rustc::hir::map::Map as HirMap;
|
@@ -210,44 +211,50 @@ fn reflect_def_path_inner<'a, 'gcx, 'tcx>(
|
210 | 211 | }
|
211 | 212 |
|
212 | 213 | // Special logic for certain node kinds
|
213 |
| - match dk.disambiguated_data.data { |
214 |
| - DefPathData::ValueNs(_) | DefPathData::TypeNs(_) => { |
215 |
| - let gen = tcx.generics_of(id); |
216 |
| - let num_params = gen |
217 |
| - .params |
218 |
| - .iter() |
219 |
| - .filter(|x| match x.kind { |
220 |
| - GenericParamDefKind::Lifetime { .. } => false, |
221 |
| - GenericParamDefKind::Type { .. } => true, |
222 |
| - GenericParamDefKind::Const => false, |
223 |
| - }) |
224 |
| - .count(); |
225 |
| - if let Some(substs) = opt_substs { |
226 |
| - if substs.len() > 0 { |
227 |
| - assert!(substs.len() >= num_params); |
228 |
| - let start = substs.len() - num_params; |
229 |
| - let tys = substs[start..] |
230 |
| - .iter() |
231 |
| - .map(|ty| reflect_tcx_ty(tcx, ty)) |
232 |
| - .collect::<Vec<_>>(); |
233 |
| - let abpd = mk().angle_bracketed_args(tys); |
234 |
| - segments.last_mut().unwrap().args = abpd.into(); |
235 |
| - opt_substs = Some(&substs[..start]); |
236 |
| - } |
237 |
| - } |
| 214 | + if let DefPathData::Ctor = dk.disambiguated_data.data { |
| 215 | + // The parent of the struct ctor in `visible_parent_map` is the parent of the |
| 216 | + // struct. But we want to visit the struct first, so we can add its name. |
| 217 | + if let Some(parent_id) = tcx.parent(id) { |
| 218 | + id = parent_id; |
| 219 | + continue; |
| 220 | + } else { |
| 221 | + break; |
238 | 222 | }
|
239 |
| - |
240 |
| - DefPathData::Ctor => { |
241 |
| - // The parent of the struct ctor in `visible_parent_map` is the parent of the |
242 |
| - // struct. But we want to visit the struct first, so we can add its name. |
243 |
| - if let Some(parent_id) = tcx.parent(id) { |
244 |
| - id = parent_id; |
245 |
| - continue; |
246 |
| - } else { |
247 |
| - break; |
| 223 | + } |
| 224 | + match tcx.def_kind(id) { |
| 225 | + // If we query for generics_of non-local defs, we may get a |
| 226 | + // panic if the def cannot be generic. This is a list of |
| 227 | + // DefKinds that can have generic type params. |
| 228 | + Some(DefKind::Struct) | Some(DefKind::Union) | Some(DefKind::Enum) |
| 229 | + | Some(DefKind::Variant) | Some(DefKind::Trait) | Some(DefKind::Existential) |
| 230 | + | Some(DefKind::TyAlias) | Some(DefKind::ForeignTy) | Some(DefKind::TraitAlias) |
| 231 | + | Some(DefKind::AssocTy) | Some(DefKind::AssocExistential) |
| 232 | + | Some(DefKind::TyParam) | Some(DefKind::Fn) | Some(DefKind::Method) |
| 233 | + | Some(DefKind::Ctor(..)) => { |
| 234 | + let gen = tcx.generics_of(id); |
| 235 | + let num_params = gen |
| 236 | + .params |
| 237 | + .iter() |
| 238 | + .filter(|x| match x.kind { |
| 239 | + GenericParamDefKind::Lifetime { .. } => false, |
| 240 | + GenericParamDefKind::Type { .. } => true, |
| 241 | + GenericParamDefKind::Const => false, |
| 242 | + }) |
| 243 | + .count(); |
| 244 | + if let Some(substs) = opt_substs { |
| 245 | + if substs.len() > 0 { |
| 246 | + assert!(substs.len() >= num_params); |
| 247 | + let start = substs.len() - num_params; |
| 248 | + let tys = substs[start..] |
| 249 | + .iter() |
| 250 | + .map(|ty| reflect_tcx_ty(tcx, ty)) |
| 251 | + .collect::<Vec<_>>(); |
| 252 | + let abpd = mk().angle_bracketed_args(tys); |
| 253 | + segments.last_mut().unwrap().args = abpd.into(); |
| 254 | + opt_substs = Some(&substs[..start]); |
| 255 | + } |
| 256 | + } |
248 | 257 | }
|
249 |
| - } |
250 |
| - |
251 | 258 | _ => {}
|
252 | 259 | }
|
253 | 260 |
|
|
0 commit comments