Skip to content

Commit 333be81

Browse files
committed
allow trait objects to have extra marker traits
1 parent efec545 commit 333be81

21 files changed

+334
-314
lines changed

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,27 +1297,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
12971297
}
12981298
}
12991299

1300-
// Expand trait aliases recursively and check that only one regular (non-auto) trait
1300+
// Expand trait aliases recursively and check that only one regular (non-auto or marker) trait
13011301
// is used and no 'maybe' bounds are used.
13021302
let expanded_traits =
13031303
traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter().map(|&(a, b, _)| (a, b)));
1304-
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
1305-
expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
1304+
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits.partition(|i| {
1305+
let trait_def = tcx.trait_def(i.trait_ref().def_id());
1306+
1307+
trait_def.has_auto_impl || trait_def.is_marker
1308+
});
13061309
if regular_traits.len() > 1 {
13071310
let first_trait = &regular_traits[0];
13081311
let additional_trait = &regular_traits[1];
13091312
let mut err = struct_span_err!(
13101313
tcx.sess,
13111314
additional_trait.bottom().1,
13121315
E0225,
1313-
"only auto traits can be used as additional traits in a trait object"
1316+
"only auto and marker traits can be used as additional traits in a trait object"
13141317
);
13151318
additional_trait.label_with_exp_info(
13161319
&mut err,
1317-
"additional non-auto trait",
1320+
"additional non-auto or marker trait",
13181321
"additional use",
13191322
);
1320-
first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use");
1323+
first_trait.label_with_exp_info(
1324+
&mut err,
1325+
"first non-auto or marker trait",
1326+
"first use",
1327+
);
13211328
err.help(&format!(
13221329
"consider creating a new trait with all of these as supertraits and using that \
13231330
trait here instead: `trait NewTrait: {} {{}}`",

src/test/ui/associated-types/issue-22560.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ LL | type Test = dyn Add + Sub;
2424
|
2525
= note: because of the default `Self` reference, type parameters must be specified on object types
2626

27-
error[E0225]: only auto traits can be used as additional traits in a trait object
27+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
2828
--> $DIR/issue-22560.rs:9:23
2929
|
3030
LL | type Test = dyn Add + Sub;
31-
| --- ^^^ additional non-auto trait
31+
| --- ^^^ additional non-auto or marker trait
3232
| |
33-
| first non-auto trait
33+
| first non-auto or marker trait
3434
|
3535
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<[type error]> + Sub<[type error]> {}`
3636
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>

src/test/ui/associated-types/missing-associated-types.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::ops::{Add, Sub, Mul, Div};
1+
use std::ops::{Add, Div, Mul, Sub};
22
trait X<Rhs>: Mul<Rhs> + Div<Rhs> {}
33
trait Y<Rhs>: Div<Rhs, Output = Rhs> {
44
type A;
@@ -10,16 +10,16 @@ trait Z<Rhs>: Div<Rhs> {
1010
trait Fine<Rhs>: Div<Rhs, Output = Rhs> {}
1111

1212
type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
13-
//~^ ERROR only auto traits can be used as additional traits in a trait object
13+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object
1414
//~| ERROR the value of the associated types
1515
type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
16-
//~^ ERROR only auto traits can be used as additional traits in a trait object
16+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object
1717
//~| ERROR the value of the associated types
1818
type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
19-
//~^ ERROR only auto traits can be used as additional traits in a trait object
19+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object
2020
//~| ERROR the value of the associated types
2121
type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
22-
//~^ ERROR only auto traits can be used as additional traits in a trait object
22+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object
2323
//~| ERROR the value of the associated types
2424
type Bal<Rhs> = dyn X<Rhs>;
2525
//~^ ERROR the value of the associated types

src/test/ui/associated-types/missing-associated-types.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0225]: only auto traits can be used as additional traits in a trait object
1+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
22
--> $DIR/missing-associated-types.rs:12:32
33
|
44
LL | type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
5-
| -------- ^^^^^^^^ additional non-auto trait
5+
| -------- ^^^^^^^^ additional non-auto or marker trait
66
| |
7-
| first non-auto trait
7+
| first non-auto or marker trait
88
|
99
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs> {}`
1010
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -27,13 +27,13 @@ help: specify the associated types
2727
LL | type Foo<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + X<Rhs, Output = Type> + Y<Rhs, A = Type>;
2828
| ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
2929

30-
error[E0225]: only auto traits can be used as additional traits in a trait object
30+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
3131
--> $DIR/missing-associated-types.rs:15:32
3232
|
3333
LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
34-
| -------- ^^^^^^^^ additional non-auto trait
34+
| -------- ^^^^^^^^ additional non-auto or marker trait
3535
| |
36-
| first non-auto trait
36+
| first non-auto or marker trait
3737
|
3838
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs> {}`
3939
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -63,13 +63,13 @@ help: specify the associated types
6363
LL | type Bar<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + X<Rhs> + Z<Rhs, A = Type, B = Type, Output = Type>;
6464
| ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6565

66-
error[E0225]: only auto traits can be used as additional traits in a trait object
66+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
6767
--> $DIR/missing-associated-types.rs:18:32
6868
|
6969
LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
70-
| -------- ^^^^^^^^ additional non-auto trait
70+
| -------- ^^^^^^^^ additional non-auto or marker trait
7171
| |
72-
| first non-auto trait
72+
| first non-auto or marker trait
7373
|
7474
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Y<Rhs> {}`
7575
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
@@ -91,13 +91,13 @@ help: specify the associated types
9191
LL | type Baz<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + Y<Rhs, A = Type>;
9292
| ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
9393

94-
error[E0225]: only auto traits can be used as additional traits in a trait object
94+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
9595
--> $DIR/missing-associated-types.rs:21:32
9696
|
9797
LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
98-
| -------- ^^^^^^^^ additional non-auto trait
98+
| -------- ^^^^^^^^ additional non-auto or marker trait
9999
| |
100-
| first non-auto trait
100+
| first non-auto or marker trait
101101
|
102102
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Fine<Rhs> {}`
103103
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>

src/test/ui/error-codes/E0225.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ trait Foo = std::io::Read + std::io::Write;
44

55
fn main() {
66
let _: Box<dyn std::io::Read + std::io::Write>;
7-
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
7+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object [E0225]
88
let _: Box<dyn Foo>;
9-
//~^ ERROR only auto traits can be used as additional traits in a trait object [E0225]
9+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object [E0225]
1010
}

src/test/ui/error-codes/E0225.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
error[E0225]: only auto traits can be used as additional traits in a trait object
1+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
22
--> $DIR/E0225.rs:6:36
33
|
44
LL | let _: Box<dyn std::io::Read + std::io::Write>;
5-
| ------------- ^^^^^^^^^^^^^^ additional non-auto trait
5+
| ------------- ^^^^^^^^^^^^^^ additional non-auto or marker trait
66
| |
7-
| first non-auto trait
7+
| first non-auto or marker trait
88
|
99
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: std::io::Read + std::io::Write {}`
1010
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
1111

12-
error[E0225]: only auto traits can be used as additional traits in a trait object
12+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
1313
--> $DIR/E0225.rs:8:20
1414
|
1515
LL | trait Foo = std::io::Read + std::io::Write;
16-
| ------------- -------------- additional non-auto trait
16+
| ------------- -------------- additional non-auto or marker trait
1717
| |
18-
| first non-auto trait
18+
| first non-auto or marker trait
1919
...
2020
LL | let _: Box<dyn Foo>;
2121
| ^^^

src/test/ui/issues/issue-32963.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ use std::mem;
22

33
trait Misc {}
44

5-
fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
5+
fn size_of_copy<T: Copy + ?Sized>() -> usize {
6+
mem::size_of::<T>()
7+
}
68

79
fn main() {
810
size_of_copy::<dyn Misc + Copy>();
9-
//~^ ERROR only auto traits can be used as additional traits in a trait object
10-
//~| ERROR only auto traits can be used as additional traits in a trait object
11+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object
12+
//~| ERROR only auto and marker traits can be used as additional traits in a trait object
1113
//~| ERROR the trait bound `dyn Misc: Copy` is not satisfied
1214
}

src/test/ui/issues/issue-32963.stderr

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
1-
error[E0225]: only auto traits can be used as additional traits in a trait object
2-
--> $DIR/issue-32963.rs:8:31
1+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
2+
--> $DIR/issue-32963.rs:10:31
33
|
44
LL | size_of_copy::<dyn Misc + Copy>();
5-
| ---- ^^^^ additional non-auto trait
5+
| ---- ^^^^ additional non-auto or marker trait
66
| |
7-
| first non-auto trait
7+
| first non-auto or marker trait
88
|
99
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Misc + Copy {}`
1010
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
1111

12-
error[E0225]: only auto traits can be used as additional traits in a trait object
13-
--> $DIR/issue-32963.rs:8:31
12+
error[E0225]: only auto and marker traits can be used as additional traits in a trait object
13+
--> $DIR/issue-32963.rs:10:31
1414
|
1515
LL | size_of_copy::<dyn Misc + Copy>();
16-
| ---- ^^^^ additional non-auto trait
16+
| ---- ^^^^ additional non-auto or marker trait
1717
| |
18-
| first non-auto trait
18+
| first non-auto or marker trait
1919
|
2020
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Misc + Copy {}`
2121
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
2222

2323
error[E0277]: the trait bound `dyn Misc: Copy` is not satisfied
24-
--> $DIR/issue-32963.rs:8:5
24+
--> $DIR/issue-32963.rs:10:5
2525
|
2626
LL | size_of_copy::<dyn Misc + Copy>();
2727
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `dyn Misc`
2828
|
2929
note: required by a bound in `size_of_copy`
3030
--> $DIR/issue-32963.rs:5:20
3131
|
32-
LL | fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
32+
LL | fn size_of_copy<T: Copy + ?Sized>() -> usize {
3333
| ^^^^ required by this bound in `size_of_copy`
3434

3535
error: aborting due to 3 previous errors
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// check-pass
2+
3+
#![feature(marker_trait_attr)]
4+
5+
trait NonMarker {}
6+
#[marker]
7+
trait Marker {}
8+
9+
fn main() {
10+
let _: &(dyn NonMarker + Marker);
11+
}

src/test/ui/parser/trait-object-delimiters.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// edition:2018
22

33
fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type
4-
//~^ ERROR only auto traits can be used as additional traits in a trait object
4+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object
55

66
fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
77

@@ -12,6 +12,6 @@ fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found
1212
fn foo4(_: &dyn <Drop + AsRef<str>>) {} //~ ERROR expected identifier, found `<`
1313

1414
fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {} //~ ERROR invalid `dyn` keyword
15-
//~^ ERROR only auto traits can be used as additional traits in a trait object
15+
//~^ ERROR only auto and marker traits can be used as additional traits in a trait object
1616

1717
fn main() {}

0 commit comments

Comments
 (0)