Skip to content

Commit 09722f7

Browse files
committed
Imply outlives-bounds on lazy type aliases
1 parent 2fe50cd commit 09722f7

File tree

7 files changed

+152
-24
lines changed

7 files changed

+152
-24
lines changed

compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs

+26
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ pub(super) fn infer_predicates(
5959
}
6060
}
6161

62+
DefKind::TyAlias if tcx.type_alias_is_lazy(item_did) => {
63+
insert_required_predicates_to_be_wf(
64+
tcx,
65+
tcx.type_of(item_did).instantiate_identity(),
66+
tcx.def_span(item_did),
67+
&global_inferred_outlives,
68+
&mut item_required_predicates,
69+
&mut explicit_map,
70+
);
71+
}
72+
6273
_ => {}
6374
};
6475

@@ -212,6 +223,21 @@ fn insert_required_predicates_to_be_wf<'tcx>(
212223
);
213224
}
214225

226+
ty::Alias(ty::Weak, alias) => {
227+
// This corresponds to a type like `Type<'a, T>`.
228+
// Contrary to a GAT like `<() as Trait>::Type<'a, T>`,
229+
// we do use the own explicit predicates.
230+
debug!("Weak");
231+
check_explicit_predicates(
232+
tcx,
233+
alias.def_id,
234+
alias.args,
235+
required_predicates,
236+
explicit_map,
237+
None,
238+
);
239+
}
240+
215241
// FIXME(inherent_associated_types): Handle this case properly.
216242
ty::Alias(ty::Inherent, _) => {}
217243

compiler/rustc_hir_analysis/src/outlives/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
2121
let crate_map = tcx.inferred_outlives_crate(());
2222
crate_map.predicates.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
2323
}
24+
DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => {
25+
let crate_map = tcx.inferred_outlives_crate(());
26+
crate_map.predicates.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
27+
}
2428
DefKind::AnonConst if tcx.features().generic_const_exprs => {
2529
let id = tcx.local_def_id_to_hir_id(item_def_id);
2630
if tcx.hir().opt_const_param_default_param_def_id(id).is_some() {

tests/ui/associated-type-bounds/duplicate.stderr

+24-24
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,30 @@ LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> {
66
| |
77
| `Item` bound here first
88

9+
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
10+
--> $DIR/duplicate.rs:255:40
11+
|
12+
LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
13+
| ---------- ^^^^^^^^^^ re-bound here
14+
| |
15+
| `Item` bound here first
16+
17+
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
18+
--> $DIR/duplicate.rs:257:44
19+
|
20+
LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
21+
| ---------- ^^^^^^^^^^ re-bound here
22+
| |
23+
| `Item` bound here first
24+
25+
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
26+
--> $DIR/duplicate.rs:259:43
27+
|
28+
LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
29+
| ------------- ^^^^^^^^^^^^^ re-bound here
30+
| |
31+
| `Item` bound here first
32+
933
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
1034
--> $DIR/duplicate.rs:11:36
1135
|
@@ -490,30 +514,6 @@ LL | Self: Iterator<Item: 'static, Item: 'static>,
490514
|
491515
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
492516

493-
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
494-
--> $DIR/duplicate.rs:255:40
495-
|
496-
LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
497-
| ---------- ^^^^^^^^^^ re-bound here
498-
| |
499-
| `Item` bound here first
500-
501-
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
502-
--> $DIR/duplicate.rs:257:44
503-
|
504-
LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
505-
| ---------- ^^^^^^^^^^ re-bound here
506-
| |
507-
| `Item` bound here first
508-
509-
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
510-
--> $DIR/duplicate.rs:259:43
511-
|
512-
LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
513-
| ------------- ^^^^^^^^^^^^^ re-bound here
514-
| |
515-
| `Item` bound here first
516-
517517
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
518518
--> $DIR/duplicate.rs:243:34
519519
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Ensure that we don't imply the *implied* outlives-bounds of weak aliases.
2+
// For context, we only imply the explicit bounds.
3+
#![feature(lazy_type_alias)]
4+
#![allow(incomplete_features)]
5+
6+
type Alias<'a, T> = &'a T; // implied bound `T: 'a`
7+
8+
struct Outer0<'a, T>(Alias<'a, T>); //~ ERROR the parameter type `T` may not live long enough
9+
10+
type Outer1<'a, T> = Alias<'a, T>; //~ ERROR the parameter type `T` may not live long enough
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0309]: the parameter type `T` may not live long enough
2+
--> $DIR/dont-imply-implied-outlives-bounds.rs:8:22
3+
|
4+
LL | struct Outer0<'a, T>(Alias<'a, T>);
5+
| -- ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
6+
| |
7+
| the parameter type `T` must be valid for the lifetime `'a` as defined here...
8+
|
9+
help: consider adding an explicit lifetime bound
10+
|
11+
LL | struct Outer0<'a, T: 'a>(Alias<'a, T>);
12+
| ++++
13+
14+
error[E0309]: the parameter type `T` may not live long enough
15+
--> $DIR/dont-imply-implied-outlives-bounds.rs:10:22
16+
|
17+
LL | type Outer1<'a, T> = Alias<'a, T>;
18+
| -- ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
19+
| |
20+
| the parameter type `T` must be valid for the lifetime `'a` as defined here...
21+
|
22+
help: consider adding an explicit lifetime bound
23+
|
24+
LL | type Outer1<'a, T: 'a> = Alias<'a, T>;
25+
| ++++
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0309`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: lifetime may not live long enough
2+
--> $DIR/implied-outlives-bounds.rs:18:12
3+
|
4+
LL | fn env0<'any>() {
5+
| ---- lifetime `'any` defined here
6+
LL | let _: TypeOutlives<'static, &'any ()>;
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'any` must outlive `'static`
8+
9+
error: lifetime may not live long enough
10+
--> $DIR/implied-outlives-bounds.rs:23:12
11+
|
12+
LL | fn env1<'any>() {
13+
| ---- lifetime `'any` defined here
14+
LL | let _: RegionOutlives<'static, 'any>;
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'any` must outlive `'static`
16+
17+
error: lifetime may not live long enough
18+
--> $DIR/implied-outlives-bounds.rs:28:12
19+
|
20+
LL | fn env2<'any>() {
21+
| ---- lifetime `'any` defined here
22+
LL | let _: Outer<'static, &'any ()>;
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'any` must outlive `'static`
24+
25+
error: aborting due to 3 previous errors
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Check that we imply outlives-bounds on lazy type aliases.
2+
3+
// revisions: pos neg
4+
//[pos] check-pass
5+
6+
#![feature(lazy_type_alias)]
7+
#![allow(incomplete_features)]
8+
9+
type TypeOutlives<'a, T> = &'a T;
10+
type RegionOutlives<'a, 'b> = &'a &'b ();
11+
12+
// Ensure that we imply `T: 'a` from the explicit predicates of the weak alias `Alias`.
13+
struct Outer<'a, T>(Alias<'a, T>);
14+
type Alias<'a, T: 'a> = &'a T;
15+
16+
#[cfg(neg)]
17+
fn env0<'any>() {
18+
let _: TypeOutlives<'static, &'any ()>; //[neg]~ ERROR lifetime may not live long enough
19+
}
20+
21+
#[cfg(neg)]
22+
fn env1<'any>() {
23+
let _: RegionOutlives<'static, 'any>; //[neg]~ ERROR lifetime may not live long enough
24+
}
25+
26+
#[cfg(neg)]
27+
fn env2<'any>() {
28+
let _: Outer<'static, &'any ()>; //[neg]~ ERROR lifetime may not live long enough
29+
}
30+
31+
fn main() {}

0 commit comments

Comments
 (0)