|
13 | 13 | //! is parameterized by an instance of `AstConv`.
|
14 | 14 |
|
15 | 15 | use rustc_data_structures::accumulate_vec::AccumulateVec;
|
| 16 | +use rustc_data_structures::array_vec::ArrayVec; |
16 | 17 | use hir::{self, GenericArg};
|
17 | 18 | use hir::def::Def;
|
18 | 19 | use hir::def_id::DefId;
|
19 | 20 | use middle::resolve_lifetime as rl;
|
20 | 21 | use namespace::Namespace;
|
21 |
| -use rustc::ty::subst::{Subst, Substs}; |
| 22 | +use rustc::ty::subst::{Kind, Subst, Substs}; |
22 | 23 | use rustc::traits;
|
23 | 24 | use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
|
24 | 25 | use rustc::ty::GenericParamDefKind;
|
@@ -270,85 +271,133 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
270 | 271 | false
|
271 | 272 | };
|
272 | 273 |
|
273 |
| - let self_offset = self_ty.is_some() as usize; |
274 |
| - let substs = Substs::for_item(tcx, def_id, |param, substs| { |
275 |
| - if param.index == 0 { |
276 |
| - if let Some(ty) = self_ty { |
277 |
| - if let GenericParamDefKind::Type { .. } = param.kind { |
278 |
| - // Handle `Self` first. |
279 |
| - return ty.into(); |
| 274 | + // Collect the segments of the path: we need to substitute arguments |
| 275 | + // for parameters throughout the entire path (wherever there are |
| 276 | + // generic parameters). |
| 277 | + let mut parent_defs = self.tcx().generics_of(def_id); |
| 278 | + let count = parent_defs.count(); |
| 279 | + let mut stack = vec![(def_id, parent_defs)]; |
| 280 | + while let Some(def_id) = parent_defs.parent { |
| 281 | + parent_defs = self.tcx().generics_of(def_id); |
| 282 | + stack.push((def_id, parent_defs)); |
| 283 | + } |
| 284 | + |
| 285 | + // We manually build up the substitution, rather than using convenience |
| 286 | + // methods in subst.rs so that we can iterate over the arguments and |
| 287 | + // parameters in lock-step linearly, rather than trying to match each pair. |
| 288 | + let mut substs: AccumulateVec<[Kind<'tcx>; 8]> = if count <= 8 { |
| 289 | + AccumulateVec::Array(ArrayVec::new()) |
| 290 | + } else { |
| 291 | + AccumulateVec::Heap(Vec::with_capacity(count)) |
| 292 | + }; |
| 293 | + fn push_kind<'tcx>(substs: &mut AccumulateVec<[Kind<'tcx>; 8]>, kind: Kind<'tcx>) { |
| 294 | + match substs { |
| 295 | + AccumulateVec::Array(ref mut arr) => arr.push(kind), |
| 296 | + AccumulateVec::Heap(ref mut vec) => vec.push(kind), |
| 297 | + } |
| 298 | + } |
| 299 | + |
| 300 | + // Iterate over each segment of the path. |
| 301 | + while let Some((_, defs)) = stack.pop() { |
| 302 | + let mut params = defs.params.iter(); |
| 303 | + let mut next_param = params.next(); |
| 304 | + |
| 305 | + // `Self` is handled first. |
| 306 | + if let Some(ty) = self_ty { |
| 307 | + if let Some(param) = next_param { |
| 308 | + if param.index == 0 { |
| 309 | + if let GenericParamDefKind::Type { .. } = param.kind { |
| 310 | + push_kind(&mut substs, ty.into()); |
| 311 | + next_param = params.next(); |
| 312 | + } |
280 | 313 | }
|
281 | 314 | }
|
282 | 315 | }
|
283 | 316 |
|
284 |
| - let inferred_lifetimes = if lt_provided == 0 { |
285 |
| - lt_accepted |
286 |
| - } else { |
287 |
| - 0 |
288 |
| - }; |
289 |
| - |
290 |
| - let param_idx = (param.index as usize - self_offset).saturating_sub(inferred_lifetimes); |
291 |
| - |
292 |
| - if let Some(arg) = generic_args.args.get(param_idx) { |
293 |
| - match param.kind { |
294 |
| - GenericParamDefKind::Lifetime => match arg { |
295 |
| - GenericArg::Lifetime(lt) => { |
296 |
| - return self.ast_region_to_region(lt, Some(param)).into(); |
| 317 | + let args = &generic_args.args; |
| 318 | + 'args: for arg in args { |
| 319 | + while let Some(param) = next_param { |
| 320 | + match param.kind { |
| 321 | + GenericParamDefKind::Lifetime => match arg { |
| 322 | + GenericArg::Lifetime(lt) => { |
| 323 | + push_kind(&mut substs, |
| 324 | + self.ast_region_to_region(<, Some(param)).into()); |
| 325 | + next_param = params.next(); |
| 326 | + continue 'args; |
| 327 | + } |
| 328 | + GenericArg::Type(_) => { |
| 329 | + // We expected a lifetime argument, but got a type |
| 330 | + // argument. That means we're inferring the lifetimes. |
| 331 | + push_kind(&mut substs, tcx.types.re_static.into()); |
| 332 | + next_param = params.next(); |
| 333 | + } |
| 334 | + } |
| 335 | + GenericParamDefKind::Type { .. } => match arg { |
| 336 | + GenericArg::Type(ty) => { |
| 337 | + push_kind(&mut substs, self.ast_ty_to_ty(&ty).into()); |
| 338 | + next_param = params.next(); |
| 339 | + continue 'args; |
| 340 | + } |
| 341 | + GenericArg::Lifetime(_) => { |
| 342 | + break 'args; |
| 343 | + } |
297 | 344 | }
|
298 |
| - _ => {} |
299 |
| - } |
300 |
| - GenericParamDefKind::Type { .. } => match arg { |
301 |
| - GenericArg::Type(ty) => return self.ast_ty_to_ty(ty).into(), |
302 |
| - _ => {} |
303 | 345 | }
|
304 | 346 | }
|
305 | 347 | }
|
306 | 348 |
|
307 |
| - match param.kind { |
308 |
| - GenericParamDefKind::Lifetime => tcx.types.re_static.into(), |
309 |
| - GenericParamDefKind::Type { has_default, .. } => { |
310 |
| - if infer_types { |
311 |
| - // No type parameters were provided, we can infer all. |
312 |
| - if !default_needs_object_self(param) { |
313 |
| - self.ty_infer_for_def(param, span).into() |
314 |
| - } else { |
315 |
| - self.ty_infer(span).into() |
316 |
| - } |
317 |
| - } else if has_default { |
318 |
| - // No type parameter provided, but a default exists. |
319 |
| - |
320 |
| - // If we are converting an object type, then the |
321 |
| - // `Self` parameter is unknown. However, some of the |
322 |
| - // other type parameters may reference `Self` in their |
323 |
| - // defaults. This will lead to an ICE if we are not |
324 |
| - // careful! |
325 |
| - if default_needs_object_self(param) { |
326 |
| - struct_span_err!(tcx.sess, span, E0393, |
327 |
| - "the type parameter `{}` must be explicitly \ |
328 |
| - specified", |
329 |
| - param.name) |
330 |
| - .span_label(span, |
331 |
| - format!("missing reference to `{}`", param.name)) |
332 |
| - .note(&format!("because of the default `Self` reference, \ |
333 |
| - type parameters must be specified on object \ |
334 |
| - types")) |
335 |
| - .emit(); |
336 |
| - tcx.types.err.into() |
| 349 | + while let Some(param) = next_param { |
| 350 | + match param.kind { |
| 351 | + GenericParamDefKind::Lifetime => { |
| 352 | + push_kind(&mut substs, tcx.types.re_static.into()); |
| 353 | + } |
| 354 | + GenericParamDefKind::Type { has_default, .. } => { |
| 355 | + if infer_types { |
| 356 | + // No type parameters were provided, we can infer all. |
| 357 | + push_kind(&mut substs, if !default_needs_object_self(param) { |
| 358 | + self.ty_infer_for_def(param, span).into() |
| 359 | + } else { |
| 360 | + self.ty_infer(span).into() |
| 361 | + }); |
| 362 | + } else if has_default { |
| 363 | + // No type parameter provided, but a default exists. |
| 364 | + |
| 365 | + // If we are converting an object type, then the |
| 366 | + // `Self` parameter is unknown. However, some of the |
| 367 | + // other type parameters may reference `Self` in their |
| 368 | + // defaults. This will lead to an ICE if we are not |
| 369 | + // careful! |
| 370 | + if default_needs_object_self(param) { |
| 371 | + struct_span_err!(tcx.sess, span, E0393, |
| 372 | + "the type parameter `{}` must be explicitly \ |
| 373 | + specified", |
| 374 | + param.name) |
| 375 | + .span_label(span, |
| 376 | + format!("missing reference to `{}`", param.name)) |
| 377 | + .note(&format!("because of the default `Self` reference, \ |
| 378 | + type parameters must be specified on object \ |
| 379 | + types")) |
| 380 | + .emit(); |
| 381 | + push_kind(&mut substs, tcx.types.err.into()); |
| 382 | + } else { |
| 383 | + // This is a default type parameter. |
| 384 | + let kind = self.normalize_ty( |
| 385 | + span, |
| 386 | + tcx.at(span).type_of(param.def_id) |
| 387 | + .subst_spanned(tcx, &substs, Some(span)) |
| 388 | + ).into(); |
| 389 | + push_kind(&mut substs, kind); |
| 390 | + } |
337 | 391 | } else {
|
338 |
| - // This is a default type parameter. |
339 |
| - self.normalize_ty( |
340 |
| - span, |
341 |
| - tcx.at(span).type_of(param.def_id) |
342 |
| - .subst_spanned(tcx, substs, Some(span)) |
343 |
| - ).into() |
| 392 | + // We've already errored above about the mismatch. |
| 393 | + push_kind(&mut substs, tcx.types.err.into()); |
344 | 394 | }
|
345 |
| - } else { |
346 |
| - // We've already errored above about the mismatch. |
347 |
| - tcx.types.err.into() |
348 | 395 | }
|
349 |
| - } |
| 396 | + }; |
| 397 | + next_param = params.next(); |
350 | 398 | }
|
351 |
| - }); |
| 399 | + } |
| 400 | + let substs = self.tcx().intern_substs(&substs); |
352 | 401 |
|
353 | 402 | let assoc_bindings = generic_args.bindings.iter().map(|binding| {
|
354 | 403 | ConvertedBinding {
|
|
0 commit comments