diff options
| author | Matthew Jasper <mjjasper1@gmail.com> | 2019-12-26 23:41:32 +0000 |
|---|---|---|
| committer | Matthew Jasper <mjjasper1@gmail.com> | 2020-02-14 20:12:46 +0000 |
| commit | 7f41cf4cef551d887de539842d11945b6bfaa8b6 (patch) | |
| tree | 2f5cda4c006088e01d4563cf9e69b63fbcfbc1c4 | |
| parent | 033bd8c7af79d362b4e861543b63991e7300948f (diff) | |
| download | rust-7f41cf4cef551d887de539842d11945b6bfaa8b6.tar.gz rust-7f41cf4cef551d887de539842d11945b6bfaa8b6.zip | |
Check associated opaque types don't use unconstrained lifetimes
5 files changed, 57 insertions, 14 deletions
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index e9c18b59da9..0b4b8a49054 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -120,11 +120,23 @@ fn enforce_impl_params_are_constrained( let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs .iter() .map(|item_ref| tcx.hir().local_def_id(item_ref.id.hir_id)) - .filter(|&def_id| { + .flat_map(|def_id| { let item = tcx.associated_item(def_id); - item.kind == ty::AssocKind::Type && item.defaultness.has_value() + match item.kind { + ty::AssocKind::Type => { + if item.defaultness.has_value() { + cgp::parameters_for(&tcx.type_of(def_id), true) + } else { + Vec::new() + } + } + ty::AssocKind::OpaqueTy => { + let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx); + cgp::parameters_for(&predicates, true) + } + ty::AssocKind::Method | ty::AssocKind::Const => Vec::new(), + } }) - .flat_map(|def_id| cgp::parameters_for(&tcx.type_of(def_id), true)) .collect(); for param in &impl_generics.params { diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.rs b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs index 5db677d82e2..2907c21c620 100644 --- a/src/test/ui/type-alias-impl-trait/assoc-type-const.rs +++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs @@ -6,7 +6,7 @@ #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash -trait UnwrapItemsExt<const C: usize> { +trait UnwrapItemsExt<'a, const C: usize> { type Iter; fn unwrap_items(self) -> Self::Iter; } @@ -18,18 +18,16 @@ trait MyTrait<'a, const C: usize> { const MY_CONST: usize; } -impl<'a, const C: usize> MyTrait<'a, {C}> for MyStruct<{C}> { +impl<'a, const C: usize> MyTrait<'a, { C }> for MyStruct<{ C }> { type MyItem = u8; const MY_CONST: usize = C; } -impl<'a, I, const C: usize> UnwrapItemsExt<{C}> for I -where -{ - type Iter = impl MyTrait<'a, {C}>; +impl<'a, I, const C: usize> UnwrapItemsExt<'a, { C }> for I { + type Iter = impl MyTrait<'a, { C }>; fn unwrap_items(self) -> Self::Iter { - MyStruct::<{C}> {} + MyStruct::<{ C }> {} } } diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs new file mode 100644 index 00000000000..3f34b00ec77 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs @@ -0,0 +1,26 @@ +// Tests that we don't allow unconstrained lifetime parameters in impls when +// the lifetime is used in an associated opaque type. + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct {} + +trait MyTrait<'a> {} + +impl<'a> MyTrait<'a> for MyStruct {} + +impl<'a, I> UnwrapItemsExt for I { + //~^ ERROR the lifetime parameter `'a` is not constrained + type Iter = impl MyTrait<'a>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr new file mode 100644 index 00000000000..e594dc577b1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr @@ -0,0 +1,9 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/assoc-type-lifetime-unconstrained.rs:17:6 + | +LL | impl<'a, I> UnwrapItemsExt for I { + | ^^ unconstrained lifetime parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs index cff1d24494e..39f785d8cc5 100644 --- a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs +++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs @@ -4,7 +4,7 @@ #![feature(type_alias_impl_trait)] -trait UnwrapItemsExt { +trait UnwrapItemsExt<'a> { type Iter; fn unwrap_items(self) -> Self::Iter; } @@ -15,9 +15,7 @@ trait MyTrait<'a> {} impl<'a> MyTrait<'a> for MyStruct {} -impl<'a, I> UnwrapItemsExt for I -where -{ +impl<'a, I> UnwrapItemsExt<'a> for I { type Iter = impl MyTrait<'a>; fn unwrap_items(self) -> Self::Iter { |
