Skip to content

Commit eccb332

Browse files
authored
Rollup merge of #60409 - JohnTitor:error-for-existential-type, r=oli-obk
Require a trait in the bounds of existential types Fixes #53090 r? @oli-obk
2 parents d11b871 + db7f265 commit eccb332

15 files changed

+104
-12
lines changed

src/librustc_passes/ast_validation.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use syntax::ptr::P;
2020
use syntax::visit::{self, Visitor};
2121
use syntax::{span_err, struct_span_err, walk_list};
2222
use syntax_ext::proc_macro_decls::is_proc_macro_attr;
23-
use syntax_pos::Span;
23+
use syntax_pos::{Span, MultiSpan};
2424
use errors::Applicability;
2525
use log::debug;
2626

@@ -679,6 +679,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
679679
"unions cannot have zero fields");
680680
}
681681
}
682+
ItemKind::Existential(ref bounds, _) => {
683+
if !bounds.iter()
684+
.any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) {
685+
let msp = MultiSpan::from_spans(bounds.iter()
686+
.map(|bound| bound.span()).collect());
687+
self.err_handler().span_err(msp, "at least one trait must be specified");
688+
}
689+
}
682690
_ => {}
683691
}
684692

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![feature(existential_type)]
2+
3+
existential type Foo: 'static;
4+
//~^ ERROR: at least one trait must be specified
5+
6+
fn foo() -> Foo {
7+
"foo"
8+
}
9+
10+
fn bar() -> impl 'static { //~ ERROR: at least one trait must be specified
11+
"foo"
12+
}
13+
14+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: at least one trait must be specified
2+
--> $DIR/existential-types-with-no-traits.rs:3:23
3+
|
4+
LL | existential type Foo: 'static;
5+
| ^^^^^^^
6+
7+
error: at least one trait must be specified
8+
--> $DIR/existential-types-with-no-traits.rs:10:13
9+
|
10+
LL | fn bar() -> impl 'static {
11+
| ^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+

src/test/ui/existential_types/generic_nondefining_use.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ fn main() {}
44

55
existential type Cmp<T>: 'static;
66
//~^ ERROR could not find defining uses
7+
//~^^ ERROR: at least one trait must be specified
8+
79

810
// not a defining use, because it doesn't define *all* possible generics
911
fn cmp() -> Cmp<u32> { //~ ERROR defining existential type use does not fully define

src/test/ui/existential_types/generic_nondefining_use.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
error: at least one trait must be specified
2+
--> $DIR/generic_nondefining_use.rs:5:26
3+
|
4+
LL | existential type Cmp<T>: 'static;
5+
| ^^^^^^^
6+
17
error: defining existential type use does not fully define existential type
2-
--> $DIR/generic_nondefining_use.rs:9:1
8+
--> $DIR/generic_nondefining_use.rs:11:1
39
|
410
LL | / fn cmp() -> Cmp<u32> {
511
LL | | 5u32
@@ -12,5 +18,5 @@ error: could not find defining uses
1218
LL | existential type Cmp<T>: 'static;
1319
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1420

15-
error: aborting due to 2 previous errors
21+
error: aborting due to 3 previous errors
1622

src/test/ui/existential_types/generic_not_used.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
fn main() {}
44

55
existential type WrongGeneric<T: 'static>: 'static;
6+
//~^ ERROR: at least one trait must be specified
67

78
fn wrong_generic<U: 'static, V: 'static>(_: U, v: V) -> WrongGeneric<U> {
89
//~^ ERROR type parameter `V` is part of concrete type but not used in parameter list
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
error: at least one trait must be specified
2+
--> $DIR/generic_not_used.rs:5:44
3+
|
4+
LL | existential type WrongGeneric<T: 'static>: 'static;
5+
| ^^^^^^^
6+
17
error: type parameter `V` is part of concrete type but not used in parameter list for existential type
2-
--> $DIR/generic_not_used.rs:7:73
8+
--> $DIR/generic_not_used.rs:8:73
39
|
410
LL | fn wrong_generic<U: 'static, V: 'static>(_: U, v: V) -> WrongGeneric<U> {
511
| _________________________________________________________________________^
@@ -8,5 +14,5 @@ LL | | v
814
LL | | }
915
| |_^
1016

11-
error: aborting due to previous error
17+
error: aborting due to 2 previous errors
1218

src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ fn main() {
88

99
existential type WrongGeneric<T>: 'static;
1010
//~^ ERROR the parameter type `T` may not live long enough
11+
//~^^ ERROR: at least one trait must be specified
1112

1213
fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
1314
t

src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error: at least one trait must be specified
2+
--> $DIR/generic_type_does_not_live_long_enough.rs:9:35
3+
|
4+
LL | existential type WrongGeneric<T>: 'static;
5+
| ^^^^^^^
6+
17
error[E0308]: mismatched types
28
--> $DIR/generic_type_does_not_live_long_enough.rs:6:18
39
|
@@ -22,7 +28,7 @@ note: ...so that the type `T` will meet its required lifetime bounds
2228
LL | existential type WrongGeneric<T>: 'static;
2329
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2430

25-
error: aborting due to 2 previous errors
31+
error: aborting due to 3 previous errors
2632

2733
Some errors have detailed explanations: E0308, E0310.
2834
For more information about an error, try `rustc --explain E0308`.

src/test/ui/existential_types/generic_underconstrained.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ fn main() {}
44

55
trait Trait {}
66
existential type Underconstrained<T: Trait>: 'static; //~ ERROR the trait bound `T: Trait`
7+
//~^ ERROR: at least one trait must be specified
78

89
// no `Trait` bound
910
fn underconstrain<T>(_: T) -> Underconstrained<T> {

0 commit comments

Comments
 (0)