summaryrefslogtreecommitdiffstats
path: root/src/test/ui/specialization/min_specialization
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/specialization/min_specialization')
-rw-r--r--src/test/ui/specialization/min_specialization/auxiliary/specialization-trait.rs6
-rw-r--r--src/test/ui/specialization/min_specialization/dyn-trait-assoc-types.rs32
-rw-r--r--src/test/ui/specialization/min_specialization/dyn-trait-assoc-types.stderr14
-rw-r--r--src/test/ui/specialization/min_specialization/impl-on-nonexisting.rs7
-rw-r--r--src/test/ui/specialization/min_specialization/impl-on-nonexisting.stderr9
-rw-r--r--src/test/ui/specialization/min_specialization/impl_specialization_trait.rs16
-rw-r--r--src/test/ui/specialization/min_specialization/impl_specialization_trait.stderr10
-rw-r--r--src/test/ui/specialization/min_specialization/implcit-well-formed-bounds.rs30
-rw-r--r--src/test/ui/specialization/min_specialization/issue-79224.rs24
-rw-r--r--src/test/ui/specialization/min_specialization/issue-79224.stderr27
-rw-r--r--src/test/ui/specialization/min_specialization/repeated_projection_type.rs24
-rw-r--r--src/test/ui/specialization/min_specialization/repeated_projection_type.stderr8
-rw-r--r--src/test/ui/specialization/min_specialization/repeating_lifetimes.rs19
-rw-r--r--src/test/ui/specialization/min_specialization/repeating_lifetimes.stderr8
-rw-r--r--src/test/ui/specialization/min_specialization/repeating_param.rs17
-rw-r--r--src/test/ui/specialization/min_specialization/repeating_param.stderr8
-rw-r--r--src/test/ui/specialization/min_specialization/spec-iter.rs20
-rw-r--r--src/test/ui/specialization/min_specialization/spec-marker-supertraits.rs29
-rw-r--r--src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr8
-rw-r--r--src/test/ui/specialization/min_specialization/spec-reference.rs19
-rw-r--r--src/test/ui/specialization/min_specialization/specialization_marker.rs17
-rw-r--r--src/test/ui/specialization/min_specialization/specialization_marker.stderr15
-rw-r--r--src/test/ui/specialization/min_specialization/specialization_super_trait.rs18
-rw-r--r--src/test/ui/specialization/min_specialization/specialization_super_trait.stderr8
-rw-r--r--src/test/ui/specialization/min_specialization/specialization_trait.rs26
-rw-r--r--src/test/ui/specialization/min_specialization/specialization_trait.stderr20
-rw-r--r--src/test/ui/specialization/min_specialization/specialize_on_marker.rs24
-rw-r--r--src/test/ui/specialization/min_specialization/specialize_on_spec_trait.rs27
-rw-r--r--src/test/ui/specialization/min_specialization/specialize_on_static.rs18
-rw-r--r--src/test/ui/specialization/min_specialization/specialize_on_static.stderr8
-rw-r--r--src/test/ui/specialization/min_specialization/specialize_on_trait.rs20
-rw-r--r--src/test/ui/specialization/min_specialization/specialize_on_trait.stderr8
32 files changed, 544 insertions, 0 deletions
diff --git a/src/test/ui/specialization/min_specialization/auxiliary/specialization-trait.rs b/src/test/ui/specialization/min_specialization/auxiliary/specialization-trait.rs
new file mode 100644
index 000000000..6ec0d261d
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/auxiliary/specialization-trait.rs
@@ -0,0 +1,6 @@
+#![feature(rustc_attrs)]
+
+#[rustc_specialization_trait]
+pub trait SpecTrait {
+ fn method(&self);
+}
diff --git a/src/test/ui/specialization/min_specialization/dyn-trait-assoc-types.rs b/src/test/ui/specialization/min_specialization/dyn-trait-assoc-types.rs
new file mode 100644
index 000000000..03cab00b0
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/dyn-trait-assoc-types.rs
@@ -0,0 +1,32 @@
+// Test that associated types in trait objects are not considered to be
+// constrained.
+
+#![feature(min_specialization)]
+
+trait Specializable {
+ fn f();
+}
+
+trait B<T> {
+ type Y;
+}
+
+trait C {
+ type Y;
+}
+
+impl<A: ?Sized> Specializable for A {
+ default fn f() {}
+}
+
+impl<'a, T> Specializable for dyn B<T, Y = T> + 'a {
+ //~^ ERROR specializing impl repeats parameter `T`
+ fn f() {}
+}
+
+impl<'a, T> Specializable for dyn C<Y = (T, T)> + 'a {
+ //~^ ERROR specializing impl repeats parameter `T`
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/dyn-trait-assoc-types.stderr b/src/test/ui/specialization/min_specialization/dyn-trait-assoc-types.stderr
new file mode 100644
index 000000000..db5558f16
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/dyn-trait-assoc-types.stderr
@@ -0,0 +1,14 @@
+error: specializing impl repeats parameter `T`
+ --> $DIR/dyn-trait-assoc-types.rs:22:1
+ |
+LL | impl<'a, T> Specializable for dyn B<T, Y = T> + 'a {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: specializing impl repeats parameter `T`
+ --> $DIR/dyn-trait-assoc-types.rs:27:1
+ |
+LL | impl<'a, T> Specializable for dyn C<Y = (T, T)> + 'a {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/specialization/min_specialization/impl-on-nonexisting.rs b/src/test/ui/specialization/min_specialization/impl-on-nonexisting.rs
new file mode 100644
index 000000000..77a64320d
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/impl-on-nonexisting.rs
@@ -0,0 +1,7 @@
+#![feature(min_specialization)]
+
+trait Trait {}
+impl Trait for NonExistent {}
+//~^ ERROR cannot find type `NonExistent` in this scope
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/impl-on-nonexisting.stderr b/src/test/ui/specialization/min_specialization/impl-on-nonexisting.stderr
new file mode 100644
index 000000000..b032ccbe5
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/impl-on-nonexisting.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `NonExistent` in this scope
+ --> $DIR/impl-on-nonexisting.rs:4:16
+ |
+LL | impl Trait for NonExistent {}
+ | ^^^^^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/specialization/min_specialization/impl_specialization_trait.rs b/src/test/ui/specialization/min_specialization/impl_specialization_trait.rs
new file mode 100644
index 000000000..723ed71c3
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/impl_specialization_trait.rs
@@ -0,0 +1,16 @@
+// Check that specialization traits can't be implemented without a feature.
+
+// gate-test-min_specialization
+
+// aux-build:specialization-trait.rs
+
+extern crate specialization_trait;
+
+struct A {}
+
+impl specialization_trait::SpecTrait for A {
+ //~^ ERROR implementing `rustc_specialization_trait` traits is unstable
+ fn method(&self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/impl_specialization_trait.stderr b/src/test/ui/specialization/min_specialization/impl_specialization_trait.stderr
new file mode 100644
index 000000000..934103d49
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/impl_specialization_trait.stderr
@@ -0,0 +1,10 @@
+error: implementing `rustc_specialization_trait` traits is unstable
+ --> $DIR/impl_specialization_trait.rs:11:1
+ |
+LL | impl specialization_trait::SpecTrait for A {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(min_specialization)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/specialization/min_specialization/implcit-well-formed-bounds.rs b/src/test/ui/specialization/min_specialization/implcit-well-formed-bounds.rs
new file mode 100644
index 000000000..98d7f9194
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/implcit-well-formed-bounds.rs
@@ -0,0 +1,30 @@
+// Test that specializing on the well-formed predicates of the trait and
+// self-type of an impl is allowed.
+
+// check-pass
+
+#![feature(min_specialization)]
+
+struct OrdOnly<T: Ord>(T);
+
+trait SpecTrait<U> {
+ fn f();
+}
+
+impl<T, U> SpecTrait<U> for T {
+ default fn f() {}
+}
+
+impl<T: Ord> SpecTrait<()> for OrdOnly<T> {
+ fn f() {}
+}
+
+impl<T: Ord> SpecTrait<OrdOnly<T>> for () {
+ fn f() {}
+}
+
+impl<T: Ord, U: Ord, V: Ord> SpecTrait<(OrdOnly<T>, OrdOnly<U>)> for &[OrdOnly<V>] {
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/issue-79224.rs b/src/test/ui/specialization/min_specialization/issue-79224.rs
new file mode 100644
index 000000000..408732fe9
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/issue-79224.rs
@@ -0,0 +1,24 @@
+#![feature(min_specialization)]
+use std::fmt::{self, Display};
+
+pub enum Cow<'a, B: ?Sized + 'a, O = <B as ToOwned>::Owned>
+where
+ B: ToOwned,
+{
+ Borrowed(&'a B),
+ Owned(O),
+}
+
+impl ToString for Cow<'_, str> {
+ fn to_string(&self) -> String {
+ String::new()
+ }
+}
+
+impl<B: ?Sized> Display for Cow<'_, B> { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
+ write!(f, "foo")
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr
new file mode 100644
index 000000000..cfb9007c7
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `B: Clone` is not satisfied
+ --> $DIR/issue-79224.rs:18:17
+ |
+LL | impl<B: ?Sized> Display for Cow<'_, B> {
+ | ^^^^^^^ the trait `Clone` is not implemented for `B`
+ |
+ = note: required because of the requirements on the impl of `ToOwned` for `B`
+help: consider further restricting this bound
+ |
+LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
+ | +++++++++++++++++++
+
+error[E0277]: the trait bound `B: Clone` is not satisfied
+ --> $DIR/issue-79224.rs:19:12
+ |
+LL | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ | ^^^^^ the trait `Clone` is not implemented for `B`
+ |
+ = note: required because of the requirements on the impl of `ToOwned` for `B`
+help: consider further restricting this bound
+ |
+LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
+ | +++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/specialization/min_specialization/repeated_projection_type.rs b/src/test/ui/specialization/min_specialization/repeated_projection_type.rs
new file mode 100644
index 000000000..f21f39f06
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/repeated_projection_type.rs
@@ -0,0 +1,24 @@
+// Test that projection bounds can't be specialized on.
+
+#![feature(min_specialization)]
+
+trait X {
+ fn f();
+}
+trait Id {
+ type This;
+}
+impl<T> Id for T {
+ type This = T;
+}
+
+impl<T: Id> X for T {
+ default fn f() {}
+}
+
+impl<I, V: Id<This = (I,)>> X for V {
+ //~^ ERROR cannot specialize on
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr
new file mode 100644
index 000000000..a751ba793
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr
@@ -0,0 +1,8 @@
+error: cannot specialize on associated type `<V as Id>::This == (I,)`
+ --> $DIR/repeated_projection_type.rs:19:15
+ |
+LL | impl<I, V: Id<This = (I,)>> X for V {
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/specialization/min_specialization/repeating_lifetimes.rs b/src/test/ui/specialization/min_specialization/repeating_lifetimes.rs
new file mode 100644
index 000000000..49bfacec0
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/repeating_lifetimes.rs
@@ -0,0 +1,19 @@
+// Test that directly specializing on repeated lifetime parameters is not
+// allowed.
+
+#![feature(min_specialization)]
+
+trait X {
+ fn f();
+}
+
+impl<T> X for T {
+ default fn f() {}
+}
+
+impl<'a> X for (&'a u8, &'a u8) {
+ //~^ ERROR specializing impl repeats parameter `'a`
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/repeating_lifetimes.stderr b/src/test/ui/specialization/min_specialization/repeating_lifetimes.stderr
new file mode 100644
index 000000000..16dccb10b
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/repeating_lifetimes.stderr
@@ -0,0 +1,8 @@
+error: specializing impl repeats parameter `'a`
+ --> $DIR/repeating_lifetimes.rs:14:1
+ |
+LL | impl<'a> X for (&'a u8, &'a u8) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/specialization/min_specialization/repeating_param.rs b/src/test/ui/specialization/min_specialization/repeating_param.rs
new file mode 100644
index 000000000..5a1c97fd3
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/repeating_param.rs
@@ -0,0 +1,17 @@
+// Test that specializing on two type parameters being equal is not allowed.
+
+#![feature(min_specialization)]
+
+trait X {
+ fn f();
+}
+
+impl<T> X for T {
+ default fn f() {}
+}
+impl<T> X for (T, T) {
+ //~^ ERROR specializing impl repeats parameter `T`
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/repeating_param.stderr b/src/test/ui/specialization/min_specialization/repeating_param.stderr
new file mode 100644
index 000000000..5e6adf723
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/repeating_param.stderr
@@ -0,0 +1,8 @@
+error: specializing impl repeats parameter `T`
+ --> $DIR/repeating_param.rs:12:1
+ |
+LL | impl<T> X for (T, T) {
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/specialization/min_specialization/spec-iter.rs b/src/test/ui/specialization/min_specialization/spec-iter.rs
new file mode 100644
index 000000000..e17e9dd5f
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/spec-iter.rs
@@ -0,0 +1,20 @@
+// Check that we can specialize on a concrete iterator type. This requires us
+// to consider which parameters in the parent impl are constrained.
+
+// check-pass
+
+#![feature(min_specialization)]
+
+trait SpecFromIter<T> {
+ fn f(&self);
+}
+
+impl<'a, T: 'a, I: Iterator<Item = &'a T>> SpecFromIter<T> for I {
+ default fn f(&self) {}
+}
+
+impl<'a, T> SpecFromIter<T> for std::slice::Iter<'a, T> {
+ fn f(&self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/spec-marker-supertraits.rs b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.rs
new file mode 100644
index 000000000..3bb2480e9
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.rs
@@ -0,0 +1,29 @@
+// Check that supertraits cannot be used to work around min_specialization
+// limitations.
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+trait HasMethod {
+ fn method(&self);
+}
+
+#[rustc_unsafe_specialization_marker]
+trait Marker: HasMethod {}
+
+trait Spec {
+ fn spec_me(&self);
+}
+
+impl<T> Spec for T {
+ default fn spec_me(&self) {}
+}
+
+impl<T: Marker> Spec for T {
+ //~^ ERROR cannot specialize on trait `HasMethod`
+ fn spec_me(&self) {
+ self.method();
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr
new file mode 100644
index 000000000..ba9d6bbe3
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr
@@ -0,0 +1,8 @@
+error: cannot specialize on trait `HasMethod`
+ --> $DIR/spec-marker-supertraits.rs:22:9
+ |
+LL | impl<T: Marker> Spec for T {
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/specialization/min_specialization/spec-reference.rs b/src/test/ui/specialization/min_specialization/spec-reference.rs
new file mode 100644
index 000000000..377889e2c
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/spec-reference.rs
@@ -0,0 +1,19 @@
+// Check that lifetime parameters are allowed in specializing impls.
+
+// check-pass
+
+#![feature(min_specialization)]
+
+trait MySpecTrait {
+ fn f();
+}
+
+impl<T> MySpecTrait for T {
+ default fn f() {}
+}
+
+impl<'a, T: ?Sized> MySpecTrait for &'a T {
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/specialization_marker.rs b/src/test/ui/specialization/min_specialization/specialization_marker.rs
new file mode 100644
index 000000000..93462d02e
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialization_marker.rs
@@ -0,0 +1,17 @@
+// Test that `rustc_unsafe_specialization_marker` is only allowed on marker traits.
+
+#![feature(rustc_attrs)]
+
+#[rustc_unsafe_specialization_marker]
+trait SpecMarker {
+ fn f();
+ //~^ ERROR marker traits
+}
+
+#[rustc_unsafe_specialization_marker]
+trait SpecMarker2 {
+ type X;
+ //~^ ERROR marker traits
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/specialization_marker.stderr b/src/test/ui/specialization/min_specialization/specialization_marker.stderr
new file mode 100644
index 000000000..b47c14f3c
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialization_marker.stderr
@@ -0,0 +1,15 @@
+error[E0714]: marker traits cannot have associated items
+ --> $DIR/specialization_marker.rs:7:5
+ |
+LL | fn f();
+ | ^^^^^^^
+
+error[E0714]: marker traits cannot have associated items
+ --> $DIR/specialization_marker.rs:13:5
+ |
+LL | type X;
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0714`.
diff --git a/src/test/ui/specialization/min_specialization/specialization_super_trait.rs b/src/test/ui/specialization/min_specialization/specialization_super_trait.rs
new file mode 100644
index 000000000..145f376ed
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialization_super_trait.rs
@@ -0,0 +1,18 @@
+// Test that supertraits can't be assumed in impls of
+// `rustc_specialization_trait`, as such impls would
+// allow specializing on the supertrait.
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+#[rustc_specialization_trait]
+trait SpecMarker: Default {
+ fn f();
+}
+
+impl<T: Default> SpecMarker for T {
+ //~^ ERROR cannot specialize
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/specialization_super_trait.stderr b/src/test/ui/specialization/min_specialization/specialization_super_trait.stderr
new file mode 100644
index 000000000..e93578662
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialization_super_trait.stderr
@@ -0,0 +1,8 @@
+error: cannot specialize on trait `Default`
+ --> $DIR/specialization_super_trait.rs:13:9
+ |
+LL | impl<T: Default> SpecMarker for T {
+ | ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/specialization/min_specialization/specialization_trait.rs b/src/test/ui/specialization/min_specialization/specialization_trait.rs
new file mode 100644
index 000000000..d597278d2
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialization_trait.rs
@@ -0,0 +1,26 @@
+// Test that `rustc_specialization_trait` requires always applicable impls.
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+#[rustc_specialization_trait]
+trait SpecMarker {
+ fn f();
+}
+
+impl SpecMarker for &'static u8 {
+ //~^ ERROR cannot specialize
+ fn f() {}
+}
+
+impl<T> SpecMarker for (T, T) {
+ //~^ ERROR specializing impl
+ fn f() {}
+}
+
+impl<T: Clone> SpecMarker for [T] {
+ //~^ ERROR cannot specialize
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/specialization_trait.stderr b/src/test/ui/specialization/min_specialization/specialization_trait.stderr
new file mode 100644
index 000000000..bc87ae0f8
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialization_trait.stderr
@@ -0,0 +1,20 @@
+error: cannot specialize on `'static` lifetime
+ --> $DIR/specialization_trait.rs:11:1
+ |
+LL | impl SpecMarker for &'static u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: specializing impl repeats parameter `T`
+ --> $DIR/specialization_trait.rs:16:1
+ |
+LL | impl<T> SpecMarker for (T, T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot specialize on trait `Clone`
+ --> $DIR/specialization_trait.rs:21:9
+ |
+LL | impl<T: Clone> SpecMarker for [T] {
+ | ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/specialization/min_specialization/specialize_on_marker.rs b/src/test/ui/specialization/min_specialization/specialize_on_marker.rs
new file mode 100644
index 000000000..4219bd13b
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialize_on_marker.rs
@@ -0,0 +1,24 @@
+// Test that specializing on a `rustc_unsafe_specialization_marker` trait is
+// allowed.
+
+// check-pass
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+#[rustc_unsafe_specialization_marker]
+trait SpecMarker {}
+
+trait X {
+ fn f();
+}
+
+impl<T> X for T {
+ default fn f() {}
+}
+
+impl<T: SpecMarker> X for T {
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/specialize_on_spec_trait.rs b/src/test/ui/specialization/min_specialization/specialize_on_spec_trait.rs
new file mode 100644
index 000000000..abbab5c23
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialize_on_spec_trait.rs
@@ -0,0 +1,27 @@
+// Test that specializing on a `rustc_specialization_trait` trait is allowed.
+
+// check-pass
+
+#![feature(min_specialization)]
+#![feature(rustc_attrs)]
+
+#[rustc_specialization_trait]
+trait SpecTrait {
+ fn g(&self);
+}
+
+trait X {
+ fn f(&self);
+}
+
+impl<T> X for T {
+ default fn f(&self) {}
+}
+
+impl<T: SpecTrait> X for T {
+ fn f(&self) {
+ self.g();
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/specialize_on_static.rs b/src/test/ui/specialization/min_specialization/specialize_on_static.rs
new file mode 100644
index 000000000..dd1b05401
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialize_on_static.rs
@@ -0,0 +1,18 @@
+// Test that directly specializing on `'static` is not allowed.
+
+#![feature(min_specialization)]
+
+trait X {
+ fn f();
+}
+
+impl<T> X for &'_ T {
+ default fn f() {}
+}
+
+impl X for &'static u8 {
+ //~^ ERROR cannot specialize on `'static` lifetime
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/specialize_on_static.stderr b/src/test/ui/specialization/min_specialization/specialize_on_static.stderr
new file mode 100644
index 000000000..9a16798f1
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialize_on_static.stderr
@@ -0,0 +1,8 @@
+error: cannot specialize on `'static` lifetime
+ --> $DIR/specialize_on_static.rs:13:1
+ |
+LL | impl X for &'static u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/specialization/min_specialization/specialize_on_trait.rs b/src/test/ui/specialization/min_specialization/specialize_on_trait.rs
new file mode 100644
index 000000000..0588442c3
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialize_on_trait.rs
@@ -0,0 +1,20 @@
+// Test that specializing on a trait is not allowed in general.
+
+#![feature(min_specialization)]
+
+trait SpecMarker {}
+
+trait X {
+ fn f();
+}
+
+impl<T> X for T {
+ default fn f() {}
+}
+
+impl<T: SpecMarker> X for T {
+ //~^ ERROR cannot specialize on trait `SpecMarker`
+ fn f() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/specialize_on_trait.stderr b/src/test/ui/specialization/min_specialization/specialize_on_trait.stderr
new file mode 100644
index 000000000..7b79c7eb4
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/specialize_on_trait.stderr
@@ -0,0 +1,8 @@
+error: cannot specialize on trait `SpecMarker`
+ --> $DIR/specialize_on_trait.rs:15:9
+ |
+LL | impl<T: SpecMarker> X for T {
+ | ^^^^^^^^^^
+
+error: aborting due to previous error
+