]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Rollup merge of #99480 - miam-miam100:arg-format, r=oli-obk
[rust.git] / compiler / rustc_borrowck / src / region_infer / opaque_types.rs
1 use rustc_data_structures::fx::FxHashMap;
2 use rustc_data_structures::vec_map::VecMap;
3 use rustc_hir::def_id::LocalDefId;
4 use rustc_hir::OpaqueTyOrigin;
5 use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
6 use rustc_infer::infer::TyCtxtInferExt as _;
7 use rustc_infer::infer::{DefiningAnchor, InferCtxt};
8 use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine};
9 use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
10 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts};
11 use rustc_middle::ty::visit::TypeVisitable;
12 use rustc_middle::ty::{
13     self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt, TypeFoldable,
14 };
15 use rustc_span::Span;
16 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
17 use rustc_trait_selection::traits::TraitEngineExt as _;
18
19 use super::RegionInferenceContext;
20
21 impl<'tcx> RegionInferenceContext<'tcx> {
22     /// Resolve any opaque types that were encountered while borrow checking
23     /// this item. This is then used to get the type in the `type_of` query.
24     ///
25     /// For example consider `fn f<'a>(x: &'a i32) -> impl Sized + 'a { x }`.
26     /// This is lowered to give HIR something like
27     ///
28     /// type f<'a>::_Return<'_a> = impl Sized + '_a;
29     /// fn f<'a>(x: &'a i32) -> f<'static>::_Return<'a> { x }
30     ///
31     /// When checking the return type record the type from the return and the
32     /// type used in the return value. In this case they might be `_Return<'1>`
33     /// and `&'2 i32` respectively.
34     ///
35     /// Once we to this method, we have completed region inference and want to
36     /// call `infer_opaque_definition_from_instantiation` to get the inferred
37     /// type of `_Return<'_a>`. `infer_opaque_definition_from_instantiation`
38     /// compares lifetimes directly, so we need to map the inference variables
39     /// back to concrete lifetimes: `'static`, `ReEarlyBound` or `ReFree`.
40     ///
41     /// First we map all the lifetimes in the concrete type to an equal
42     /// universal region that occurs in the concrete type's substs, in this case
43     /// this would result in `&'1 i32`. We only consider regions in the substs
44     /// in case there is an equal region that does not. For example, this should
45     /// be allowed:
46     /// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }`
47     ///
48     /// Then we map the regions in both the type and the subst to their
49     /// `external_name` giving `concrete_type = &'a i32`,
50     /// `substs = ['static, 'a]`. This will then allow
51     /// `infer_opaque_definition_from_instantiation` to determine that
52     /// `_Return<'_a> = &'_a i32`.
53     ///
54     /// There's a slight complication around closures. Given
55     /// `fn f<'a: 'a>() { || {} }` the closure's type is something like
56     /// `f::<'a>::{{closure}}`. The region parameter from f is essentially
57     /// ignored by type checking so ends up being inferred to an empty region.
58     /// Calling `universal_upper_bound` for such a region gives `fr_fn_body`,
59     /// which has no `external_name` in which case we use `'empty` as the
60     /// region to pass to `infer_opaque_definition_from_instantiation`.
61     #[instrument(level = "debug", skip(self, infcx))]
62     pub(crate) fn infer_opaque_types(
63         &self,
64         infcx: &InferCtxt<'_, 'tcx>,
65         opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
66     ) -> VecMap<LocalDefId, OpaqueHiddenType<'tcx>> {
67         let mut result: VecMap<LocalDefId, OpaqueHiddenType<'tcx>> = VecMap::new();
68         for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
69             let substs = opaque_type_key.substs;
70             debug!(?concrete_type, ?substs);
71
72             let mut subst_regions = vec![self.universal_regions.fr_static];
73             let universal_substs = infcx.tcx.fold_regions(substs, |region, _| {
74                 if let ty::RePlaceholder(..) = region.kind() {
75                     // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
76                     return region;
77                 }
78                 let vid = self.to_region_vid(region);
79                 trace!(?vid);
80                 let scc = self.constraint_sccs.scc(vid);
81                 trace!(?scc);
82                 match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
83                     self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
84                 }) {
85                     Some(region) => {
86                         let vid = self.universal_regions.to_region_vid(region);
87                         subst_regions.push(vid);
88                         region
89                     }
90                     None => {
91                         subst_regions.push(vid);
92                         infcx.tcx.sess.delay_span_bug(
93                             concrete_type.span,
94                             "opaque type with non-universal region substs",
95                         );
96                         infcx.tcx.lifetimes.re_static
97                     }
98                 }
99             });
100
101             subst_regions.sort();
102             subst_regions.dedup();
103
104             let universal_concrete_type =
105                 infcx.tcx.fold_regions(concrete_type, |region, _| match *region {
106                     ty::ReVar(vid) => subst_regions
107                         .iter()
108                         .find(|ur_vid| self.eval_equal(vid, **ur_vid))
109                         .and_then(|ur_vid| self.definitions[*ur_vid].external_name)
110                         .unwrap_or(infcx.tcx.lifetimes.re_root_empty),
111                     _ => region,
112                 });
113
114             debug!(?universal_concrete_type, ?universal_substs);
115
116             let opaque_type_key =
117                 OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
118             let ty = infcx.infer_opaque_definition_from_instantiation(
119                 opaque_type_key,
120                 universal_concrete_type,
121                 origin,
122             );
123             // Sometimes two opaque types are the same only after we remap the generic parameters
124             // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
125             // and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
126             // once we convert the generic parameters to those of the opaque type.
127             if let Some(prev) = result.get_mut(&opaque_type_key.def_id) {
128                 if prev.ty != ty {
129                     if !ty.references_error() {
130                         prev.report_mismatch(
131                             &OpaqueHiddenType { ty, span: concrete_type.span },
132                             infcx.tcx,
133                         );
134                     }
135                     prev.ty = infcx.tcx.ty_error();
136                 }
137                 // Pick a better span if there is one.
138                 // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
139                 prev.span = prev.span.substitute_dummy(concrete_type.span);
140             } else {
141                 result.insert(
142                     opaque_type_key.def_id,
143                     OpaqueHiddenType { ty, span: concrete_type.span },
144                 );
145             }
146         }
147         result
148     }
149
150     /// Map the regions in the type to named regions. This is similar to what
151     /// `infer_opaque_types` does, but can infer any universal region, not only
152     /// ones from the substs for the opaque type. It also doesn't double check
153     /// that the regions produced are in fact equal to the named region they are
154     /// replaced with. This is fine because this function is only to improve the
155     /// region names in error messages.
156     pub(crate) fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
157     where
158         T: TypeFoldable<'tcx>,
159     {
160         tcx.fold_regions(ty, |region, _| match *region {
161             ty::ReVar(vid) => {
162                 // Find something that we can name
163                 let upper_bound = self.approx_universal_upper_bound(vid);
164                 let upper_bound = &self.definitions[upper_bound];
165                 match upper_bound.external_name {
166                     Some(reg) => reg,
167                     None => {
168                         // Nothing exact found, so we pick the first one that we find.
169                         let scc = self.constraint_sccs.scc(vid);
170                         for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
171                             match self.definitions[vid].external_name {
172                                 None => {}
173                                 Some(region) if region.is_static() => {}
174                                 Some(region) => return region,
175                             }
176                         }
177                         region
178                     }
179                 }
180             }
181             _ => region,
182         })
183     }
184 }
185
186 pub trait InferCtxtExt<'tcx> {
187     fn infer_opaque_definition_from_instantiation(
188         &self,
189         opaque_type_key: OpaqueTypeKey<'tcx>,
190         instantiated_ty: OpaqueHiddenType<'tcx>,
191         origin: OpaqueTyOrigin,
192     ) -> Ty<'tcx>;
193 }
194
195 impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
196     /// Given the fully resolved, instantiated type for an opaque
197     /// type, i.e., the value of an inference variable like C1 or C2
198     /// (*), computes the "definition type" for an opaque type
199     /// definition -- that is, the inferred value of `Foo1<'x>` or
200     /// `Foo2<'x>` that we would conceptually use in its definition:
201     /// ```ignore (illustrative)
202     /// type Foo1<'x> = impl Bar<'x> = AAA;  // <-- this type AAA
203     /// type Foo2<'x> = impl Bar<'x> = BBB;  // <-- or this type BBB
204     /// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
205     /// ```
206     /// Note that these values are defined in terms of a distinct set of
207     /// generic parameters (`'x` instead of `'a`) from C1 or C2. The main
208     /// purpose of this function is to do that translation.
209     ///
210     /// (*) C1 and C2 were introduced in the comments on
211     /// `register_member_constraints`. Read that comment for more context.
212     ///
213     /// # Parameters
214     ///
215     /// - `def_id`, the `impl Trait` type
216     /// - `substs`, the substs  used to instantiate this opaque type
217     /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
218     ///   `opaque_defn.concrete_ty`
219     #[instrument(level = "debug", skip(self))]
220     fn infer_opaque_definition_from_instantiation(
221         &self,
222         opaque_type_key: OpaqueTypeKey<'tcx>,
223         instantiated_ty: OpaqueHiddenType<'tcx>,
224         origin: OpaqueTyOrigin,
225     ) -> Ty<'tcx> {
226         if self.is_tainted_by_errors() {
227             return self.tcx.ty_error();
228         }
229
230         let OpaqueTypeKey { def_id, substs } = opaque_type_key;
231
232         // Use substs to build up a reverse map from regions to their
233         // identity mappings. This is necessary because of `impl
234         // Trait` lifetimes are computed by replacing existing
235         // lifetimes with 'static and remapping only those used in the
236         // `impl Trait` return type, resulting in the parameters
237         // shifting.
238         let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id());
239         debug!(?id_substs);
240         let map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>> =
241             substs.iter().enumerate().map(|(index, subst)| (subst, id_substs[index])).collect();
242         debug!("map = {:#?}", map);
243
244         // Convert the type from the function into a type valid outside
245         // the function, by replacing invalid regions with 'static,
246         // after producing an error for each of them.
247         let definition_ty = instantiated_ty.ty.fold_with(&mut ReverseMapper::new(
248             self.tcx,
249             def_id,
250             map,
251             instantiated_ty.ty,
252             instantiated_ty.span,
253         ));
254         debug!(?definition_ty);
255
256         if !check_opaque_type_parameter_valid(
257             self.tcx,
258             opaque_type_key,
259             origin,
260             instantiated_ty.span,
261         ) {
262             return self.tcx.ty_error();
263         }
264
265         // Only check this for TAIT. RPIT already supports `src/test/ui/impl-trait/nested-return-type2.rs`
266         // on stable and we'd break that.
267         if let OpaqueTyOrigin::TyAlias = origin {
268             // This logic duplicates most of `check_opaque_meets_bounds`.
269             // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
270             let param_env = self.tcx.param_env(def_id);
271             let body_id = self.tcx.local_def_id_to_hir_id(def_id);
272             // HACK This bubble is required for this tests to pass:
273             // type-alias-impl-trait/issue-67844-nested-opaque.rs
274             self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter(
275                 move |infcx| {
276                     // Require the hidden type to be well-formed with only the generics of the opaque type.
277                     // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
278                     // hidden type is well formed even without those bounds.
279                     let predicate =
280                         ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
281                             .to_predicate(infcx.tcx);
282                     let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
283
284                     // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
285                     // the bounds that the function supplies.
286                     match infcx.register_hidden_type(
287                         OpaqueTypeKey { def_id, substs: id_substs },
288                         ObligationCause::misc(instantiated_ty.span, body_id),
289                         param_env,
290                         definition_ty,
291                         origin,
292                     ) {
293                         Ok(infer_ok) => {
294                             for obligation in infer_ok.obligations {
295                                 fulfillment_cx.register_predicate_obligation(&infcx, obligation);
296                             }
297                         }
298                         Err(err) => {
299                             infcx
300                                 .report_mismatched_types(
301                                     &ObligationCause::misc(instantiated_ty.span, body_id),
302                                     self.tcx.mk_opaque(def_id.to_def_id(), id_substs),
303                                     definition_ty,
304                                     err,
305                                 )
306                                 .emit();
307                         }
308                     }
309
310                     fulfillment_cx.register_predicate_obligation(
311                         &infcx,
312                         Obligation::misc(instantiated_ty.span, body_id, param_env, predicate),
313                     );
314
315                     // Check that all obligations are satisfied by the implementation's
316                     // version.
317                     let errors = fulfillment_cx.select_all_or_error(&infcx);
318
319                     // This is still required for many(half of the tests in ui/type-alias-impl-trait)
320                     // tests to pass
321                     let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
322
323                     if errors.is_empty() {
324                         definition_ty
325                     } else {
326                         infcx.report_fulfillment_errors(&errors, None, false);
327                         self.tcx.ty_error()
328                     }
329                 },
330             )
331         } else {
332             definition_ty
333         }
334     }
335 }
336
337 fn check_opaque_type_parameter_valid(
338     tcx: TyCtxt<'_>,
339     opaque_type_key: OpaqueTypeKey<'_>,
340     origin: OpaqueTyOrigin,
341     span: Span,
342 ) -> bool {
343     match origin {
344         // No need to check return position impl trait (RPIT)
345         // because for type and const parameters they are correct
346         // by construction: we convert
347         //
348         // fn foo<P0..Pn>() -> impl Trait
349         //
350         // into
351         //
352         // type Foo<P0...Pn>
353         // fn foo<P0..Pn>() -> Foo<P0...Pn>.
354         //
355         // For lifetime parameters we convert
356         //
357         // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
358         //
359         // into
360         //
361         // type foo::<'p0..'pn>::Foo<'q0..'qm>
362         // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
363         //
364         // which would error here on all of the `'static` args.
365         OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true,
366         // Check these
367         OpaqueTyOrigin::TyAlias => {}
368     }
369     let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
370     let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
371     for (i, arg) in opaque_type_key.substs.iter().enumerate() {
372         let arg_is_param = match arg.unpack() {
373             GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
374             GenericArgKind::Lifetime(lt) if lt.is_static() => {
375                 tcx.sess
376                     .struct_span_err(span, "non-defining opaque type use in defining scope")
377                     .span_label(
378                         tcx.def_span(opaque_generics.param_at(i, tcx).def_id),
379                         "cannot use static lifetime; use a bound lifetime \
380                                     instead or remove the lifetime parameter from the \
381                                     opaque type",
382                     )
383                     .emit();
384                 return false;
385             }
386             GenericArgKind::Lifetime(lt) => {
387                 matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_))
388             }
389             GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)),
390         };
391
392         if arg_is_param {
393             seen_params.entry(arg).or_default().push(i);
394         } else {
395             // Prevent `fn foo() -> Foo<u32>` from being defining.
396             let opaque_param = opaque_generics.param_at(i, tcx);
397             tcx.sess
398                 .struct_span_err(span, "non-defining opaque type use in defining scope")
399                 .span_note(
400                     tcx.def_span(opaque_param.def_id),
401                     &format!(
402                         "used non-generic {} `{}` for generic parameter",
403                         opaque_param.kind.descr(),
404                         arg,
405                     ),
406                 )
407                 .emit();
408             return false;
409         }
410     }
411
412     for (_, indices) in seen_params {
413         if indices.len() > 1 {
414             let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
415             let spans: Vec<_> = indices
416                 .into_iter()
417                 .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
418                 .collect();
419             tcx.sess
420                 .struct_span_err(span, "non-defining opaque type use in defining scope")
421                 .span_note(spans, &format!("{} used multiple times", descr))
422                 .emit();
423             return false;
424         }
425     }
426     true
427 }
428
429 struct ReverseMapper<'tcx> {
430     tcx: TyCtxt<'tcx>,
431
432     opaque_type_def_id: LocalDefId,
433     map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
434     map_missing_regions_to_empty: bool,
435
436     /// initially `Some`, set to `None` once error has been reported
437     hidden_ty: Option<Ty<'tcx>>,
438
439     /// Span of function being checked.
440     span: Span,
441 }
442
443 impl<'tcx> ReverseMapper<'tcx> {
444     fn new(
445         tcx: TyCtxt<'tcx>,
446         opaque_type_def_id: LocalDefId,
447         map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>>,
448         hidden_ty: Ty<'tcx>,
449         span: Span,
450     ) -> Self {
451         Self {
452             tcx,
453             opaque_type_def_id,
454             map,
455             map_missing_regions_to_empty: false,
456             hidden_ty: Some(hidden_ty),
457             span,
458         }
459     }
460
461     fn fold_kind_mapping_missing_regions_to_empty(
462         &mut self,
463         kind: GenericArg<'tcx>,
464     ) -> GenericArg<'tcx> {
465         assert!(!self.map_missing_regions_to_empty);
466         self.map_missing_regions_to_empty = true;
467         let kind = kind.fold_with(self);
468         self.map_missing_regions_to_empty = false;
469         kind
470     }
471
472     fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
473         assert!(!self.map_missing_regions_to_empty);
474         kind.fold_with(self)
475     }
476 }
477
478 impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
479     fn tcx(&self) -> TyCtxt<'tcx> {
480         self.tcx
481     }
482
483     #[instrument(skip(self), level = "debug")]
484     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
485         match *r {
486             // Ignore bound regions and `'static` regions that appear in the
487             // type, we only need to remap regions that reference lifetimes
488             // from the function declaration.
489             // This would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
490             ty::ReLateBound(..) | ty::ReStatic => return r,
491
492             // If regions have been erased (by writeback), don't try to unerase
493             // them.
494             ty::ReErased => return r,
495
496             // The regions that we expect from borrow checking.
497             ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {}
498
499             ty::ReEmpty(_) | ty::RePlaceholder(_) | ty::ReVar(_) => {
500                 // All of the regions in the type should either have been
501                 // erased by writeback, or mapped back to named regions by
502                 // borrow checking.
503                 bug!("unexpected region kind in opaque type: {:?}", r);
504             }
505         }
506
507         let generics = self.tcx().generics_of(self.opaque_type_def_id);
508         match self.map.get(&r.into()).map(|k| k.unpack()) {
509             Some(GenericArgKind::Lifetime(r1)) => r1,
510             Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
511             None if self.map_missing_regions_to_empty => self.tcx.lifetimes.re_root_empty,
512             None if generics.parent.is_some() => {
513                 if let Some(hidden_ty) = self.hidden_ty.take() {
514                     unexpected_hidden_region_diagnostic(
515                         self.tcx,
516                         self.tcx.def_span(self.opaque_type_def_id),
517                         hidden_ty,
518                         r,
519                     )
520                     .emit();
521                 }
522                 self.tcx.lifetimes.re_root_empty
523             }
524             None => {
525                 self.tcx
526                     .sess
527                     .struct_span_err(self.span, "non-defining opaque type use in defining scope")
528                     .span_label(
529                         self.span,
530                         format!(
531                             "lifetime `{}` is part of concrete type but not used in \
532                                  parameter list of the `impl Trait` type alias",
533                             r
534                         ),
535                     )
536                     .emit();
537
538                 self.tcx().lifetimes.re_static
539             }
540         }
541     }
542
543     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
544         match *ty.kind() {
545             ty::Closure(def_id, substs) => {
546                 // I am a horrible monster and I pray for death. When
547                 // we encounter a closure here, it is always a closure
548                 // from within the function that we are currently
549                 // type-checking -- one that is now being encapsulated
550                 // in an opaque type. Ideally, we would
551                 // go through the types/lifetimes that it references
552                 // and treat them just like we would any other type,
553                 // which means we would error out if we find any
554                 // reference to a type/region that is not in the
555                 // "reverse map".
556                 //
557                 // **However,** in the case of closures, there is a
558                 // somewhat subtle (read: hacky) consideration. The
559                 // problem is that our closure types currently include
560                 // all the lifetime parameters declared on the
561                 // enclosing function, even if they are unused by the
562                 // closure itself. We can't readily filter them out,
563                 // so here we replace those values with `'empty`. This
564                 // can't really make a difference to the rest of the
565                 // compiler; those regions are ignored for the
566                 // outlives relation, and hence don't affect trait
567                 // selection or auto traits, and they are erased
568                 // during codegen.
569
570                 let generics = self.tcx.generics_of(def_id);
571                 let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
572                     if index < generics.parent_count {
573                         // Accommodate missing regions in the parent kinds...
574                         self.fold_kind_mapping_missing_regions_to_empty(kind)
575                     } else {
576                         // ...but not elsewhere.
577                         self.fold_kind_normally(kind)
578                     }
579                 }));
580
581                 self.tcx.mk_closure(def_id, substs)
582             }
583
584             ty::Generator(def_id, substs, movability) => {
585                 let generics = self.tcx.generics_of(def_id);
586                 let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
587                     if index < generics.parent_count {
588                         // Accommodate missing regions in the parent kinds...
589                         self.fold_kind_mapping_missing_regions_to_empty(kind)
590                     } else {
591                         // ...but not elsewhere.
592                         self.fold_kind_normally(kind)
593                     }
594                 }));
595
596                 self.tcx.mk_generator(def_id, substs, movability)
597             }
598
599             ty::Param(param) => {
600                 // Look it up in the substitution list.
601                 match self.map.get(&ty.into()).map(|k| k.unpack()) {
602                     // Found it in the substitution list; replace with the parameter from the
603                     // opaque type.
604                     Some(GenericArgKind::Type(t1)) => t1,
605                     Some(u) => panic!("type mapped to unexpected kind: {:?}", u),
606                     None => {
607                         debug!(?param, ?self.map);
608                         self.tcx
609                             .sess
610                             .struct_span_err(
611                                 self.span,
612                                 &format!(
613                                     "type parameter `{}` is part of concrete type but not \
614                                           used in parameter list for the `impl Trait` type alias",
615                                     ty
616                                 ),
617                             )
618                             .emit();
619
620                         self.tcx().ty_error()
621                     }
622                 }
623             }
624
625             _ => ty.super_fold_with(self),
626         }
627     }
628
629     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
630         trace!("checking const {:?}", ct);
631         // Find a const parameter
632         match ct.kind() {
633             ty::ConstKind::Param(..) => {
634                 // Look it up in the substitution list.
635                 match self.map.get(&ct.into()).map(|k| k.unpack()) {
636                     // Found it in the substitution list, replace with the parameter from the
637                     // opaque type.
638                     Some(GenericArgKind::Const(c1)) => c1,
639                     Some(u) => panic!("const mapped to unexpected kind: {:?}", u),
640                     None => {
641                         self.tcx
642                             .sess
643                             .struct_span_err(
644                                 self.span,
645                                 &format!(
646                                     "const parameter `{}` is part of concrete type but not \
647                                           used in parameter list for the `impl Trait` type alias",
648                                     ct
649                                 ),
650                             )
651                             .emit();
652
653                         self.tcx().const_error(ct.ty())
654                     }
655                 }
656             }
657
658             _ => ct,
659         }
660     }
661 }