diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2020-01-12 10:19:19 +0000 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2020-02-14 22:40:03 +0000 |
| commit | 6d9e270a4ddf517b008537f0d8b3768db20d5436 (patch) | |
| tree | 88b297296b6e535c674ea18dd99c1cbefb61f53d | |
| parent | 78e0ab53fb4ac444e7d62735f0b8dcc9a42004f6 (diff) | |
| download | rust-6d9e270a4ddf517b008537f0d8b3768db20d5436.tar.gz rust-6d9e270a4ddf517b008537f0d8b3768db20d5436.zip | |
Fix and test nested impl Trait
| -rw-r--r-- | src/librustc_mir/borrow_check/region_infer/opaque_types.rs | 18 | ||||
| -rw-r--r-- | src/test/ui/impl-trait/nested-return-type.rs | 16 |
2 files changed, 29 insertions, 5 deletions
diff --git a/src/librustc_mir/borrow_check/region_infer/opaque_types.rs b/src/librustc_mir/borrow_check/region_infer/opaque_types.rs index 71702eb84e7..52d54f7b53c 100644 --- a/src/librustc_mir/borrow_check/region_infer/opaque_types.rs +++ b/src/librustc_mir/borrow_check/region_infer/opaque_types.rs @@ -13,8 +13,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// For example consider `fn f<'a>(x: &'a i32) -> impl Sized + 'a { x }`. /// This is lowered to give HIR something like /// - /// type _Return<'_a> = impl Sized + '_a; - /// fn f<'a>(x: &'a i32) -> _Return<'a> { x } + /// type f<'a>::_Return<'_a> = impl Sized + '_a; + /// fn f<'a>(x: &'a i32) -> f<'static>::_Return<'a> { x } /// /// When checking the return type record the type from the return and the /// type used in the return value. In this case they might be `_Return<'1>` @@ -34,9 +34,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }` /// /// Then we map the regions in both the type and the subst to their - /// `external_name` giving `concrete_type = &'a i32, substs = ['a]`. This - /// will then allow `infer_opaque_definition_from_instantiation` to - /// determine that `_Return<'_a> = &'_a i32`. + /// `external_name` giving `concrete_type = &'a i32`, + /// `substs = ['static, 'a]`. This will then allow + /// `infer_opaque_definition_from_instantiation` to determine that + /// `_Return<'_a> = &'_a i32`. /// /// There's a slight complication around closures. Given /// `fn f<'a: 'a>() { || {} }` the closure's type is something like @@ -72,6 +73,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { infcx.tcx.lifetimes.re_static }) } + // We don't fold regions in the predicates of opaque + // types to `ReVar`s. This means that in a case like + // + // fn f<'a: 'a>() -> impl Iterator<Item = impl Sized> + // + // The inner opaque type has `'static` in its substs. + ty::ReStatic => region, _ => { infcx.tcx.sess.delay_span_bug( span, diff --git a/src/test/ui/impl-trait/nested-return-type.rs b/src/test/ui/impl-trait/nested-return-type.rs new file mode 100644 index 00000000000..7d7a084b890 --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type.rs @@ -0,0 +1,16 @@ +// Check that nested impl Trait items work in functions with generic parameters. +// check-pass + +trait Captures<'a> {} + +impl<T> Captures<'_> for T {} + +fn nested_assoc_type<'a: 'a, T>() -> impl Iterator<Item = impl Sized> { + [1].iter() +} + +fn nested_assoc_lifetime<'a: 'a, T>() -> impl Iterator<Item = impl Captures<'a>> { + [1].iter() +} + +fn main() {} |
