Check associated opaque types don't use unconstrained lifetimes

This commit is contained in:
Matthew Jasper 2019-12-26 23:41:32 +00:00
parent 033bd8c7af
commit 7f41cf4cef
5 changed files with 57 additions and 14 deletions

@ -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 {

@ -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 }> {}
}
}

@ -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() {}

@ -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`.

@ -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 {