Skip to content

Commit ec61abf

Browse files
authored
Rollup merge of #84496 - marmeladema:specialization-test, r=JohnTitor
Add some specialization tests Closes #33017 Closes #51892 r? `@JohnTitor`
2 parents aae871d + 9b430df commit ec61abf

File tree

4 files changed

+91
-0
lines changed

4 files changed

+91
-0
lines changed
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Test to ensure that trait bounds are propertly
2+
// checked on specializable associated types
3+
4+
#![allow(incomplete_features)]
5+
#![feature(specialization)]
6+
7+
trait UncheckedCopy: Sized {
8+
type Output: From<Self> + Copy + Into<Self>;
9+
}
10+
11+
impl<T> UncheckedCopy for T {
12+
default type Output = Self;
13+
//~^ ERROR: the trait bound `T: Copy` is not satisfied
14+
}
15+
16+
fn unchecked_copy<T: UncheckedCopy>(other: &T::Output) -> T {
17+
(*other).into()
18+
}
19+
20+
fn bug(origin: String) {
21+
// Turn the String into it's Output type...
22+
// Which we can just do by `.into()`, the assoc type states `From<Self>`.
23+
let origin_output = origin.into();
24+
25+
// Make a copy of String::Output, which is a String...
26+
let mut copy: String = unchecked_copy::<String>(&origin_output);
27+
28+
// Turn the Output type into a String again,
29+
// Which we can just do by `.into()`, the assoc type states `Into<Self>`.
30+
let mut origin: String = origin_output.into();
31+
32+
// assert both Strings use the same buffer.
33+
assert_eq!(copy.as_ptr(), origin.as_ptr());
34+
35+
// Any use of the copy we made becomes invalid,
36+
drop(origin);
37+
38+
// OH NO! UB UB UB UB!
39+
copy.push_str(" world!");
40+
println!("{}", copy);
41+
}
42+
43+
fn main() {
44+
bug(String::from("hello"));
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0277]: the trait bound `T: Copy` is not satisfied
2+
--> $DIR/issue-33017.rs:12:5
3+
|
4+
LL | type Output: From<Self> + Copy + Into<Self>;
5+
| ---- required by this bound in `UncheckedCopy::Output`
6+
...
7+
LL | default type Output = Self;
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
9+
|
10+
help: consider restricting type parameter `T`
11+
|
12+
LL | impl<T: std::marker::Copy> UncheckedCopy for T {
13+
| ^^^^^^^^^^^^^^^^^^^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0277`.
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![allow(incomplete_features)]
2+
#![feature(const_generics)]
3+
#![feature(const_evaluatable_checked)]
4+
#![feature(specialization)]
5+
6+
pub trait Trait {
7+
type Type;
8+
}
9+
10+
impl<T: ?Sized> Trait for T {
11+
default type Type = [u8; 1];
12+
}
13+
14+
impl<T: Trait> Trait for *const T {
15+
type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()];
16+
//~^ ERROR: unconstrained generic constant
17+
}
18+
19+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: unconstrained generic constant
2+
--> $DIR/issue-51892.rs:15:5
3+
|
4+
LL | type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()];
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<<T as Trait>::Type>()]:`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)