Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some specialization tests #84496

Merged
merged 2 commits into from
Apr 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/test/ui/specialization/issue-33017.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Test to ensure that trait bounds are propertly
// checked on specializable associated types

#![allow(incomplete_features)]
#![feature(specialization)]

trait UncheckedCopy: Sized {
type Output: From<Self> + Copy + Into<Self>;
}

impl<T> UncheckedCopy for T {
default type Output = Self;
//~^ ERROR: the trait bound `T: Copy` is not satisfied
}

fn unchecked_copy<T: UncheckedCopy>(other: &T::Output) -> T {
(*other).into()
}

fn bug(origin: String) {
// Turn the String into it's Output type...
// Which we can just do by `.into()`, the assoc type states `From<Self>`.
let origin_output = origin.into();

// Make a copy of String::Output, which is a String...
let mut copy: String = unchecked_copy::<String>(&origin_output);

// Turn the Output type into a String again,
// Which we can just do by `.into()`, the assoc type states `Into<Self>`.
let mut origin: String = origin_output.into();

// assert both Strings use the same buffer.
assert_eq!(copy.as_ptr(), origin.as_ptr());

// Any use of the copy we made becomes invalid,
drop(origin);

// OH NO! UB UB UB UB!
copy.push_str(" world!");
println!("{}", copy);
}

fn main() {
bug(String::from("hello"));
}
17 changes: 17 additions & 0 deletions src/test/ui/specialization/issue-33017.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/issue-33017.rs:12:5
|
LL | type Output: From<Self> + Copy + Into<Self>;
| ---- required by this bound in `UncheckedCopy::Output`
...
LL | default type Output = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
LL | impl<T: std::marker::Copy> UncheckedCopy for T {
| ^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
19 changes: 19 additions & 0 deletions src/test/ui/specialization/issue-51892.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![allow(incomplete_features)]
#![feature(const_generics)]
#![feature(const_evaluatable_checked)]
#![feature(specialization)]

pub trait Trait {
type Type;
}

impl<T: ?Sized> Trait for T {
default type Type = [u8; 1];
}

impl<T: Trait> Trait for *const T {
type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()];
//~^ ERROR: unconstrained generic constant
}

fn main() {}
10 changes: 10 additions & 0 deletions src/test/ui/specialization/issue-51892.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: unconstrained generic constant
--> $DIR/issue-51892.rs:15:5
|
LL | type Type = [u8; std::mem::size_of::<<T as Trait>::Type>()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<<T as Trait>::Type>()]:`

error: aborting due to previous error