Skip to content

Commit 7d5d374

Browse files
committed
Check associated opaque types don't use unconstrained lifetimes
1 parent 42a229b commit 7d5d374

File tree

5 files changed

+57
-14
lines changed

5 files changed

+57
-14
lines changed

src/librustc_typeck/impl_wf_check.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,23 @@ fn enforce_impl_params_are_constrained(
122122
let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs
123123
.iter()
124124
.map(|item_ref| tcx.hir().local_def_id(item_ref.id.hir_id))
125-
.filter(|&def_id| {
125+
.flat_map(|def_id| {
126126
let item = tcx.associated_item(def_id);
127-
item.kind == ty::AssocKind::Type && item.defaultness.has_value()
127+
match item.kind {
128+
ty::AssocKind::Type => {
129+
if item.defaultness.has_value() {
130+
cgp::parameters_for(&tcx.type_of(def_id), true)
131+
} else {
132+
Vec::new()
133+
}
134+
}
135+
ty::AssocKind::OpaqueTy => {
136+
let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx);
137+
cgp::parameters_for(&predicates, true)
138+
}
139+
ty::AssocKind::Method | ty::AssocKind::Const => Vec::new(),
140+
}
128141
})
129-
.flat_map(|def_id| cgp::parameters_for(&tcx.type_of(def_id), true))
130142
.collect();
131143

132144
for param in &impl_generics.params {

src/test/ui/type-alias-impl-trait/assoc-type-const.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#![feature(const_generics)]
77
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
88

9-
trait UnwrapItemsExt<const C: usize> {
9+
trait UnwrapItemsExt<'a, const C: usize> {
1010
type Iter;
1111
fn unwrap_items(self) -> Self::Iter;
1212
}
@@ -18,18 +18,16 @@ trait MyTrait<'a, const C: usize> {
1818
const MY_CONST: usize;
1919
}
2020

21-
impl<'a, const C: usize> MyTrait<'a, {C}> for MyStruct<{C}> {
21+
impl<'a, const C: usize> MyTrait<'a, { C }> for MyStruct<{ C }> {
2222
type MyItem = u8;
2323
const MY_CONST: usize = C;
2424
}
2525

26-
impl<'a, I, const C: usize> UnwrapItemsExt<{C}> for I
27-
where
28-
{
29-
type Iter = impl MyTrait<'a, {C}>;
26+
impl<'a, I, const C: usize> UnwrapItemsExt<'a, { C }> for I {
27+
type Iter = impl MyTrait<'a, { C }>;
3028

3129
fn unwrap_items(self) -> Self::Iter {
32-
MyStruct::<{C}> {}
30+
MyStruct::<{ C }> {}
3331
}
3432
}
3533

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Tests that we don't allow unconstrained lifetime parameters in impls when
2+
// the lifetime is used in an associated opaque type.
3+
4+
#![feature(type_alias_impl_trait)]
5+
6+
trait UnwrapItemsExt {
7+
type Iter;
8+
fn unwrap_items(self) -> Self::Iter;
9+
}
10+
11+
struct MyStruct {}
12+
13+
trait MyTrait<'a> {}
14+
15+
impl<'a> MyTrait<'a> for MyStruct {}
16+
17+
impl<'a, I> UnwrapItemsExt for I {
18+
//~^ ERROR the lifetime parameter `'a` is not constrained
19+
type Iter = impl MyTrait<'a>;
20+
21+
fn unwrap_items(self) -> Self::Iter {
22+
MyStruct {}
23+
}
24+
}
25+
26+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
2+
--> $DIR/assoc-type-lifetime-unconstrained.rs:17:6
3+
|
4+
LL | impl<'a, I> UnwrapItemsExt for I {
5+
| ^^ unconstrained lifetime parameter
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0207`.

src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#![feature(type_alias_impl_trait)]
66

7-
trait UnwrapItemsExt {
7+
trait UnwrapItemsExt<'a> {
88
type Iter;
99
fn unwrap_items(self) -> Self::Iter;
1010
}
@@ -15,9 +15,7 @@ trait MyTrait<'a> {}
1515

1616
impl<'a> MyTrait<'a> for MyStruct {}
1717

18-
impl<'a, I> UnwrapItemsExt for I
19-
where
20-
{
18+
impl<'a, I> UnwrapItemsExt<'a> for I {
2119
type Iter = impl MyTrait<'a>;
2220

2321
fn unwrap_items(self) -> Self::Iter {

0 commit comments

Comments
 (0)