summaryrefslogtreecommitdiffstats
path: root/tests/ui/specialization
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/specialization')
-rw-r--r--tests/ui/specialization/README-rpass.md37
-rw-r--r--tests/ui/specialization/README.md21
-rw-r--r--tests/ui/specialization/assoc-ty-graph-cycle.rs25
-rw-r--r--tests/ui/specialization/assoc-ty-graph-cycle.stderr12
-rw-r--r--tests/ui/specialization/auxiliary/cross_crates_defaults.rs40
-rw-r--r--tests/ui/specialization/auxiliary/go_trait.rs43
-rw-r--r--tests/ui/specialization/auxiliary/specialization_cross_crate.rs72
-rw-r--r--tests/ui/specialization/const_trait_impl.rs55
-rw-r--r--tests/ui/specialization/cross-crate-defaults.rs41
-rw-r--r--tests/ui/specialization/cross-crate-defaults.stderr12
-rw-r--r--tests/ui/specialization/default-associated-type-bound-1.rs24
-rw-r--r--tests/ui/specialization/default-associated-type-bound-1.stderr26
-rw-r--r--tests/ui/specialization/default-associated-type-bound-2.rs22
-rw-r--r--tests/ui/specialization/default-associated-type-bound-2.stderr30
-rw-r--r--tests/ui/specialization/default-generic-associated-type-bound.rs25
-rw-r--r--tests/ui/specialization/default-generic-associated-type-bound.stderr30
-rw-r--r--tests/ui/specialization/defaultimpl/allowed-cross-crate.rs26
-rw-r--r--tests/ui/specialization/defaultimpl/allowed-cross-crate.stderr12
-rw-r--r--tests/ui/specialization/defaultimpl/auxiliary/go_trait.rs43
-rw-r--r--tests/ui/specialization/defaultimpl/out-of-order.rs19
-rw-r--r--tests/ui/specialization/defaultimpl/out-of-order.stderr12
-rw-r--r--tests/ui/specialization/defaultimpl/overlap-projection.rs25
-rw-r--r--tests/ui/specialization/defaultimpl/overlap-projection.stderr12
-rw-r--r--tests/ui/specialization/defaultimpl/projection.rs42
-rw-r--r--tests/ui/specialization/defaultimpl/projection.stderr12
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-feature-gate-default.rs11
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr14
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-no-default.rs77
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-no-default.stderr68
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs34
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr12
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs23
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr22
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs24
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr44
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-wfcheck.rs10
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-wfcheck.stderr29
-rw-r--r--tests/ui/specialization/defaultimpl/validation.rs16
-rw-r--r--tests/ui/specialization/defaultimpl/validation.stderr51
-rw-r--r--tests/ui/specialization/issue-33017.rs45
-rw-r--r--tests/ui/specialization/issue-33017.stderr19
-rw-r--r--tests/ui/specialization/issue-35376.rs43
-rw-r--r--tests/ui/specialization/issue-35376.stderr12
-rw-r--r--tests/ui/specialization/issue-36804.rs35
-rw-r--r--tests/ui/specialization/issue-36804.stderr12
-rw-r--r--tests/ui/specialization/issue-38091-2.rs28
-rw-r--r--tests/ui/specialization/issue-38091-2.stderr24
-rw-r--r--tests/ui/specialization/issue-38091.rs24
-rw-r--r--tests/ui/specialization/issue-38091.stderr25
-rw-r--r--tests/ui/specialization/issue-39448.rs50
-rw-r--r--tests/ui/specialization/issue-39448.stderr35
-rw-r--r--tests/ui/specialization/issue-39618.rs27
-rw-r--r--tests/ui/specialization/issue-39618.stderr12
-rw-r--r--tests/ui/specialization/issue-43037.current.stderr12
-rw-r--r--tests/ui/specialization/issue-43037.negative.stderr12
-rw-r--r--tests/ui/specialization/issue-43037.rs22
-rw-r--r--tests/ui/specialization/issue-44861.rs40
-rw-r--r--tests/ui/specialization/issue-44861.stderr15
-rw-r--r--tests/ui/specialization/issue-45814.current.stderr14
-rw-r--r--tests/ui/specialization/issue-45814.negative.stderr14
-rw-r--r--tests/ui/specialization/issue-45814.rs13
-rw-r--r--tests/ui/specialization/issue-50452-fail.rs21
-rw-r--r--tests/ui/specialization/issue-50452-fail.stderr24
-rw-r--r--tests/ui/specialization/issue-50452.rs19
-rw-r--r--tests/ui/specialization/issue-50452.stderr12
-rw-r--r--tests/ui/specialization/issue-51892.rs18
-rw-r--r--tests/ui/specialization/issue-51892.stderr10
-rw-r--r--tests/ui/specialization/issue-52050.rs32
-rw-r--r--tests/ui/specialization/issue-52050.stderr24
-rw-r--r--tests/ui/specialization/issue-59435.rs17
-rw-r--r--tests/ui/specialization/issue-59435.stderr19
-rw-r--r--tests/ui/specialization/issue-63716-parse-async.rs14
-rw-r--r--tests/ui/specialization/issue-63716-parse-async.stderr12
-rw-r--r--tests/ui/specialization/issue-68830-spurious-diagnostics.rs23
-rw-r--r--tests/ui/specialization/issue-68830-spurious-diagnostics.stderr9
-rw-r--r--tests/ui/specialization/issue-70442.rs23
-rw-r--r--tests/ui/specialization/issue-70442.stderr12
-rw-r--r--tests/ui/specialization/min_specialization/auxiliary/specialization-trait.rs6
-rw-r--r--tests/ui/specialization/min_specialization/dyn-trait-assoc-types.rs32
-rw-r--r--tests/ui/specialization/min_specialization/dyn-trait-assoc-types.stderr14
-rw-r--r--tests/ui/specialization/min_specialization/impl-on-nonexisting.rs7
-rw-r--r--tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr9
-rw-r--r--tests/ui/specialization/min_specialization/impl_specialization_trait.rs16
-rw-r--r--tests/ui/specialization/min_specialization/impl_specialization_trait.stderr10
-rw-r--r--tests/ui/specialization/min_specialization/implcit-well-formed-bounds.rs30
-rw-r--r--tests/ui/specialization/min_specialization/issue-79224.rs26
-rw-r--r--tests/ui/specialization/min_specialization/issue-79224.stderr27
-rw-r--r--tests/ui/specialization/min_specialization/repeated_projection_type.rs24
-rw-r--r--tests/ui/specialization/min_specialization/repeated_projection_type.stderr8
-rw-r--r--tests/ui/specialization/min_specialization/repeating_lifetimes.rs19
-rw-r--r--tests/ui/specialization/min_specialization/repeating_lifetimes.stderr8
-rw-r--r--tests/ui/specialization/min_specialization/repeating_param.rs17
-rw-r--r--tests/ui/specialization/min_specialization/repeating_param.stderr8
-rw-r--r--tests/ui/specialization/min_specialization/spec-iter.rs20
-rw-r--r--tests/ui/specialization/min_specialization/spec-marker-supertraits.rs29
-rw-r--r--tests/ui/specialization/min_specialization/spec-marker-supertraits.stderr8
-rw-r--r--tests/ui/specialization/min_specialization/spec-reference.rs19
-rw-r--r--tests/ui/specialization/min_specialization/specialization_marker.rs17
-rw-r--r--tests/ui/specialization/min_specialization/specialization_marker.stderr15
-rw-r--r--tests/ui/specialization/min_specialization/specialization_super_trait.rs18
-rw-r--r--tests/ui/specialization/min_specialization/specialization_super_trait.stderr8
-rw-r--r--tests/ui/specialization/min_specialization/specialization_trait.rs26
-rw-r--r--tests/ui/specialization/min_specialization/specialization_trait.stderr20
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_marker.rs24
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_spec_trait.rs27
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_static.rs18
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_static.stderr8
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_trait.rs20
-rw-r--r--tests/ui/specialization/min_specialization/specialize_on_trait.stderr8
-rw-r--r--tests/ui/specialization/non-defaulted-item-fail.rs54
-rw-r--r--tests/ui/specialization/non-defaulted-item-fail.stderr79
-rw-r--r--tests/ui/specialization/soundness/partial_eq_range_inclusive.rs35
-rw-r--r--tests/ui/specialization/soundness/partial_ord_slice.rs42
-rw-r--r--tests/ui/specialization/specialization-allowed-cross-crate.rs26
-rw-r--r--tests/ui/specialization/specialization-allowed-cross-crate.stderr12
-rw-r--r--tests/ui/specialization/specialization-assoc-fns.rs29
-rw-r--r--tests/ui/specialization/specialization-assoc-fns.stderr12
-rw-r--r--tests/ui/specialization/specialization-basics.rs98
-rw-r--r--tests/ui/specialization/specialization-basics.stderr12
-rw-r--r--tests/ui/specialization/specialization-cross-crate-no-gate.rs21
-rw-r--r--tests/ui/specialization/specialization-cross-crate.rs50
-rw-r--r--tests/ui/specialization/specialization-cross-crate.stderr12
-rw-r--r--tests/ui/specialization/specialization-default-methods.rs87
-rw-r--r--tests/ui/specialization/specialization-default-methods.stderr12
-rw-r--r--tests/ui/specialization/specialization-default-projection.rs36
-rw-r--r--tests/ui/specialization/specialization-default-projection.stderr43
-rw-r--r--tests/ui/specialization/specialization-default-types.rs35
-rw-r--r--tests/ui/specialization/specialization-default-types.stderr39
-rw-r--r--tests/ui/specialization/specialization-feature-gate-default.rs13
-rw-r--r--tests/ui/specialization/specialization-feature-gate-default.stderr12
-rw-r--r--tests/ui/specialization/specialization-feature-gate-overlap.rs17
-rw-r--r--tests/ui/specialization/specialization-feature-gate-overlap.stderr12
-rw-r--r--tests/ui/specialization/specialization-no-default.rs77
-rw-r--r--tests/ui/specialization/specialization-no-default.stderr68
-rw-r--r--tests/ui/specialization/specialization-on-projection.rs24
-rw-r--r--tests/ui/specialization/specialization-on-projection.stderr12
-rw-r--r--tests/ui/specialization/specialization-out-of-order.rs19
-rw-r--r--tests/ui/specialization/specialization-out-of-order.stderr12
-rw-r--r--tests/ui/specialization/specialization-overlap-hygiene.rs23
-rw-r--r--tests/ui/specialization/specialization-overlap-hygiene.stderr12
-rw-r--r--tests/ui/specialization/specialization-overlap-negative.rs11
-rw-r--r--tests/ui/specialization/specialization-overlap-negative.stderr21
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.rs25
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.stderr12
-rw-r--r--tests/ui/specialization/specialization-overlap.rs19
-rw-r--r--tests/ui/specialization/specialization-overlap.stderr45
-rw-r--r--tests/ui/specialization/specialization-polarity.rs17
-rw-r--r--tests/ui/specialization/specialization-polarity.stderr29
-rw-r--r--tests/ui/specialization/specialization-projection-alias.rs26
-rw-r--r--tests/ui/specialization/specialization-projection-alias.stderr12
-rw-r--r--tests/ui/specialization/specialization-projection.rs42
-rw-r--r--tests/ui/specialization/specialization-projection.stderr12
-rw-r--r--tests/ui/specialization/specialization-supertraits.rs17
-rw-r--r--tests/ui/specialization/specialization-supertraits.stderr12
-rw-r--r--tests/ui/specialization/specialization-translate-projections-with-lifetimes.rs33
-rw-r--r--tests/ui/specialization/specialization-translate-projections-with-lifetimes.stderr12
-rw-r--r--tests/ui/specialization/specialization-translate-projections-with-params.rs32
-rw-r--r--tests/ui/specialization/specialization-translate-projections-with-params.stderr12
-rw-r--r--tests/ui/specialization/specialization-translate-projections.rs33
-rw-r--r--tests/ui/specialization/specialization-translate-projections.stderr12
-rw-r--r--tests/ui/specialization/transmute-specialization.rs15
-rw-r--r--tests/ui/specialization/transmute-specialization.stderr12
162 files changed, 4017 insertions, 0 deletions
diff --git a/tests/ui/specialization/README-rpass.md b/tests/ui/specialization/README-rpass.md
new file mode 100644
index 000000000..c1486ce1e
--- /dev/null
+++ b/tests/ui/specialization/README-rpass.md
@@ -0,0 +1,37 @@
+Tests that specialization is working correctly:
+
+- Dispatch
+ - [On methods](specialization-basics.rs), includes:
+ - Specialization via adding a trait bound
+ - Including both remote and local traits
+ - Specialization via pure structure (e.g. `(T, U)` vs `(T, T)`)
+ - Specialization via concrete types vs unknown types
+ - In top level of the trait reference
+ - Embedded within another type (`Vec<T>` vs `Vec<i32>`)
+ - [Specialization based on super trait relationships](specialization-supertraits.rs)
+ - [On assoc fns](specialization-assoc-fns.rs)
+ - [Ensure that impl order doesn't matter](specialization-out-of-order.rs)
+
+- Item inheritance
+ - [Correct default cascading for methods](specialization-default-methods.rs)
+ - Inheritance works across impls with varying generics
+ - [With projections](specialization-translate-projections.rs)
+ - [With projections that involve input types](specialization-translate-projections-with-params.rs)
+
+- Normalization issues
+ - [Non-default assoc types can be projected](specialization-projection.rs)
+ - Including non-specialized cases
+ - Including specialized cases
+ - [Specialized Impls can happen on projections](specialization-on-projection.rs)
+ - [Projections and aliases play well together](specialization-projection-alias.rs)
+ - [Projections involving specialization allowed in the trait ref for impls, and overlap can still be determined](specialization-overlap-projection.rs)
+ - Only works for the simple case where the most specialized impl directly
+ provides a non-`default` associated type
+
+- Across crates
+ - [For traits defined in upstream crate](specialization-allowed-cross-crate.rs)
+ - [Full method dispatch tests, drawing from upstream crate](specialization-cross-crate.rs)
+ - Including *additional* local specializations
+ - [Full method dispatch tests, *without* turning on specialization in local crate](specialization-cross-crate-no-gate.rs)
+ - [Test that defaults cascade correctly from upstream crates](specialization-cross-crate-defaults.rs)
+ - Including *additional* local use of defaults
diff --git a/tests/ui/specialization/README.md b/tests/ui/specialization/README.md
new file mode 100644
index 000000000..f2b4bf946
--- /dev/null
+++ b/tests/ui/specialization/README.md
@@ -0,0 +1,21 @@
+This directory contains the test for incorrect usage of specialization that
+should lead to compile failure. Those tests break down into a few categories:
+
+- Feature gating
+ - [On use of the `default` keyword](specialization-feature-gate-default.rs)
+ - [On overlapping impls](specialization-feature-gate-overlap.rs)
+
+- Overlap checking with specialization enabled
+ - [Basic overlap scenarios](specialization-overlap.rs)
+ - Includes purely structural overlap
+ - Includes purely trait-based overlap
+ - Includes mix
+ - [Overlap with differing polarity](specialization-overlap-negative.rs)
+
+- [Attempt to specialize without using `default`](specialization-no-default.rs)
+
+- [Attempt to change impl polarity in a specialization](specialization-polarity.rs)
+
+- Attempt to rely on projection of a `default` type
+ - [Rely on it externally in both generic and monomorphic contexts](specialization-default-projection.rs)
+ - [Rely on it both within an impl and outside it](specialization-default-types.rs)
diff --git a/tests/ui/specialization/assoc-ty-graph-cycle.rs b/tests/ui/specialization/assoc-ty-graph-cycle.rs
new file mode 100644
index 000000000..fc39b553a
--- /dev/null
+++ b/tests/ui/specialization/assoc-ty-graph-cycle.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+// Make sure we don't crash with a cycle error during coherence.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Trait<T> {
+ type Assoc;
+}
+
+impl<T> Trait<T> for Vec<T> {
+ default type Assoc = ();
+}
+
+impl Trait<u8> for Vec<u8> {
+ type Assoc = u8;
+}
+
+impl<T> Trait<T> for String {
+ type Assoc = ();
+}
+
+impl Trait<<Vec<u8> as Trait<u8>>::Assoc> for String {}
+
+fn main() {}
diff --git a/tests/ui/specialization/assoc-ty-graph-cycle.stderr b/tests/ui/specialization/assoc-ty-graph-cycle.stderr
new file mode 100644
index 000000000..f5529c24d
--- /dev/null
+++ b/tests/ui/specialization/assoc-ty-graph-cycle.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/assoc-ty-graph-cycle.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/auxiliary/cross_crates_defaults.rs b/tests/ui/specialization/auxiliary/cross_crates_defaults.rs
new file mode 100644
index 000000000..1e5555355
--- /dev/null
+++ b/tests/ui/specialization/auxiliary/cross_crates_defaults.rs
@@ -0,0 +1,40 @@
+#![feature(specialization)]
+
+// First, test only use of explicit `default` items:
+
+pub trait Foo {
+ fn foo(&self) -> bool;
+}
+
+impl<T> Foo for T {
+ default fn foo(&self) -> bool { false }
+}
+
+impl Foo for i32 {}
+
+impl Foo for i64 {
+ fn foo(&self) -> bool { true }
+}
+
+// Next, test mixture of explicit `default` and provided methods:
+
+pub trait Bar {
+ fn bar(&self) -> i32 { 0 }
+}
+
+impl<T> Bar for T {
+ default fn bar(&self) -> i32 { 0 }
+}
+
+impl Bar for i32 {
+ fn bar(&self) -> i32 { 1 }
+}
+impl<'a> Bar for &'a str {}
+
+impl<T> Bar for Vec<T> {
+ default fn bar(&self) -> i32 { 2 }
+}
+impl Bar for Vec<i32> {}
+impl Bar for Vec<i64> {
+ fn bar(&self) -> i32 { 3 }
+}
diff --git a/tests/ui/specialization/auxiliary/go_trait.rs b/tests/ui/specialization/auxiliary/go_trait.rs
new file mode 100644
index 000000000..aa0ec2289
--- /dev/null
+++ b/tests/ui/specialization/auxiliary/go_trait.rs
@@ -0,0 +1,43 @@
+#![feature(specialization)]
+
+// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy.
+
+pub trait Go {
+ fn go(&self, arg: isize);
+}
+
+pub fn go<G:Go>(this: &G, arg: isize) {
+ this.go(arg)
+}
+
+pub trait GoMut {
+ fn go_mut(&mut self, arg: isize);
+}
+
+pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) {
+ this.go_mut(arg)
+}
+
+pub trait GoOnce {
+ fn go_once(self, arg: isize);
+}
+
+pub fn go_once<G:GoOnce>(this: G, arg: isize) {
+ this.go_once(arg)
+}
+
+impl<G> GoMut for G
+ where G : Go
+{
+ default fn go_mut(&mut self, arg: isize) {
+ go(&*self, arg)
+ }
+}
+
+impl<G> GoOnce for G
+ where G : GoMut
+{
+ default fn go_once(mut self, arg: isize) {
+ go_mut(&mut self, arg)
+ }
+}
diff --git a/tests/ui/specialization/auxiliary/specialization_cross_crate.rs b/tests/ui/specialization/auxiliary/specialization_cross_crate.rs
new file mode 100644
index 000000000..8caa8524f
--- /dev/null
+++ b/tests/ui/specialization/auxiliary/specialization_cross_crate.rs
@@ -0,0 +1,72 @@
+#![feature(specialization)]
+
+pub trait Foo {
+ fn foo(&self) -> &'static str;
+}
+
+impl<T> Foo for T {
+ default fn foo(&self) -> &'static str {
+ "generic"
+ }
+}
+
+impl<T: Clone> Foo for T {
+ default fn foo(&self) -> &'static str {
+ "generic Clone"
+ }
+}
+
+impl<T, U> Foo for (T, U) where T: Clone, U: Clone {
+ default fn foo(&self) -> &'static str {
+ "generic pair"
+ }
+}
+
+impl<T: Clone> Foo for (T, T) {
+ default fn foo(&self) -> &'static str {
+ "generic uniform pair"
+ }
+}
+
+impl Foo for (u8, u32) {
+ default fn foo(&self) -> &'static str {
+ "(u8, u32)"
+ }
+}
+
+impl Foo for (u8, u8) {
+ default fn foo(&self) -> &'static str {
+ "(u8, u8)"
+ }
+}
+
+impl<T: Clone> Foo for Vec<T> {
+ default fn foo(&self) -> &'static str {
+ "generic Vec"
+ }
+}
+
+impl Foo for Vec<i32> {
+ fn foo(&self) -> &'static str {
+ "Vec<i32>"
+ }
+}
+
+impl Foo for String {
+ fn foo(&self) -> &'static str {
+ "String"
+ }
+}
+
+impl Foo for i32 {
+ fn foo(&self) -> &'static str {
+ "i32"
+ }
+}
+
+pub trait MyMarker {}
+impl<T: Clone + MyMarker> Foo for T {
+ default fn foo(&self) -> &'static str {
+ "generic Clone + MyMarker"
+ }
+}
diff --git a/tests/ui/specialization/const_trait_impl.rs b/tests/ui/specialization/const_trait_impl.rs
new file mode 100644
index 000000000..05ba4c8d4
--- /dev/null
+++ b/tests/ui/specialization/const_trait_impl.rs
@@ -0,0 +1,55 @@
+// check-pass
+#![feature(const_trait_impl, min_specialization, rustc_attrs)]
+
+#[rustc_specialization_trait]
+#[const_trait]
+pub unsafe trait Sup {
+ fn foo() -> u32;
+}
+
+#[rustc_specialization_trait]
+#[const_trait]
+pub unsafe trait Sub: ~const Sup {}
+
+unsafe impl const Sup for u8 {
+ default fn foo() -> u32 {
+ 1
+ }
+}
+
+unsafe impl const Sup for () {
+ fn foo() -> u32 {
+ 42
+ }
+}
+
+unsafe impl const Sub for () {}
+
+#[const_trait]
+pub trait A {
+ fn a() -> u32;
+}
+
+impl<T: ~const Default> const A for T {
+ default fn a() -> u32 {
+ 2
+ }
+}
+
+impl<T: ~const Default + ~const Sup> const A for T {
+ default fn a() -> u32 {
+ 3
+ }
+}
+
+impl<T: ~const Default + ~const Sub> const A for T {
+ fn a() -> u32 {
+ T::foo()
+ }
+}
+
+const _: () = assert!(<()>::a() == 42);
+const _: () = assert!(<u8>::a() == 3);
+const _: () = assert!(<u16>::a() == 2);
+
+fn main() {}
diff --git a/tests/ui/specialization/cross-crate-defaults.rs b/tests/ui/specialization/cross-crate-defaults.rs
new file mode 100644
index 000000000..fc28d0c81
--- /dev/null
+++ b/tests/ui/specialization/cross-crate-defaults.rs
@@ -0,0 +1,41 @@
+// run-pass
+
+// aux-build:cross_crates_defaults.rs
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+extern crate cross_crates_defaults;
+
+use cross_crates_defaults::*;
+
+struct LocalDefault;
+struct LocalOverride;
+
+impl Foo for LocalDefault {}
+
+impl Foo for LocalOverride {
+ fn foo(&self) -> bool { true }
+}
+
+fn test_foo() {
+ assert!(!0i8.foo());
+ assert!(!0i32.foo());
+ assert!(0i64.foo());
+
+ assert!(!LocalDefault.foo());
+ assert!(LocalOverride.foo());
+}
+
+fn test_bar() {
+ assert!(0u8.bar() == 0);
+ assert!(0i32.bar() == 1);
+ assert!("hello".bar() == 0);
+ assert!(vec![()].bar() == 2);
+ assert!(vec![0i32].bar() == 2);
+ assert!(vec![0i64].bar() == 3);
+}
+
+fn main() {
+ test_foo();
+ test_bar();
+}
diff --git a/tests/ui/specialization/cross-crate-defaults.stderr b/tests/ui/specialization/cross-crate-defaults.stderr
new file mode 100644
index 000000000..ee5c77a76
--- /dev/null
+++ b/tests/ui/specialization/cross-crate-defaults.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/cross-crate-defaults.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/default-associated-type-bound-1.rs b/tests/ui/specialization/default-associated-type-bound-1.rs
new file mode 100644
index 000000000..c043114b5
--- /dev/null
+++ b/tests/ui/specialization/default-associated-type-bound-1.rs
@@ -0,0 +1,24 @@
+// Check that we check that default associated types satisfy the required
+// bounds on them.
+
+#![feature(specialization)]
+//~^ WARNING `specialization` is incomplete
+
+trait X {
+ type U: Clone;
+ fn unsafe_clone(&self, x: Option<&Self::U>) {
+ x.cloned();
+ }
+}
+
+// We cannot normalize `<T as X>::U` to `str` here, because the default could
+// be overridden. The error here must therefore be found by a method other than
+// normalization.
+impl<T> X for T {
+ default type U = str;
+ //~^ ERROR the trait bound `str: Clone` is not satisfied
+}
+
+pub fn main() {
+ 1.unsafe_clone(None);
+}
diff --git a/tests/ui/specialization/default-associated-type-bound-1.stderr b/tests/ui/specialization/default-associated-type-bound-1.stderr
new file mode 100644
index 000000000..e498187c0
--- /dev/null
+++ b/tests/ui/specialization/default-associated-type-bound-1.stderr
@@ -0,0 +1,26 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/default-associated-type-bound-1.rs:4:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/default-associated-type-bound-1.rs:18:22
+ |
+LL | default type U = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X::U`
+ --> $DIR/default-associated-type-bound-1.rs:8:13
+ |
+LL | type U: Clone;
+ | ^^^^^ required by this bound in `X::U`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/default-associated-type-bound-2.rs b/tests/ui/specialization/default-associated-type-bound-2.rs
new file mode 100644
index 000000000..0a21b1f09
--- /dev/null
+++ b/tests/ui/specialization/default-associated-type-bound-2.rs
@@ -0,0 +1,22 @@
+// Check that generic predicates are also checked for default associated types.
+#![feature(specialization)]
+//~^ WARNING `specialization` is incomplete
+
+trait X<T> {
+ type U: PartialEq<T>;
+ fn unsafe_compare(x: Option<Self::U>, y: Option<T>) {
+ match (x, y) {
+ (Some(a), Some(b)) => a == b,
+ _ => false,
+ };
+ }
+}
+
+impl<B: 'static, T> X<B> for T {
+ default type U = &'static B;
+ //~^ ERROR can't compare `&'static B` with `B`
+}
+
+pub fn main() {
+ <i32 as X<i32>>::unsafe_compare(None, None);
+}
diff --git a/tests/ui/specialization/default-associated-type-bound-2.stderr b/tests/ui/specialization/default-associated-type-bound-2.stderr
new file mode 100644
index 000000000..4dbe251ed
--- /dev/null
+++ b/tests/ui/specialization/default-associated-type-bound-2.stderr
@@ -0,0 +1,30 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/default-associated-type-bound-2.rs:2:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: can't compare `&'static B` with `B`
+ --> $DIR/default-associated-type-bound-2.rs:16:22
+ |
+LL | default type U = &'static B;
+ | ^^^^^^^^^^ no implementation for `&'static B == B`
+ |
+ = help: the trait `PartialEq<B>` is not implemented for `&'static B`
+note: required by a bound in `X::U`
+ --> $DIR/default-associated-type-bound-2.rs:6:13
+ |
+LL | type U: PartialEq<T>;
+ | ^^^^^^^^^^^^ required by this bound in `X::U`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+ |
+LL | impl<B: 'static, T> X<B> for T where &'static B: PartialEq<B> {
+ | ++++++++++++++++++++++++++++++
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/default-generic-associated-type-bound.rs b/tests/ui/specialization/default-generic-associated-type-bound.rs
new file mode 100644
index 000000000..31a0685d0
--- /dev/null
+++ b/tests/ui/specialization/default-generic-associated-type-bound.rs
@@ -0,0 +1,25 @@
+// Check that default generics associated types are validated.
+
+#![feature(specialization)]
+//~^ WARNING `specialization` is incomplete
+
+trait X {
+ type U<'a>: PartialEq<&'a Self> where Self: 'a;
+ fn unsafe_compare<'b>(x: Option<Self::U<'b>>, y: Option<&'b Self>) {
+ match (x, y) {
+ (Some(a), Some(b)) => a == b,
+ _ => false,
+ };
+ }
+}
+
+impl<T: 'static> X for T {
+ default type U<'a> = &'a T;
+ //~^ ERROR can't compare `T` with `T`
+}
+
+struct NotComparable;
+
+pub fn main() {
+ <NotComparable as X>::unsafe_compare(None, None);
+}
diff --git a/tests/ui/specialization/default-generic-associated-type-bound.stderr b/tests/ui/specialization/default-generic-associated-type-bound.stderr
new file mode 100644
index 000000000..c597eed37
--- /dev/null
+++ b/tests/ui/specialization/default-generic-associated-type-bound.stderr
@@ -0,0 +1,30 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/default-generic-associated-type-bound.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: can't compare `T` with `T`
+ --> $DIR/default-generic-associated-type-bound.rs:17:26
+ |
+LL | default type U<'a> = &'a T;
+ | ^^^^^ no implementation for `T == T`
+ |
+ = note: required for `&'a T` to implement `PartialEq`
+note: required by a bound in `X::U`
+ --> $DIR/default-generic-associated-type-bound.rs:7:17
+ |
+LL | type U<'a>: PartialEq<&'a Self> where Self: 'a;
+ | ^^^^^^^^^^^^^^^^^^^ required by this bound in `X::U`
+help: consider further restricting this bound
+ |
+LL | impl<T: 'static + std::cmp::PartialEq> X for T {
+ | +++++++++++++++++++++
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/defaultimpl/allowed-cross-crate.rs b/tests/ui/specialization/defaultimpl/allowed-cross-crate.rs
new file mode 100644
index 000000000..5d67160eb
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/allowed-cross-crate.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_imports)]
+
+// aux-build:go_trait.rs
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+extern crate go_trait;
+
+use go_trait::{Go,GoMut};
+use std::fmt::Debug;
+use std::default::Default;
+
+struct MyThingy;
+
+impl Go for MyThingy {
+ fn go(&self, arg: isize) { }
+}
+
+impl GoMut for MyThingy {
+ fn go_mut(&mut self, arg: isize) { }
+}
+
+fn main() { }
diff --git a/tests/ui/specialization/defaultimpl/allowed-cross-crate.stderr b/tests/ui/specialization/defaultimpl/allowed-cross-crate.stderr
new file mode 100644
index 000000000..02f13d461
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/allowed-cross-crate.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/allowed-cross-crate.rs:8:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/defaultimpl/auxiliary/go_trait.rs b/tests/ui/specialization/defaultimpl/auxiliary/go_trait.rs
new file mode 100644
index 000000000..c065593b4
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/auxiliary/go_trait.rs
@@ -0,0 +1,43 @@
+#![feature(specialization)]
+
+// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy.
+
+pub trait Go {
+ fn go(&self, arg: isize);
+}
+
+pub fn go<G:Go>(this: &G, arg: isize) {
+ this.go(arg)
+}
+
+pub trait GoMut {
+ fn go_mut(&mut self, arg: isize);
+}
+
+pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) {
+ this.go_mut(arg)
+}
+
+pub trait GoOnce {
+ fn go_once(self, arg: isize);
+}
+
+pub fn go_once<G:GoOnce>(this: G, arg: isize) {
+ this.go_once(arg)
+}
+
+default impl<G> GoMut for G
+ where G : Go
+{
+ fn go_mut(&mut self, arg: isize) {
+ go(&*self, arg)
+ }
+}
+
+default impl<G> GoOnce for G
+ where G : GoMut
+{
+ fn go_once(mut self, arg: isize) {
+ go_mut(&mut self, arg)
+ }
+}
diff --git a/tests/ui/specialization/defaultimpl/out-of-order.rs b/tests/ui/specialization/defaultimpl/out-of-order.rs
new file mode 100644
index 000000000..13258ac8c
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/out-of-order.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+// Test that you can list the more specific impl before the more general one.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo {
+ type Out;
+}
+
+impl Foo for bool {
+ type Out = ();
+}
+
+default impl<T> Foo for T {
+ type Out = bool;
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/defaultimpl/out-of-order.stderr b/tests/ui/specialization/defaultimpl/out-of-order.stderr
new file mode 100644
index 000000000..2cf1ac909
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/out-of-order.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/out-of-order.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/defaultimpl/overlap-projection.rs b/tests/ui/specialization/defaultimpl/overlap-projection.rs
new file mode 100644
index 000000000..0add4d551
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/overlap-projection.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+// Test that impls on projected self types can resolve overlap, even when the
+// projections involve specialization, so long as the associated type is
+// provided by the most specialized impl.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Assoc {
+ type Output;
+}
+
+default impl<T> Assoc for T {
+ type Output = bool;
+}
+
+impl Assoc for u8 { type Output = u8; }
+impl Assoc for u16 { type Output = u16; }
+
+trait Foo {}
+impl Foo for u32 {}
+impl Foo for <u8 as Assoc>::Output {}
+impl Foo for <u16 as Assoc>::Output {}
+
+fn main() {}
diff --git a/tests/ui/specialization/defaultimpl/overlap-projection.stderr b/tests/ui/specialization/defaultimpl/overlap-projection.stderr
new file mode 100644
index 000000000..75fdfafd9
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/overlap-projection.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/overlap-projection.rs:7:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/defaultimpl/projection.rs b/tests/ui/specialization/defaultimpl/projection.rs
new file mode 100644
index 000000000..f19c55b04
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/projection.rs
@@ -0,0 +1,42 @@
+// run-pass
+#![allow(dead_code)]
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Make sure we *can* project non-defaulted associated types
+// cf ui/specialization/specialization-default-projection.rs
+
+// First, do so without any use of specialization
+
+trait Foo {
+ type Assoc;
+}
+
+impl<T> Foo for T {
+ type Assoc = ();
+}
+
+fn generic_foo<T>() -> <T as Foo>::Assoc {
+ ()
+}
+
+// Next, allow for one layer of specialization
+
+trait Bar {
+ type Assoc;
+}
+
+default impl<T> Bar for T {
+ type Assoc = ();
+}
+
+impl<T: Clone> Bar for T {
+ type Assoc = u8;
+}
+
+fn generic_bar_clone<T: Clone>() -> <T as Bar>::Assoc {
+ 0u8
+}
+
+fn main() {
+}
diff --git a/tests/ui/specialization/defaultimpl/projection.stderr b/tests/ui/specialization/defaultimpl/projection.stderr
new file mode 100644
index 000000000..cc3fe8237
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/projection.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/projection.rs:4:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.rs b/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.rs
new file mode 100644
index 000000000..89158b65a
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.rs
@@ -0,0 +1,11 @@
+// Check that specialization must be ungated to use the `default` keyword
+
+trait Foo {
+ fn foo(&self);
+}
+
+default impl<T> Foo for T { //~ ERROR specialization is unstable
+ fn foo(&self) {}
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr b/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr
new file mode 100644
index 000000000..64e14f580
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-feature-gate-default.stderr
@@ -0,0 +1,14 @@
+error[E0658]: specialization is unstable
+ --> $DIR/specialization-feature-gate-default.rs:7:1
+ |
+LL | / default impl<T> Foo for T {
+LL | | fn foo(&self) {}
+LL | | }
+ | |_^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: add `#![feature(specialization)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.rs b/tests/ui/specialization/defaultimpl/specialization-no-default.rs
new file mode 100644
index 000000000..661724eef
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-no-default.rs
@@ -0,0 +1,77 @@
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Check a number of scenarios in which one impl tries to override another,
+// without correctly using `default`.
+
+// Test 1: one layer of specialization, multiple methods, missing `default`
+
+trait Foo {
+ fn foo(&self);
+ fn bar(&self);
+}
+
+impl<T> Foo for T {
+ fn foo(&self) {}
+ fn bar(&self) {}
+}
+
+impl Foo for u8 {}
+impl Foo for u16 {
+ fn foo(&self) {} //~ ERROR E0520
+}
+impl Foo for u32 {
+ fn bar(&self) {} //~ ERROR E0520
+}
+
+// Test 2: one layer of specialization, missing `default` on associated type
+
+trait Bar {
+ type T;
+}
+
+impl<T> Bar for T {
+ type T = u8;
+}
+
+impl Bar for u8 {
+ type T = (); //~ ERROR E0520
+}
+
+// Test 3a: multiple layers of specialization, missing interior `default`
+
+trait Baz {
+ fn baz(&self);
+}
+
+default impl<T> Baz for T {
+ fn baz(&self) {}
+}
+
+impl<T: Clone> Baz for T {
+ fn baz(&self) {}
+}
+
+impl Baz for i32 {
+ fn baz(&self) {} //~ ERROR E0520
+}
+
+// Test 3b: multiple layers of specialization, missing interior `default`,
+// redundant `default` in bottom layer.
+
+trait Redundant {
+ fn redundant(&self);
+}
+
+default impl<T> Redundant for T {
+ fn redundant(&self) {}
+}
+
+impl<T: Clone> Redundant for T {
+ fn redundant(&self) {}
+}
+
+default impl Redundant for i32 {
+ fn redundant(&self) {} //~ ERROR E0520
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr
new file mode 100644
index 000000000..770be2af2
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr
@@ -0,0 +1,68 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-no-default.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:20:5
+ |
+LL | impl<T> Foo for T {
+ | ----------------- parent `impl` is here
+...
+LL | fn foo(&self) {}
+ | ^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
+ |
+ = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error[E0520]: `bar` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:23:5
+ |
+LL | impl<T> Foo for T {
+ | ----------------- parent `impl` is here
+...
+LL | fn bar(&self) {}
+ | ^^^^^^^^^^^^^^^^ cannot specialize default item `bar`
+ |
+ = note: to specialize, `bar` in the parent `impl` must be marked `default`
+
+error[E0520]: `T` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:37:5
+ |
+LL | impl<T> Bar for T {
+ | ----------------- parent `impl` is here
+...
+LL | type T = ();
+ | ^^^^^^^^^^^^ cannot specialize default item `T`
+ |
+ = note: to specialize, `T` in the parent `impl` must be marked `default`
+
+error[E0520]: `baz` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:55:5
+ |
+LL | impl<T: Clone> Baz for T {
+ | ------------------------ parent `impl` is here
+...
+LL | fn baz(&self) {}
+ | ^^^^^^^^^^^^^^^^ cannot specialize default item `baz`
+ |
+ = note: to specialize, `baz` in the parent `impl` must be marked `default`
+
+error[E0520]: `redundant` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:74:5
+ |
+LL | impl<T: Clone> Redundant for T {
+ | ------------------------------ parent `impl` is here
+...
+LL | fn redundant(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant`
+ |
+ = note: to specialize, `redundant` in the parent `impl` must be marked `default`
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs
new file mode 100644
index 000000000..89fef5b5e
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+// Tests that we can combine a default impl that supplies one method with a
+// full impl that supplies the other, and they can invoke one another.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo {
+ fn foo_one(&self) -> &'static str;
+ fn foo_two(&self) -> &'static str;
+ fn foo_three(&self) -> &'static str;
+}
+
+struct MyStruct;
+
+default impl<T> Foo for T {
+ fn foo_one(&self) -> &'static str {
+ self.foo_three()
+ }
+}
+
+impl Foo for MyStruct {
+ fn foo_two(&self) -> &'static str {
+ self.foo_one()
+ }
+
+ fn foo_three(&self) -> &'static str {
+ "generic"
+ }
+}
+
+fn main() {
+ assert!(MyStruct.foo_two() == "generic");
+}
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr
new file mode 100644
index 000000000..407c1ab77
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-trait-item-not-implemented-rpass.rs:6:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs
new file mode 100644
index 000000000..3c5414469
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs
@@ -0,0 +1,23 @@
+// Tests that default impls do not have to supply all items but regular impls do.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo {
+ fn foo_one(&self) -> &'static str;
+ fn foo_two(&self) -> &'static str;
+}
+
+struct MyStruct;
+
+default impl<T> Foo for T {
+ fn foo_one(&self) -> &'static str {
+ "generic"
+ }
+}
+
+impl Foo for MyStruct {}
+//~^ ERROR not all trait items implemented, missing: `foo_two` [E0046]
+
+fn main() {
+ println!("{}", MyStruct.foo_one());
+}
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr
new file mode 100644
index 000000000..f19975060
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr
@@ -0,0 +1,22 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-trait-item-not-implemented.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0046]: not all trait items implemented, missing: `foo_two`
+ --> $DIR/specialization-trait-item-not-implemented.rs:18:1
+ |
+LL | fn foo_two(&self) -> &'static str;
+ | ---------------------------------- `foo_two` from trait
+...
+LL | impl Foo for MyStruct {}
+ | ^^^^^^^^^^^^^^^^^^^^^ missing `foo_two` in implementation
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs
new file mode 100644
index 000000000..6834d5736
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs
@@ -0,0 +1,24 @@
+// Tests that:
+// - default impls do not have to supply all items and
+// - a default impl does not count as an impl (in this case, an incomplete default impl).
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo {
+ fn foo_one(&self) -> &'static str;
+ fn foo_two(&self) -> &'static str;
+}
+
+struct MyStruct;
+
+default impl<T> Foo for T {
+ fn foo_one(&self) -> &'static str {
+ "generic"
+ }
+}
+
+
+fn main() {
+ println!("{}", MyStruct.foo_one());
+ //~^ ERROR the method
+}
diff --git a/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
new file mode 100644
index 000000000..37788612f
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
@@ -0,0 +1,44 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-trait-not-implemented.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0599]: the method `foo_one` exists for struct `MyStruct`, but its trait bounds were not satisfied
+ --> $DIR/specialization-trait-not-implemented.rs:22:29
+ |
+LL | struct MyStruct;
+ | ---------------
+ | |
+ | method `foo_one` not found for this struct
+ | doesn't satisfy `MyStruct: Foo`
+...
+LL | println!("{}", MyStruct.foo_one());
+ | ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds
+ |
+note: trait bound `MyStruct: Foo` was not satisfied
+ --> $DIR/specialization-trait-not-implemented.rs:14:1
+ |
+LL | default impl<T> Foo for T {
+ | ^^^^^^^^^^^^^^^^---^^^^^-
+ | |
+ | unsatisfied trait bound introduced here
+note: the trait `Foo` must be implemented
+ --> $DIR/specialization-trait-not-implemented.rs:7:1
+ |
+LL | trait Foo {
+ | ^^^^^^^^^
+ = help: items from traits can only be used if the trait is implemented and in scope
+note: `Foo` defines an item `foo_one`, perhaps you need to implement it
+ --> $DIR/specialization-trait-not-implemented.rs:7:1
+ |
+LL | trait Foo {
+ | ^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-wfcheck.rs b/tests/ui/specialization/defaultimpl/specialization-wfcheck.rs
new file mode 100644
index 000000000..eb18d6eaa
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-wfcheck.rs
@@ -0,0 +1,10 @@
+// Tests that a default impl still has to have a WF trait ref.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo<'a, T: Eq + 'a> { }
+
+default impl<U> Foo<'static, U> for () {}
+//~^ ERROR the trait bound `U: Eq` is not satisfied
+
+fn main(){}
diff --git a/tests/ui/specialization/defaultimpl/specialization-wfcheck.stderr b/tests/ui/specialization/defaultimpl/specialization-wfcheck.stderr
new file mode 100644
index 000000000..e78016034
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/specialization-wfcheck.stderr
@@ -0,0 +1,29 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-wfcheck.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `U: Eq` is not satisfied
+ --> $DIR/specialization-wfcheck.rs:7:17
+ |
+LL | default impl<U> Foo<'static, U> for () {}
+ | ^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `U`
+ |
+note: required by a bound in `Foo`
+ --> $DIR/specialization-wfcheck.rs:5:18
+ |
+LL | trait Foo<'a, T: Eq + 'a> { }
+ | ^^ required by this bound in `Foo`
+help: consider restricting type parameter `U`
+ |
+LL | default impl<U: std::cmp::Eq> Foo<'static, U> for () {}
+ | ++++++++++++++
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/defaultimpl/validation.rs b/tests/ui/specialization/defaultimpl/validation.rs
new file mode 100644
index 000000000..8558a1efb
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/validation.rs
@@ -0,0 +1,16 @@
+#![feature(negative_impls)]
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+struct S;
+struct Z;
+
+default impl S {} //~ ERROR inherent impls cannot be `default`
+
+default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
+default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
+ //~^ ERROR negative impls cannot be default impls
+
+trait Tr {}
+default impl !Tr for S {} //~ ERROR negative impls cannot be default impls
+
+fn main() {}
diff --git a/tests/ui/specialization/defaultimpl/validation.stderr b/tests/ui/specialization/defaultimpl/validation.stderr
new file mode 100644
index 000000000..eb6dc9355
--- /dev/null
+++ b/tests/ui/specialization/defaultimpl/validation.stderr
@@ -0,0 +1,51 @@
+error: inherent impls cannot be `default`
+ --> $DIR/validation.rs:7:14
+ |
+LL | default impl S {}
+ | ------- ^ inherent impl for this type
+ | |
+ | `default` because of this
+ |
+ = note: only trait implementations may be annotated with `default`
+
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/validation.rs:2:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error: impls of auto traits cannot be default
+ --> $DIR/validation.rs:9:21
+ |
+LL | default unsafe impl Send for S {}
+ | ------- ^^^^ auto trait
+ | |
+ | default because of this
+
+error: impls of auto traits cannot be default
+ --> $DIR/validation.rs:10:15
+ |
+LL | default impl !Send for Z {}
+ | ------- ^^^^ auto trait
+ | |
+ | default because of this
+
+error[E0750]: negative impls cannot be default impls
+ --> $DIR/validation.rs:10:1
+ |
+LL | default impl !Send for Z {}
+ | ^^^^^^^ ^
+
+error[E0750]: negative impls cannot be default impls
+ --> $DIR/validation.rs:14:1
+ |
+LL | default impl !Tr for S {}
+ | ^^^^^^^ ^
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0750`.
diff --git a/tests/ui/specialization/issue-33017.rs b/tests/ui/specialization/issue-33017.rs
new file mode 100644
index 000000000..8dbadf58d
--- /dev/null
+++ b/tests/ui/specialization/issue-33017.rs
@@ -0,0 +1,45 @@
+// Test to ensure that trait bounds are properly
+// 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"));
+}
diff --git a/tests/ui/specialization/issue-33017.stderr b/tests/ui/specialization/issue-33017.stderr
new file mode 100644
index 000000000..78e94cec2
--- /dev/null
+++ b/tests/ui/specialization/issue-33017.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/issue-33017.rs:12:27
+ |
+LL | default type Output = Self;
+ | ^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/issue-33017.rs:8:31
+ |
+LL | type Output: From<Self> + Copy + Into<Self>;
+ | ^^^^ required by this bound in `UncheckedCopy::Output`
+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`.
diff --git a/tests/ui/specialization/issue-35376.rs b/tests/ui/specialization/issue-35376.rs
new file mode 100644
index 000000000..cc35213b9
--- /dev/null
+++ b/tests/ui/specialization/issue-35376.rs
@@ -0,0 +1,43 @@
+// check-pass
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+fn main() {}
+
+pub trait Alpha<T> { }
+
+pub trait Beta {
+ type Event;
+}
+
+pub trait Delta {
+ type Handle;
+ fn process(&self);
+}
+
+pub struct Parent<A, T>(A, T);
+
+impl<A, T> Delta for Parent<A, T>
+where A: Alpha<T::Handle>,
+ T: Delta,
+ T::Handle: Beta<Event = <Handle as Beta>::Event> {
+ type Handle = Handle;
+ default fn process(&self) {
+ unimplemented!()
+ }
+}
+
+impl<A, T> Delta for Parent<A, T>
+where A: Alpha<T::Handle> + Alpha<Handle>,
+ T: Delta,
+ T::Handle: Beta<Event = <Handle as Beta>::Event> {
+ fn process(&self) {
+ unimplemented!()
+ }
+}
+
+pub struct Handle;
+
+impl Beta for Handle {
+ type Event = ();
+}
diff --git a/tests/ui/specialization/issue-35376.stderr b/tests/ui/specialization/issue-35376.stderr
new file mode 100644
index 000000000..6c4167f3f
--- /dev/null
+++ b/tests/ui/specialization/issue-35376.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-35376.rs:2:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/issue-36804.rs b/tests/ui/specialization/issue-36804.rs
new file mode 100644
index 000000000..89350602f
--- /dev/null
+++ b/tests/ui/specialization/issue-36804.rs
@@ -0,0 +1,35 @@
+// check-pass
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+pub struct Cloned<I>(I);
+
+impl<'a, I, T: 'a> Iterator for Cloned<I>
+where
+ I: Iterator<Item = &'a T>,
+ T: Clone,
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ unimplemented!()
+ }
+
+ default fn count(self) -> usize where Self: Sized {
+ self.fold(0, |cnt, _| cnt + 1)
+ }
+}
+
+impl<'a, I, T: 'a> Iterator for Cloned<I>
+where
+ I: Iterator<Item = &'a T>,
+ T: Copy,
+{
+ fn count(self) -> usize {
+ unimplemented!()
+ }
+}
+
+fn main() {
+ let a = [1,2,3,4];
+ Cloned(a.iter()).count();
+}
diff --git a/tests/ui/specialization/issue-36804.stderr b/tests/ui/specialization/issue-36804.stderr
new file mode 100644
index 000000000..c2113b25f
--- /dev/null
+++ b/tests/ui/specialization/issue-36804.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-36804.rs:2:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/issue-38091-2.rs b/tests/ui/specialization/issue-38091-2.rs
new file mode 100644
index 000000000..9ed0b240d
--- /dev/null
+++ b/tests/ui/specialization/issue-38091-2.rs
@@ -0,0 +1,28 @@
+// build-fail
+//~^ ERROR overflow evaluating the requirement `i32: Check`
+
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+trait Iterate<'a> {
+ type Ty: Valid;
+ fn iterate(self);
+}
+impl<'a, T> Iterate<'a> for T
+where
+ T: Check,
+{
+ default type Ty = ();
+ default fn iterate(self) {}
+}
+
+trait Check {}
+impl<'a, T> Check for T where <T as Iterate<'a>>::Ty: Valid {}
+
+trait Valid {}
+
+impl Valid for () {}
+
+fn main() {
+ Iterate::iterate(0);
+}
diff --git a/tests/ui/specialization/issue-38091-2.stderr b/tests/ui/specialization/issue-38091-2.stderr
new file mode 100644
index 000000000..5a05f9c27
--- /dev/null
+++ b/tests/ui/specialization/issue-38091-2.stderr
@@ -0,0 +1,24 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-38091-2.rs:4:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0275]: overflow evaluating the requirement `i32: Check`
+ |
+note: required for `i32` to implement `Iterate<'_>`
+ --> $DIR/issue-38091-2.rs:11:13
+ |
+LL | impl<'a, T> Iterate<'a> for T
+ | ^^^^^^^^^^^ ^
+LL | where
+LL | T: Check,
+ | ----- unsatisfied trait bound introduced here
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/specialization/issue-38091.rs b/tests/ui/specialization/issue-38091.rs
new file mode 100644
index 000000000..5b398368a
--- /dev/null
+++ b/tests/ui/specialization/issue-38091.rs
@@ -0,0 +1,24 @@
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+trait Iterate<'a> {
+ type Ty: Valid;
+ fn iterate(self);
+}
+impl<'a, T> Iterate<'a> for T
+where
+ T: Check,
+{
+ default type Ty = ();
+ //~^ ERROR the trait bound `(): Valid` is not satisfied
+ default fn iterate(self) {}
+}
+
+trait Check {}
+impl<'a, T> Check for T where <T as Iterate<'a>>::Ty: Valid {}
+
+trait Valid {}
+
+fn main() {
+ Iterate::iterate(0);
+}
diff --git a/tests/ui/specialization/issue-38091.stderr b/tests/ui/specialization/issue-38091.stderr
new file mode 100644
index 000000000..f2210a407
--- /dev/null
+++ b/tests/ui/specialization/issue-38091.stderr
@@ -0,0 +1,25 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-38091.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `(): Valid` is not satisfied
+ --> $DIR/issue-38091.rs:12:23
+ |
+LL | default type Ty = ();
+ | ^^ the trait `Valid` is not implemented for `()`
+ |
+note: required by a bound in `Iterate::Ty`
+ --> $DIR/issue-38091.rs:5:14
+ |
+LL | type Ty: Valid;
+ | ^^^^^ required by this bound in `Iterate::Ty`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/issue-39448.rs b/tests/ui/specialization/issue-39448.rs
new file mode 100644
index 000000000..a15c4bd6b
--- /dev/null
+++ b/tests/ui/specialization/issue-39448.rs
@@ -0,0 +1,50 @@
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Regression test for a specialization-related ICE (#39448).
+
+trait A: Sized {
+ fn foo(self, _: Self) -> Self {
+ self
+ }
+}
+
+impl A for u8 {}
+impl A for u16 {}
+
+impl FromA<u8> for u16 {
+ fn from(x: u8) -> u16 {
+ x as u16
+ }
+}
+
+trait FromA<T> {
+ fn from(t: T) -> Self;
+}
+
+impl<T: A, U: A + FromA<T>> FromA<T> for U {
+ default fn from(x: T) -> Self {
+ ToA::to(x)
+ }
+}
+
+trait ToA<T> {
+ fn to(self) -> T;
+}
+
+impl<T, U> ToA<U> for T
+where
+ U: FromA<T>,
+{
+ fn to(self) -> U {
+ U::from(self)
+ }
+}
+
+#[allow(dead_code)]
+fn foo<T: A, U: A>(x: T, y: U) -> U {
+ x.foo(y.to()).to() //~ ERROR overflow evaluating the requirement
+}
+
+fn main() {
+ let z = foo(8u8, 1u16);
+}
diff --git a/tests/ui/specialization/issue-39448.stderr b/tests/ui/specialization/issue-39448.stderr
new file mode 100644
index 000000000..9ce51d113
--- /dev/null
+++ b/tests/ui/specialization/issue-39448.stderr
@@ -0,0 +1,35 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-39448.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0275]: overflow evaluating the requirement `T: FromA<U>`
+ --> $DIR/issue-39448.rs:45:13
+ |
+LL | x.foo(y.to()).to()
+ | ^^
+ |
+note: required for `T` to implement `FromA<U>`
+ --> $DIR/issue-39448.rs:24:29
+ |
+LL | impl<T: A, U: A + FromA<T>> FromA<T> for U {
+ | -------- ^^^^^^^^ ^
+ | |
+ | unsatisfied trait bound introduced here
+note: required for `U` to implement `ToA<T>`
+ --> $DIR/issue-39448.rs:34:12
+ |
+LL | impl<T, U> ToA<U> for T
+ | ^^^^^^ ^
+LL | where
+LL | U: FromA<T>,
+ | -------- unsatisfied trait bound introduced here
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/specialization/issue-39618.rs b/tests/ui/specialization/issue-39618.rs
new file mode 100644
index 000000000..72630ee9c
--- /dev/null
+++ b/tests/ui/specialization/issue-39618.rs
@@ -0,0 +1,27 @@
+// Regression test for #39618, shouldn't crash.
+// FIXME(JohnTitor): Centril pointed out this looks suspicions, we should revisit here.
+// More context: https://github.com/rust-lang/rust/pull/69192#discussion_r379846796
+
+// check-pass
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo {
+ fn foo(&self);
+}
+
+trait Bar {
+ fn bar(&self);
+}
+
+impl<T> Bar for T where T: Foo {
+ fn bar(&self) {}
+}
+
+impl<T> Foo for T where T: Bar {
+ fn foo(&self) {}
+}
+
+impl Foo for u64 {}
+
+fn main() {}
diff --git a/tests/ui/specialization/issue-39618.stderr b/tests/ui/specialization/issue-39618.stderr
new file mode 100644
index 000000000..19de60c7c
--- /dev/null
+++ b/tests/ui/specialization/issue-39618.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-39618.rs:7:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/issue-43037.current.stderr b/tests/ui/specialization/issue-43037.current.stderr
new file mode 100644
index 000000000..26db9d7c9
--- /dev/null
+++ b/tests/ui/specialization/issue-43037.current.stderr
@@ -0,0 +1,12 @@
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+ --> $DIR/issue-43037.rs:19:6
+ |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+ | ^ type parameter `T` must be used as the type parameter for some local type
+ |
+ = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+ = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/specialization/issue-43037.negative.stderr b/tests/ui/specialization/issue-43037.negative.stderr
new file mode 100644
index 000000000..26db9d7c9
--- /dev/null
+++ b/tests/ui/specialization/issue-43037.negative.stderr
@@ -0,0 +1,12 @@
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+ --> $DIR/issue-43037.rs:19:6
+ |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+ | ^ type parameter `T` must be used as the type parameter for some local type
+ |
+ = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+ = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/specialization/issue-43037.rs b/tests/ui/specialization/issue-43037.rs
new file mode 100644
index 000000000..a1e3f998b
--- /dev/null
+++ b/tests/ui/specialization/issue-43037.rs
@@ -0,0 +1,22 @@
+// revisions: current negative
+#![feature(specialization)]
+#![cfg_attr(negative, feature(with_negative_coherence))]
+#![allow(incomplete_features)]
+
+trait X {}
+trait Y: X {}
+trait Z {
+ type Assoc: Y;
+}
+struct A<T>(T);
+
+impl<T> Y for T where T: X {}
+impl<T: X> Z for A<T> {
+ type Assoc = T;
+}
+
+// this impl is invalid, but causes an ICE anyway
+impl<T> From<<A<T> as Z>::Assoc> for T {}
+//~^ ERROR type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+
+fn main() {}
diff --git a/tests/ui/specialization/issue-44861.rs b/tests/ui/specialization/issue-44861.rs
new file mode 100644
index 000000000..79d9b9490
--- /dev/null
+++ b/tests/ui/specialization/issue-44861.rs
@@ -0,0 +1,40 @@
+#![crate_type = "lib"]
+#![feature(specialization)]
+#![feature(unsize, coerce_unsized)]
+#![allow(incomplete_features)]
+
+use std::ops::CoerceUnsized;
+
+pub struct SmartassPtr<A: Smartass+?Sized>(A::Data);
+
+pub trait Smartass {
+ type Data;
+ type Data2: CoerceUnsized<*const [u8]>;
+}
+
+pub trait MaybeObjectSafe {}
+
+impl MaybeObjectSafe for () {}
+
+impl<T> Smartass for T {
+ type Data = <Self as Smartass>::Data2;
+ default type Data2 = ();
+ //~^ ERROR: the trait bound `(): CoerceUnsized<*const [u8]>` is not satisfied
+}
+
+impl Smartass for () {
+ type Data2 = *const [u8; 1];
+}
+
+impl Smartass for dyn MaybeObjectSafe {
+ type Data = *const [u8];
+ type Data2 = *const [u8; 0];
+}
+
+impl<U: Smartass+?Sized, T: Smartass+?Sized> CoerceUnsized<SmartassPtr<T>> for SmartassPtr<U>
+ where <U as Smartass>::Data: std::ops::CoerceUnsized<<T as Smartass>::Data>
+{}
+
+pub fn conv(s: SmartassPtr<()>) -> SmartassPtr<dyn MaybeObjectSafe> {
+ s
+}
diff --git a/tests/ui/specialization/issue-44861.stderr b/tests/ui/specialization/issue-44861.stderr
new file mode 100644
index 000000000..1941d40fe
--- /dev/null
+++ b/tests/ui/specialization/issue-44861.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `(): CoerceUnsized<*const [u8]>` is not satisfied
+ --> $DIR/issue-44861.rs:21:26
+ |
+LL | default type Data2 = ();
+ | ^^ the trait `CoerceUnsized<*const [u8]>` is not implemented for `()`
+ |
+note: required by a bound in `Smartass::Data2`
+ --> $DIR/issue-44861.rs:12:17
+ |
+LL | type Data2: CoerceUnsized<*const [u8]>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Smartass::Data2`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/issue-45814.current.stderr b/tests/ui/specialization/issue-45814.current.stderr
new file mode 100644
index 000000000..5013559b8
--- /dev/null
+++ b/tests/ui/specialization/issue-45814.current.stderr
@@ -0,0 +1,14 @@
+error[E0275]: overflow evaluating the requirement `T: Trait<_>`
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
+note: required for `T` to implement `Trait<_>`
+ --> $DIR/issue-45814.rs:9:20
+ |
+LL | default impl<T, U> Trait<T> for U {}
+ | ^^^^^^^^ ^
+ = note: 128 redundant requirements hidden
+ = note: required for `T` to implement `Trait<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/specialization/issue-45814.negative.stderr b/tests/ui/specialization/issue-45814.negative.stderr
new file mode 100644
index 000000000..5013559b8
--- /dev/null
+++ b/tests/ui/specialization/issue-45814.negative.stderr
@@ -0,0 +1,14 @@
+error[E0275]: overflow evaluating the requirement `T: Trait<_>`
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
+note: required for `T` to implement `Trait<_>`
+ --> $DIR/issue-45814.rs:9:20
+ |
+LL | default impl<T, U> Trait<T> for U {}
+ | ^^^^^^^^ ^
+ = note: 128 redundant requirements hidden
+ = note: required for `T` to implement `Trait<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/specialization/issue-45814.rs b/tests/ui/specialization/issue-45814.rs
new file mode 100644
index 000000000..fce236390
--- /dev/null
+++ b/tests/ui/specialization/issue-45814.rs
@@ -0,0 +1,13 @@
+//~ ERROR overflow evaluating the requirement `T: Trait<_>`
+// revisions: current negative
+#![feature(specialization)]
+#![cfg_attr(negative, feature(with_negative_coherence))]
+#![allow(incomplete_features)]
+
+pub trait Trait<T> {}
+
+default impl<T, U> Trait<T> for U {}
+
+impl<T> Trait<<T as Iterator>::Item> for T {}
+
+fn main() {}
diff --git a/tests/ui/specialization/issue-50452-fail.rs b/tests/ui/specialization/issue-50452-fail.rs
new file mode 100644
index 000000000..fe21e9b6e
--- /dev/null
+++ b/tests/ui/specialization/issue-50452-fail.rs
@@ -0,0 +1,21 @@
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+pub trait Foo {
+ fn foo();
+}
+
+impl Foo for i32 {}
+impl Foo for i64 {
+ fn foo() {}
+ //~^ERROR `foo` specializes an item from a parent `impl`
+}
+impl<T> Foo for T {
+ fn foo() {}
+}
+
+fn main() {
+ i32::foo();
+ i64::foo();
+ u8::foo();
+}
diff --git a/tests/ui/specialization/issue-50452-fail.stderr b/tests/ui/specialization/issue-50452-fail.stderr
new file mode 100644
index 000000000..5c136adc4
--- /dev/null
+++ b/tests/ui/specialization/issue-50452-fail.stderr
@@ -0,0 +1,24 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-50452-fail.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/issue-50452-fail.rs:10:5
+ |
+LL | fn foo() {}
+ | ^^^^^^^^^^^ cannot specialize default item `foo`
+...
+LL | impl<T> Foo for T {
+ | ----------------- parent `impl` is here
+ |
+ = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/specialization/issue-50452.rs b/tests/ui/specialization/issue-50452.rs
new file mode 100644
index 000000000..29fc12066
--- /dev/null
+++ b/tests/ui/specialization/issue-50452.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+pub trait Foo {
+ fn foo();
+}
+
+impl Foo for i32 {}
+impl Foo for i64 {}
+impl<T> Foo for T {
+ fn foo() {}
+}
+
+fn main() {
+ i32::foo();
+ i64::foo();
+ u8::foo();
+}
diff --git a/tests/ui/specialization/issue-50452.stderr b/tests/ui/specialization/issue-50452.stderr
new file mode 100644
index 000000000..48cab9dcd
--- /dev/null
+++ b/tests/ui/specialization/issue-50452.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-50452.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/issue-51892.rs b/tests/ui/specialization/issue-51892.rs
new file mode 100644
index 000000000..5c0625414
--- /dev/null
+++ b/tests/ui/specialization/issue-51892.rs
@@ -0,0 +1,18 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+#![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() {}
diff --git a/tests/ui/specialization/issue-51892.stderr b/tests/ui/specialization/issue-51892.stderr
new file mode 100644
index 000000000..cb46db836
--- /dev/null
+++ b/tests/ui/specialization/issue-51892.stderr
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+ --> $DIR/issue-51892.rs:14:17
+ |
+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
+
diff --git a/tests/ui/specialization/issue-52050.rs b/tests/ui/specialization/issue-52050.rs
new file mode 100644
index 000000000..804658702
--- /dev/null
+++ b/tests/ui/specialization/issue-52050.rs
@@ -0,0 +1,32 @@
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Regression test for #52050: when inserting the blanket impl `I`
+// into the tree, we had to replace the child node for `Foo`, which
+// led to the structure of the tree being messed up.
+
+use std::iter::Iterator;
+
+trait IntoPyDictPointer { }
+
+struct Foo { }
+
+impl Iterator for Foo {
+ type Item = ();
+ fn next(&mut self) -> Option<()> {
+ None
+ }
+}
+
+impl IntoPyDictPointer for Foo { }
+
+impl<I> IntoPyDictPointer for I
+where
+ I: Iterator,
+{
+}
+
+impl IntoPyDictPointer for () //~ ERROR conflicting implementations
+{
+}
+
+fn main() { }
diff --git a/tests/ui/specialization/issue-52050.stderr b/tests/ui/specialization/issue-52050.stderr
new file mode 100644
index 000000000..c263fe467
--- /dev/null
+++ b/tests/ui/specialization/issue-52050.stderr
@@ -0,0 +1,24 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-52050.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0119]: conflicting implementations of trait `IntoPyDictPointer` for type `()`
+ --> $DIR/issue-52050.rs:28:1
+ |
+LL | impl<I> IntoPyDictPointer for I
+ | ------------------------------- first implementation here
+...
+LL | impl IntoPyDictPointer for ()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+ |
+ = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/issue-59435.rs b/tests/ui/specialization/issue-59435.rs
new file mode 100644
index 000000000..323900256
--- /dev/null
+++ b/tests/ui/specialization/issue-59435.rs
@@ -0,0 +1,17 @@
+#![feature(specialization)]
+#![allow(incomplete_features)]
+
+struct MyStruct {}
+
+trait MyTrait {
+ type MyType: Default;
+}
+
+impl MyTrait for i32 {
+ default type MyType = MyStruct;
+ //~^ ERROR: the trait bound `MyStruct: Default` is not satisfied
+}
+
+fn main() {
+ let _x: <i32 as MyTrait>::MyType = <i32 as MyTrait>::MyType::default();
+}
diff --git a/tests/ui/specialization/issue-59435.stderr b/tests/ui/specialization/issue-59435.stderr
new file mode 100644
index 000000000..211459406
--- /dev/null
+++ b/tests/ui/specialization/issue-59435.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `MyStruct: Default` is not satisfied
+ --> $DIR/issue-59435.rs:11:27
+ |
+LL | default type MyType = MyStruct;
+ | ^^^^^^^^ the trait `Default` is not implemented for `MyStruct`
+ |
+note: required by a bound in `MyTrait::MyType`
+ --> $DIR/issue-59435.rs:7:18
+ |
+LL | type MyType: Default;
+ | ^^^^^^^ required by this bound in `MyTrait::MyType`
+help: consider annotating `MyStruct` with `#[derive(Default)]`
+ |
+LL | #[derive(Default)]
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/specialization/issue-63716-parse-async.rs b/tests/ui/specialization/issue-63716-parse-async.rs
new file mode 100644
index 000000000..10f185c33
--- /dev/null
+++ b/tests/ui/specialization/issue-63716-parse-async.rs
@@ -0,0 +1,14 @@
+// Ensure that `default async fn` will parse.
+// See issue #63716 for details.
+
+// check-pass
+// edition:2018
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl Foo for Bar {
+ default async fn baz() {}
+}
diff --git a/tests/ui/specialization/issue-63716-parse-async.stderr b/tests/ui/specialization/issue-63716-parse-async.stderr
new file mode 100644
index 000000000..a00572da8
--- /dev/null
+++ b/tests/ui/specialization/issue-63716-parse-async.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-63716-parse-async.rs:7:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs
new file mode 100644
index 000000000..d11ec7983
--- /dev/null
+++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs
@@ -0,0 +1,23 @@
+// A regression test for #68830. This checks we don't emit
+// a verbose `conflicting implementations` error.
+
+#![feature(specialization)]
+#![allow(incomplete_features)]
+
+struct BadStruct {
+ err: MissingType //~ ERROR: cannot find type `MissingType` in this scope
+}
+
+trait MyTrait<T> {
+ fn foo();
+}
+
+impl<T, D> MyTrait<T> for D {
+ default fn foo() {}
+}
+
+impl<T> MyTrait<T> for BadStruct {
+ fn foo() {}
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr
new file mode 100644
index 000000000..833f61dca
--- /dev/null
+++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `MissingType` in this scope
+ --> $DIR/issue-68830-spurious-diagnostics.rs:8:10
+ |
+LL | err: MissingType
+ | ^^^^^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/specialization/issue-70442.rs b/tests/ui/specialization/issue-70442.rs
new file mode 100644
index 000000000..d41b5355c
--- /dev/null
+++ b/tests/ui/specialization/issue-70442.rs
@@ -0,0 +1,23 @@
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// check-pass
+
+trait Trait {
+ type Assoc;
+}
+
+impl<T> Trait for T {
+ default type Assoc = bool;
+}
+
+// This impl inherits the `Assoc` definition from above and "locks it in", or finalizes it, making
+// child impls unable to further specialize it. However, since the specialization graph didn't
+// correctly track this, we would refuse to project `Assoc` from this impl, even though that should
+// happen for items that are final.
+impl Trait for () {}
+
+fn foo<X: Trait<Assoc=bool>>() {}
+
+fn main() {
+ foo::<()>(); // `<() as Trait>::Assoc` is normalized to `bool` correctly
+}
diff --git a/tests/ui/specialization/issue-70442.stderr b/tests/ui/specialization/issue-70442.stderr
new file mode 100644
index 000000000..aa72c3286
--- /dev/null
+++ b/tests/ui/specialization/issue-70442.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-70442.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/min_specialization/auxiliary/specialization-trait.rs b/tests/ui/specialization/min_specialization/auxiliary/specialization-trait.rs
new file mode 100644
index 000000000..6ec0d261d
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/dyn-trait-assoc-types.rs b/tests/ui/specialization/min_specialization/dyn-trait-assoc-types.rs
new file mode 100644
index 000000000..03cab00b0
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/dyn-trait-assoc-types.stderr b/tests/ui/specialization/min_specialization/dyn-trait-assoc-types.stderr
new file mode 100644
index 000000000..db5558f16
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/impl-on-nonexisting.rs b/tests/ui/specialization/min_specialization/impl-on-nonexisting.rs
new file mode 100644
index 000000000..77a64320d
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr b/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr
new file mode 100644
index 000000000..b032ccbe5
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/impl_specialization_trait.rs b/tests/ui/specialization/min_specialization/impl_specialization_trait.rs
new file mode 100644
index 000000000..723ed71c3
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/impl_specialization_trait.stderr b/tests/ui/specialization/min_specialization/impl_specialization_trait.stderr
new file mode 100644
index 000000000..934103d49
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/implcit-well-formed-bounds.rs b/tests/ui/specialization/min_specialization/implcit-well-formed-bounds.rs
new file mode 100644
index 000000000..98d7f9194
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/issue-79224.rs b/tests/ui/specialization/min_specialization/issue-79224.rs
new file mode 100644
index 000000000..104bddd07
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/issue-79224.rs
@@ -0,0 +1,26 @@
+#![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/tests/ui/specialization/min_specialization/issue-79224.stderr b/tests/ui/specialization/min_specialization/issue-79224.stderr
new file mode 100644
index 000000000..505baa23c
--- /dev/null
+++ b/tests/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:29
+ |
+LL | impl<B: ?Sized> Display for Cow<'_, B> {
+ | ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
+ |
+ = note: required for `B` to implement `ToOwned`
+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:20:12
+ |
+LL | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ | ^^^^^ the trait `Clone` is not implemented for `B`
+ |
+ = note: required for `B` to implement `ToOwned`
+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/tests/ui/specialization/min_specialization/repeated_projection_type.rs b/tests/ui/specialization/min_specialization/repeated_projection_type.rs
new file mode 100644
index 000000000..f21f39f06
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/repeated_projection_type.stderr b/tests/ui/specialization/min_specialization/repeated_projection_type.stderr
new file mode 100644
index 000000000..a751ba793
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/repeating_lifetimes.rs b/tests/ui/specialization/min_specialization/repeating_lifetimes.rs
new file mode 100644
index 000000000..49bfacec0
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/repeating_lifetimes.stderr b/tests/ui/specialization/min_specialization/repeating_lifetimes.stderr
new file mode 100644
index 000000000..16dccb10b
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/repeating_param.rs b/tests/ui/specialization/min_specialization/repeating_param.rs
new file mode 100644
index 000000000..5a1c97fd3
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/repeating_param.stderr b/tests/ui/specialization/min_specialization/repeating_param.stderr
new file mode 100644
index 000000000..5e6adf723
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/spec-iter.rs b/tests/ui/specialization/min_specialization/spec-iter.rs
new file mode 100644
index 000000000..e17e9dd5f
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/spec-marker-supertraits.rs b/tests/ui/specialization/min_specialization/spec-marker-supertraits.rs
new file mode 100644
index 000000000..3bb2480e9
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/spec-marker-supertraits.stderr b/tests/ui/specialization/min_specialization/spec-marker-supertraits.stderr
new file mode 100644
index 000000000..ba9d6bbe3
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/spec-reference.rs b/tests/ui/specialization/min_specialization/spec-reference.rs
new file mode 100644
index 000000000..377889e2c
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialization_marker.rs b/tests/ui/specialization/min_specialization/specialization_marker.rs
new file mode 100644
index 000000000..93462d02e
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialization_marker.stderr b/tests/ui/specialization/min_specialization/specialization_marker.stderr
new file mode 100644
index 000000000..b47c14f3c
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialization_super_trait.rs b/tests/ui/specialization/min_specialization/specialization_super_trait.rs
new file mode 100644
index 000000000..145f376ed
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialization_super_trait.stderr b/tests/ui/specialization/min_specialization/specialization_super_trait.stderr
new file mode 100644
index 000000000..e93578662
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialization_trait.rs b/tests/ui/specialization/min_specialization/specialization_trait.rs
new file mode 100644
index 000000000..d597278d2
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialization_trait.stderr b/tests/ui/specialization/min_specialization/specialization_trait.stderr
new file mode 100644
index 000000000..bc87ae0f8
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialize_on_marker.rs b/tests/ui/specialization/min_specialization/specialize_on_marker.rs
new file mode 100644
index 000000000..4219bd13b
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialize_on_spec_trait.rs b/tests/ui/specialization/min_specialization/specialize_on_spec_trait.rs
new file mode 100644
index 000000000..abbab5c23
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialize_on_static.rs b/tests/ui/specialization/min_specialization/specialize_on_static.rs
new file mode 100644
index 000000000..dd1b05401
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialize_on_static.stderr b/tests/ui/specialization/min_specialization/specialize_on_static.stderr
new file mode 100644
index 000000000..9a16798f1
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialize_on_trait.rs b/tests/ui/specialization/min_specialization/specialize_on_trait.rs
new file mode 100644
index 000000000..0588442c3
--- /dev/null
+++ b/tests/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/tests/ui/specialization/min_specialization/specialize_on_trait.stderr b/tests/ui/specialization/min_specialization/specialize_on_trait.stderr
new file mode 100644
index 000000000..7b79c7eb4
--- /dev/null
+++ b/tests/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
+
diff --git a/tests/ui/specialization/non-defaulted-item-fail.rs b/tests/ui/specialization/non-defaulted-item-fail.rs
new file mode 100644
index 000000000..b7d6ac829
--- /dev/null
+++ b/tests/ui/specialization/non-defaulted-item-fail.rs
@@ -0,0 +1,54 @@
+#![feature(specialization, associated_type_defaults)]
+//~^ WARN the feature `specialization` is incomplete
+
+// Test that attempting to override a non-default method or one not in the
+// parent impl causes an error.
+
+trait Foo {
+ type Ty = ();
+ const CONST: u8 = 123;
+ fn foo(&self) -> bool { true }
+}
+
+// Specialization tree for Foo:
+//
+// Box<T> Vec<T>
+// / \ / \
+// Box<i32> Box<i64> Vec<()> Vec<bool>
+
+impl<T> Foo for Box<T> {
+ type Ty = bool;
+ const CONST: u8 = 0;
+ fn foo(&self) -> bool { false }
+}
+
+// Allowed
+impl Foo for Box<i32> {}
+
+// Can't override a non-`default` fn
+impl Foo for Box<i64> {
+ type Ty = Vec<()>;
+//~^ error: `Ty` specializes an item from a parent `impl`, but that item is not marked `default`
+ const CONST: u8 = 42;
+//~^ error: `CONST` specializes an item from a parent `impl`, but that item is not marked `default`
+ fn foo(&self) -> bool { true }
+//~^ error: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+}
+
+
+// Doesn't mention the item = provided body/value is used and the method is final.
+impl<T> Foo for Vec<T> {}
+
+// Allowed
+impl Foo for Vec<()> {}
+
+impl Foo for Vec<bool> {
+ type Ty = Vec<()>;
+//~^ error: `Ty` specializes an item from a parent `impl`, but that item is not marked `default`
+ const CONST: u8 = 42;
+//~^ error: `CONST` specializes an item from a parent `impl`, but that item is not marked `default`
+ fn foo(&self) -> bool { true }
+//~^ error: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/non-defaulted-item-fail.stderr b/tests/ui/specialization/non-defaulted-item-fail.stderr
new file mode 100644
index 000000000..faa14555a
--- /dev/null
+++ b/tests/ui/specialization/non-defaulted-item-fail.stderr
@@ -0,0 +1,79 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/non-defaulted-item-fail.rs:1:12
+ |
+LL | #![feature(specialization, associated_type_defaults)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0520]: `Ty` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/non-defaulted-item-fail.rs:30:5
+ |
+LL | impl<T> Foo for Box<T> {
+ | ---------------------- parent `impl` is here
+...
+LL | type Ty = Vec<()>;
+ | ^^^^^^^^^^^^^^^^^^ cannot specialize default item `Ty`
+ |
+ = note: to specialize, `Ty` in the parent `impl` must be marked `default`
+
+error[E0520]: `CONST` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/non-defaulted-item-fail.rs:32:5
+ |
+LL | impl<T> Foo for Box<T> {
+ | ---------------------- parent `impl` is here
+...
+LL | const CONST: u8 = 42;
+ | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `CONST`
+ |
+ = note: to specialize, `CONST` in the parent `impl` must be marked `default`
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/non-defaulted-item-fail.rs:34:5
+ |
+LL | impl<T> Foo for Box<T> {
+ | ---------------------- parent `impl` is here
+...
+LL | fn foo(&self) -> bool { true }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
+ |
+ = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error[E0520]: `Ty` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/non-defaulted-item-fail.rs:46:5
+ |
+LL | impl<T> Foo for Vec<T> {}
+ | ---------------------- parent `impl` is here
+...
+LL | type Ty = Vec<()>;
+ | ^^^^^^^^^^^^^^^^^^ cannot specialize default item `Ty`
+ |
+ = note: to specialize, `Ty` in the parent `impl` must be marked `default`
+
+error[E0520]: `CONST` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/non-defaulted-item-fail.rs:48:5
+ |
+LL | impl<T> Foo for Vec<T> {}
+ | ---------------------- parent `impl` is here
+...
+LL | const CONST: u8 = 42;
+ | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `CONST`
+ |
+ = note: to specialize, `CONST` in the parent `impl` must be marked `default`
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/non-defaulted-item-fail.rs:50:5
+ |
+LL | impl<T> Foo for Vec<T> {}
+ | ---------------------- parent `impl` is here
+...
+LL | fn foo(&self) -> bool { true }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
+ |
+ = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/specialization/soundness/partial_eq_range_inclusive.rs b/tests/ui/specialization/soundness/partial_eq_range_inclusive.rs
new file mode 100644
index 000000000..923dec892
--- /dev/null
+++ b/tests/ui/specialization/soundness/partial_eq_range_inclusive.rs
@@ -0,0 +1,35 @@
+// run-pass
+
+use std::cell::RefCell;
+use std::cmp::Ordering;
+
+struct Evil<'a, 'b> {
+ values: RefCell<Vec<&'a str>>,
+ to_insert: &'b String,
+}
+
+impl<'a, 'b> PartialEq for Evil<'a, 'b> {
+ fn eq(&self, _other: &Self) -> bool {
+ true
+ }
+}
+
+impl<'a> PartialOrd for Evil<'a, 'a> {
+ fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
+ self.values.borrow_mut().push(self.to_insert);
+ None
+ }
+}
+
+fn main() {
+ let e;
+ let values;
+ {
+ let to_insert = String::from("Hello, world!");
+ e = Evil { values: RefCell::new(Vec::new()), to_insert: &to_insert };
+ let range = &e..=&e;
+ let _ = range == range;
+ values = e.values;
+ }
+ assert_eq!(*values.borrow(), Vec::<&str>::new());
+}
diff --git a/tests/ui/specialization/soundness/partial_ord_slice.rs b/tests/ui/specialization/soundness/partial_ord_slice.rs
new file mode 100644
index 000000000..b9e80a48d
--- /dev/null
+++ b/tests/ui/specialization/soundness/partial_ord_slice.rs
@@ -0,0 +1,42 @@
+// Check that we aren't using unsound specialization in slice comparisons.
+
+// run-pass
+
+use std::cell::Cell;
+use std::cmp::Ordering;
+
+struct Evil<'a, 'b>(Cell<(&'a [i32], &'b [i32])>);
+
+impl PartialEq for Evil<'_, '_> {
+ fn eq(&self, _other: &Self) -> bool {
+ true
+ }
+}
+
+impl Eq for Evil<'_, '_> {}
+
+impl PartialOrd for Evil<'_, '_> {
+ fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
+ Some(Ordering::Equal)
+ }
+}
+
+impl<'a> Ord for Evil<'a, 'a> {
+ fn cmp(&self, _other: &Self) -> Ordering {
+ let (a, b) = self.0.get();
+ self.0.set((b, a));
+ Ordering::Equal
+ }
+}
+
+fn main() {
+ let x = &[1, 2, 3, 4];
+ let u = {
+ let a = Box::new([7, 8, 9, 10]);
+ let y = [Evil(Cell::new((x, &*a)))];
+ let _ = &y[..] <= &y[..];
+ let [Evil(c)] = y;
+ c.get().0
+ };
+ assert_eq!(u, &[1, 2, 3, 4]);
+}
diff --git a/tests/ui/specialization/specialization-allowed-cross-crate.rs b/tests/ui/specialization/specialization-allowed-cross-crate.rs
new file mode 100644
index 000000000..5d67160eb
--- /dev/null
+++ b/tests/ui/specialization/specialization-allowed-cross-crate.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_imports)]
+
+// aux-build:go_trait.rs
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+extern crate go_trait;
+
+use go_trait::{Go,GoMut};
+use std::fmt::Debug;
+use std::default::Default;
+
+struct MyThingy;
+
+impl Go for MyThingy {
+ fn go(&self, arg: isize) { }
+}
+
+impl GoMut for MyThingy {
+ fn go_mut(&mut self, arg: isize) { }
+}
+
+fn main() { }
diff --git a/tests/ui/specialization/specialization-allowed-cross-crate.stderr b/tests/ui/specialization/specialization-allowed-cross-crate.stderr
new file mode 100644
index 000000000..3eea4a53b
--- /dev/null
+++ b/tests/ui/specialization/specialization-allowed-cross-crate.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-allowed-cross-crate.rs:8:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-assoc-fns.rs b/tests/ui/specialization/specialization-assoc-fns.rs
new file mode 100644
index 000000000..cbfcb4719
--- /dev/null
+++ b/tests/ui/specialization/specialization-assoc-fns.rs
@@ -0,0 +1,29 @@
+// run-pass
+
+// Test that non-method associated functions can be specialized
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo {
+ fn mk() -> Self;
+}
+
+impl<T: Default> Foo for T {
+ default fn mk() -> T {
+ T::default()
+ }
+}
+
+impl Foo for Vec<u8> {
+ fn mk() -> Vec<u8> {
+ vec![0]
+ }
+}
+
+fn main() {
+ let v1: Vec<i32> = Foo::mk();
+ let v2: Vec<u8> = Foo::mk();
+
+ assert!(v1.len() == 0);
+ assert!(v2.len() == 1);
+}
diff --git a/tests/ui/specialization/specialization-assoc-fns.stderr b/tests/ui/specialization/specialization-assoc-fns.stderr
new file mode 100644
index 000000000..69f7cece7
--- /dev/null
+++ b/tests/ui/specialization/specialization-assoc-fns.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-assoc-fns.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-basics.rs b/tests/ui/specialization/specialization-basics.rs
new file mode 100644
index 000000000..721c934db
--- /dev/null
+++ b/tests/ui/specialization/specialization-basics.rs
@@ -0,0 +1,98 @@
+// run-pass
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Tests a variety of basic specialization scenarios and method
+// dispatch for them.
+
+trait Foo {
+ fn foo(&self) -> &'static str;
+}
+
+impl<T> Foo for T {
+ default fn foo(&self) -> &'static str {
+ "generic"
+ }
+}
+
+impl<T: Clone> Foo for T {
+ default fn foo(&self) -> &'static str {
+ "generic Clone"
+ }
+}
+
+impl<T, U> Foo for (T, U) where T: Clone, U: Clone {
+ default fn foo(&self) -> &'static str {
+ "generic pair"
+ }
+}
+
+impl<T: Clone> Foo for (T, T) {
+ default fn foo(&self) -> &'static str {
+ "generic uniform pair"
+ }
+}
+
+impl Foo for (u8, u32) {
+ default fn foo(&self) -> &'static str {
+ "(u8, u32)"
+ }
+}
+
+impl Foo for (u8, u8) {
+ default fn foo(&self) -> &'static str {
+ "(u8, u8)"
+ }
+}
+
+impl<T: Clone> Foo for Vec<T> {
+ default fn foo(&self) -> &'static str {
+ "generic Vec"
+ }
+}
+
+impl Foo for Vec<i32> {
+ fn foo(&self) -> &'static str {
+ "Vec<i32>"
+ }
+}
+
+impl Foo for String {
+ fn foo(&self) -> &'static str {
+ "String"
+ }
+}
+
+impl Foo for i32 {
+ fn foo(&self) -> &'static str {
+ "i32"
+ }
+}
+
+struct NotClone;
+
+trait MyMarker {}
+impl<T: Clone + MyMarker> Foo for T {
+ default fn foo(&self) -> &'static str {
+ "generic Clone + MyMarker"
+ }
+}
+
+#[derive(Clone)]
+struct MarkedAndClone;
+impl MyMarker for MarkedAndClone {}
+
+fn main() {
+ assert!(NotClone.foo() == "generic");
+ assert!(0u8.foo() == "generic Clone");
+ assert!(vec![NotClone].foo() == "generic");
+ assert!(vec![0u8].foo() == "generic Vec");
+ assert!(vec![0i32].foo() == "Vec<i32>");
+ assert!(0i32.foo() == "i32");
+ assert!(String::new().foo() == "String");
+ assert!(((), 0).foo() == "generic pair");
+ assert!(((), ()).foo() == "generic uniform pair");
+ assert!((0u8, 0u32).foo() == "(u8, u32)");
+ assert!((0u8, 0u8).foo() == "(u8, u8)");
+ assert!(MarkedAndClone.foo() == "generic Clone + MyMarker");
+}
diff --git a/tests/ui/specialization/specialization-basics.stderr b/tests/ui/specialization/specialization-basics.stderr
new file mode 100644
index 000000000..7714d4af4
--- /dev/null
+++ b/tests/ui/specialization/specialization-basics.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-basics.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-cross-crate-no-gate.rs b/tests/ui/specialization/specialization-cross-crate-no-gate.rs
new file mode 100644
index 000000000..f744b16de
--- /dev/null
+++ b/tests/ui/specialization/specialization-cross-crate-no-gate.rs
@@ -0,0 +1,21 @@
+// run-pass
+
+// Test that specialization works even if only the upstream crate enables it
+
+// aux-build:specialization_cross_crate.rs
+
+extern crate specialization_cross_crate;
+
+use specialization_cross_crate::*;
+
+fn main() {
+ assert!(0u8.foo() == "generic Clone");
+ assert!(vec![0u8].foo() == "generic Vec");
+ assert!(vec![0i32].foo() == "Vec<i32>");
+ assert!(0i32.foo() == "i32");
+ assert!(String::new().foo() == "String");
+ assert!(((), 0).foo() == "generic pair");
+ assert!(((), ()).foo() == "generic uniform pair");
+ assert!((0u8, 0u32).foo() == "(u8, u32)");
+ assert!((0u8, 0u8).foo() == "(u8, u8)");
+}
diff --git a/tests/ui/specialization/specialization-cross-crate.rs b/tests/ui/specialization/specialization-cross-crate.rs
new file mode 100644
index 000000000..d9381d661
--- /dev/null
+++ b/tests/ui/specialization/specialization-cross-crate.rs
@@ -0,0 +1,50 @@
+// run-pass
+
+// aux-build:specialization_cross_crate.rs
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+extern crate specialization_cross_crate;
+
+use specialization_cross_crate::*;
+
+struct NotClone;
+
+#[derive(Clone)]
+struct MarkedAndClone;
+impl MyMarker for MarkedAndClone {}
+
+struct MyType<T>(#[allow(unused_tuple_struct_fields)] T);
+impl<T> Foo for MyType<T> {
+ default fn foo(&self) -> &'static str {
+ "generic MyType"
+ }
+}
+
+impl Foo for MyType<u8> {
+ fn foo(&self) -> &'static str {
+ "MyType<u8>"
+ }
+}
+
+struct MyOtherType;
+impl Foo for MyOtherType {}
+
+fn main() {
+ assert!(NotClone.foo() == "generic");
+ assert!(0u8.foo() == "generic Clone");
+ assert!(vec![NotClone].foo() == "generic");
+ assert!(vec![0u8].foo() == "generic Vec");
+ assert!(vec![0i32].foo() == "Vec<i32>");
+ assert!(0i32.foo() == "i32");
+ assert!(String::new().foo() == "String");
+ assert!(((), 0).foo() == "generic pair");
+ assert!(((), ()).foo() == "generic uniform pair");
+ assert!((0u8, 0u32).foo() == "(u8, u32)");
+ assert!((0u8, 0u8).foo() == "(u8, u8)");
+ assert!(MarkedAndClone.foo() == "generic Clone + MyMarker");
+
+ assert!(MyType(()).foo() == "generic MyType");
+ assert!(MyType(0u8).foo() == "MyType<u8>");
+ assert!(MyOtherType.foo() == "generic");
+}
diff --git a/tests/ui/specialization/specialization-cross-crate.stderr b/tests/ui/specialization/specialization-cross-crate.stderr
new file mode 100644
index 000000000..06818bb56
--- /dev/null
+++ b/tests/ui/specialization/specialization-cross-crate.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-cross-crate.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-default-methods.rs b/tests/ui/specialization/specialization-default-methods.rs
new file mode 100644
index 000000000..dcf68afa9
--- /dev/null
+++ b/tests/ui/specialization/specialization-default-methods.rs
@@ -0,0 +1,87 @@
+// run-pass
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Test that default methods are cascaded correctly
+
+// First, test only use of explicit `default` items:
+
+trait Foo {
+ fn foo(&self) -> bool;
+}
+
+// Specialization tree for Foo:
+//
+// T
+// / \
+// i32 i64
+
+impl<T> Foo for T {
+ default fn foo(&self) -> bool { false }
+}
+
+impl Foo for i32 {}
+
+impl Foo for i64 {
+ fn foo(&self) -> bool { true }
+}
+
+fn test_foo() {
+ assert!(!0i8.foo());
+ assert!(!0i32.foo());
+ assert!(0i64.foo());
+}
+
+// Next, test mixture of explicit `default` and provided methods:
+
+trait Bar {
+ fn bar(&self) -> i32 { 0 }
+}
+
+// Specialization tree for Bar.
+// Uses of $ designate that method is provided
+//
+// $Bar (the trait)
+// |
+// T
+// /|\
+// / | \
+// / | \
+// / | \
+// / | \
+// / | \
+// $i32 &str $Vec<T>
+// /\
+// / \
+// Vec<i32> $Vec<i64>
+
+impl<T> Bar for T {
+ default fn bar(&self) -> i32 { 0 }
+}
+
+impl Bar for i32 {
+ fn bar(&self) -> i32 { 1 }
+}
+impl<'a> Bar for &'a str {}
+
+impl<T> Bar for Vec<T> {
+ default fn bar(&self) -> i32 { 2 }
+}
+impl Bar for Vec<i32> {}
+impl Bar for Vec<i64> {
+ fn bar(&self) -> i32 { 3 }
+}
+
+fn test_bar() {
+ assert!(0u8.bar() == 0);
+ assert!(0i32.bar() == 1);
+ assert!("hello".bar() == 0);
+ assert!(vec![()].bar() == 2);
+ assert!(vec![0i32].bar() == 2);
+ assert!(vec![0i64].bar() == 3);
+}
+
+fn main() {
+ test_foo();
+ test_bar();
+}
diff --git a/tests/ui/specialization/specialization-default-methods.stderr b/tests/ui/specialization/specialization-default-methods.stderr
new file mode 100644
index 000000000..d78d30bd8
--- /dev/null
+++ b/tests/ui/specialization/specialization-default-methods.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-default-methods.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-default-projection.rs b/tests/ui/specialization/specialization-default-projection.rs
new file mode 100644
index 000000000..7f3ae9512
--- /dev/null
+++ b/tests/ui/specialization/specialization-default-projection.rs
@@ -0,0 +1,36 @@
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Make sure we can't project defaulted associated types
+
+trait Foo {
+ type Assoc;
+}
+
+impl<T> Foo for T {
+ default type Assoc = ();
+}
+
+impl Foo for u8 {
+ type Assoc = String;
+}
+
+fn generic<T>() -> <T as Foo>::Assoc {
+ // `T` could be some downstream crate type that specializes (or,
+ // for that matter, `u8`).
+
+ () //~ ERROR mismatched types
+}
+
+fn monomorphic() -> () {
+ // Even though we know that `()` is not specialized in a
+ // downstream crate, typeck refuses to project here.
+
+ generic::<()>() //~ ERROR mismatched types
+}
+
+fn main() {
+ // No error here, we CAN project from `u8`, as there is no `default`
+ // in that impl.
+ let s: String = generic::<u8>();
+ println!("{}", s); // bad news if this all compiles
+}
diff --git a/tests/ui/specialization/specialization-default-projection.stderr b/tests/ui/specialization/specialization-default-projection.stderr
new file mode 100644
index 000000000..b8b81876d
--- /dev/null
+++ b/tests/ui/specialization/specialization-default-projection.stderr
@@ -0,0 +1,43 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-default-projection.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+ --> $DIR/specialization-default-projection.rs:21:5
+ |
+LL | fn generic<T>() -> <T as Foo>::Assoc {
+ | ----------------- expected `<T as Foo>::Assoc` because of return type
+...
+LL | ()
+ | ^^ expected associated type, found `()`
+ |
+ = note: expected associated type `<T as Foo>::Assoc`
+ found unit type `()`
+ = help: consider constraining the associated type `<T as Foo>::Assoc` to `()` or calling a method that returns `<T as Foo>::Assoc`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error[E0308]: mismatched types
+ --> $DIR/specialization-default-projection.rs:28:5
+ |
+LL | fn monomorphic() -> () {
+ | -- expected `()` because of return type
+...
+LL | generic::<()>()
+ | ^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;`
+ | |
+ | expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<() as Foo>::Assoc`
+ = help: consider constraining the associated type `<() as Foo>::Assoc` to `()`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/specialization/specialization-default-types.rs b/tests/ui/specialization/specialization-default-types.rs
new file mode 100644
index 000000000..346471f11
--- /dev/null
+++ b/tests/ui/specialization/specialization-default-types.rs
@@ -0,0 +1,35 @@
+// It should not be possible to use the concrete value of a defaulted
+// associated type in the impl defining it -- otherwise, what happens
+// if it's overridden?
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Example {
+ type Output;
+ fn generate(self) -> Self::Output;
+}
+
+impl<T> Example for T {
+ default type Output = Box<T>;
+ default fn generate(self) -> Self::Output {
+ Box::new(self) //~ ERROR mismatched types
+ }
+}
+
+impl Example for bool {
+ type Output = bool;
+ fn generate(self) -> bool { self }
+}
+
+fn trouble<T>(t: T) -> Box<T> {
+ Example::generate(t) //~ ERROR mismatched types
+}
+
+fn weaponize() -> bool {
+ let b: Box<bool> = trouble(true);
+ *b
+}
+
+fn main() {
+ weaponize();
+}
diff --git a/tests/ui/specialization/specialization-default-types.stderr b/tests/ui/specialization/specialization-default-types.stderr
new file mode 100644
index 000000000..61a556a93
--- /dev/null
+++ b/tests/ui/specialization/specialization-default-types.stderr
@@ -0,0 +1,39 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-default-types.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+ --> $DIR/specialization-default-types.rs:15:9
+ |
+LL | default type Output = Box<T>;
+ | ----------------------------- expected this associated type
+LL | default fn generate(self) -> Self::Output {
+ | ------------ expected `<T as Example>::Output` because of return type
+LL | Box::new(self)
+ | ^^^^^^^^^^^^^^ expected associated type, found struct `Box`
+ |
+ = note: expected associated type `<T as Example>::Output`
+ found struct `Box<T>`
+
+error[E0308]: mismatched types
+ --> $DIR/specialization-default-types.rs:25:5
+ |
+LL | fn trouble<T>(t: T) -> Box<T> {
+ | ------ expected `Box<T>` because of return type
+LL | Example::generate(t)
+ | ^^^^^^^^^^^^^^^^^^^^ expected struct `Box`, found associated type
+ |
+ = note: expected struct `Box<T>`
+ found associated type `<T as Example>::Output`
+ = help: consider constraining the associated type `<T as Example>::Output` to `Box<T>`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/specialization/specialization-feature-gate-default.rs b/tests/ui/specialization/specialization-feature-gate-default.rs
new file mode 100644
index 000000000..8bad3ac0a
--- /dev/null
+++ b/tests/ui/specialization/specialization-feature-gate-default.rs
@@ -0,0 +1,13 @@
+// Check that specialization must be ungated to use the `default` keyword
+
+// gate-test-specialization
+
+trait Foo {
+ fn foo(&self);
+}
+
+impl<T> Foo for T {
+ default fn foo(&self) {} //~ ERROR specialization is unstable
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-feature-gate-default.stderr b/tests/ui/specialization/specialization-feature-gate-default.stderr
new file mode 100644
index 000000000..42dbb200c
--- /dev/null
+++ b/tests/ui/specialization/specialization-feature-gate-default.stderr
@@ -0,0 +1,12 @@
+error[E0658]: specialization is unstable
+ --> $DIR/specialization-feature-gate-default.rs:10:5
+ |
+LL | default fn foo(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: add `#![feature(specialization)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/specialization/specialization-feature-gate-overlap.rs b/tests/ui/specialization/specialization-feature-gate-overlap.rs
new file mode 100644
index 000000000..b83c84ab8
--- /dev/null
+++ b/tests/ui/specialization/specialization-feature-gate-overlap.rs
@@ -0,0 +1,17 @@
+// Check that writing an overlapping impl is not allow unless specialization is ungated.
+
+// gate-test-specialization
+
+trait Foo {
+ fn foo(&self);
+}
+
+impl<T> Foo for T {
+ fn foo(&self) {}
+}
+
+impl Foo for u8 { //~ ERROR E0119
+ fn foo(&self) {}
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-feature-gate-overlap.stderr b/tests/ui/specialization/specialization-feature-gate-overlap.stderr
new file mode 100644
index 000000000..9157ad0d4
--- /dev/null
+++ b/tests/ui/specialization/specialization-feature-gate-overlap.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `Foo` for type `u8`
+ --> $DIR/specialization-feature-gate-overlap.rs:13:1
+ |
+LL | impl<T> Foo for T {
+ | ----------------- first implementation here
+...
+LL | impl Foo for u8 {
+ | ^^^^^^^^^^^^^^^ conflicting implementation for `u8`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/specialization-no-default.rs b/tests/ui/specialization/specialization-no-default.rs
new file mode 100644
index 000000000..ae739b235
--- /dev/null
+++ b/tests/ui/specialization/specialization-no-default.rs
@@ -0,0 +1,77 @@
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Check a number of scenarios in which one impl tries to override another,
+// without correctly using `default`.
+
+// Test 1: one layer of specialization, multiple methods, missing `default`
+
+trait Foo {
+ fn foo(&self);
+ fn bar(&self);
+}
+
+impl<T> Foo for T {
+ fn foo(&self) {}
+ fn bar(&self) {}
+}
+
+impl Foo for u8 {}
+impl Foo for u16 {
+ fn foo(&self) {} //~ ERROR E0520
+}
+impl Foo for u32 {
+ fn bar(&self) {} //~ ERROR E0520
+}
+
+// Test 2: one layer of specialization, missing `default` on associated type
+
+trait Bar {
+ type T;
+}
+
+impl<T> Bar for T {
+ type T = u8;
+}
+
+impl Bar for u8 {
+ type T = (); //~ ERROR E0520
+}
+
+// Test 3a: multiple layers of specialization, missing interior `default`
+
+trait Baz {
+ fn baz(&self);
+}
+
+impl<T> Baz for T {
+ default fn baz(&self) {}
+}
+
+impl<T: Clone> Baz for T {
+ fn baz(&self) {}
+}
+
+impl Baz for i32 {
+ fn baz(&self) {} //~ ERROR E0520
+}
+
+// Test 3b: multiple layers of specialization, missing interior `default`,
+// redundant `default` in bottom layer.
+
+trait Redundant {
+ fn redundant(&self);
+}
+
+impl<T> Redundant for T {
+ default fn redundant(&self) {}
+}
+
+impl<T: Clone> Redundant for T {
+ fn redundant(&self) {}
+}
+
+impl Redundant for i32 {
+ default fn redundant(&self) {} //~ ERROR E0520
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-no-default.stderr b/tests/ui/specialization/specialization-no-default.stderr
new file mode 100644
index 000000000..842cec9c7
--- /dev/null
+++ b/tests/ui/specialization/specialization-no-default.stderr
@@ -0,0 +1,68 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-no-default.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:20:5
+ |
+LL | impl<T> Foo for T {
+ | ----------------- parent `impl` is here
+...
+LL | fn foo(&self) {}
+ | ^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
+ |
+ = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error[E0520]: `bar` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:23:5
+ |
+LL | impl<T> Foo for T {
+ | ----------------- parent `impl` is here
+...
+LL | fn bar(&self) {}
+ | ^^^^^^^^^^^^^^^^ cannot specialize default item `bar`
+ |
+ = note: to specialize, `bar` in the parent `impl` must be marked `default`
+
+error[E0520]: `T` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:37:5
+ |
+LL | impl<T> Bar for T {
+ | ----------------- parent `impl` is here
+...
+LL | type T = ();
+ | ^^^^^^^^^^^^ cannot specialize default item `T`
+ |
+ = note: to specialize, `T` in the parent `impl` must be marked `default`
+
+error[E0520]: `baz` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:55:5
+ |
+LL | impl<T: Clone> Baz for T {
+ | ------------------------ parent `impl` is here
+...
+LL | fn baz(&self) {}
+ | ^^^^^^^^^^^^^^^^ cannot specialize default item `baz`
+ |
+ = note: to specialize, `baz` in the parent `impl` must be marked `default`
+
+error[E0520]: `redundant` specializes an item from a parent `impl`, but that item is not marked `default`
+ --> $DIR/specialization-no-default.rs:74:5
+ |
+LL | impl<T: Clone> Redundant for T {
+ | ------------------------------ parent `impl` is here
+...
+LL | default fn redundant(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant`
+ |
+ = note: to specialize, `redundant` in the parent `impl` must be marked `default`
+
+error: aborting due to 5 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0520`.
diff --git a/tests/ui/specialization/specialization-on-projection.rs b/tests/ui/specialization/specialization-on-projection.rs
new file mode 100644
index 000000000..be8dcc423
--- /dev/null
+++ b/tests/ui/specialization/specialization-on-projection.rs
@@ -0,0 +1,24 @@
+// run-pass
+#![allow(dead_code)]
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Ensure that specialization works for impls defined directly on a projection
+
+trait Foo<T> {}
+
+trait Assoc {
+ type Item;
+}
+
+impl<T: Assoc> Foo<T::Item> for T {}
+
+struct Struct;
+
+impl Assoc for Struct {
+ type Item = u8;
+}
+
+impl Foo<u8> for Struct {}
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-on-projection.stderr b/tests/ui/specialization/specialization-on-projection.stderr
new file mode 100644
index 000000000..00fc7ffc5
--- /dev/null
+++ b/tests/ui/specialization/specialization-on-projection.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-on-projection.rs:4:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-out-of-order.rs b/tests/ui/specialization/specialization-out-of-order.rs
new file mode 100644
index 000000000..cb7563e27
--- /dev/null
+++ b/tests/ui/specialization/specialization-out-of-order.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+// Test that you can list the more specific impl before the more general one.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo {
+ type Out;
+}
+
+impl Foo for bool {
+ type Out = ();
+}
+
+impl<T> Foo for T {
+ default type Out = bool;
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-out-of-order.stderr b/tests/ui/specialization/specialization-out-of-order.stderr
new file mode 100644
index 000000000..b524e00f0
--- /dev/null
+++ b/tests/ui/specialization/specialization-out-of-order.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-out-of-order.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-overlap-hygiene.rs b/tests/ui/specialization/specialization-overlap-hygiene.rs
new file mode 100644
index 000000000..93e7c8325
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap-hygiene.rs
@@ -0,0 +1,23 @@
+#![feature(decl_macro)]
+
+struct X;
+
+macro_rules! define_f_legacy { () => {
+ fn f() {}
+}}
+macro define_g_modern() {
+ fn g() {}
+}
+
+impl X {
+ fn f() {} //~ ERROR duplicate definitions with name `f`
+ fn g() {} // OK
+}
+impl X {
+ define_f_legacy!();
+}
+impl X {
+ define_g_modern!();
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-overlap-hygiene.stderr b/tests/ui/specialization/specialization-overlap-hygiene.stderr
new file mode 100644
index 000000000..81efd46cc
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap-hygiene.stderr
@@ -0,0 +1,12 @@
+error[E0592]: duplicate definitions with name `f`
+ --> $DIR/specialization-overlap-hygiene.rs:13:4
+ |
+LL | fn f() {}
+ | ------ other definition for `f`
+...
+LL | fn f() {}
+ | ^^^^^^ duplicate definitions for `f`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0592`.
diff --git a/tests/ui/specialization/specialization-overlap-negative.rs b/tests/ui/specialization/specialization-overlap-negative.rs
new file mode 100644
index 000000000..550d37082
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap-negative.rs
@@ -0,0 +1,11 @@
+#![feature(negative_impls)]
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait MyTrait {}
+
+struct TestType<T>(::std::marker::PhantomData<T>);
+
+unsafe impl<T: Clone> Send for TestType<T> {}
+impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0751
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-overlap-negative.stderr b/tests/ui/specialization/specialization-overlap-negative.stderr
new file mode 100644
index 000000000..1fe4869ff
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap-negative.stderr
@@ -0,0 +1,21 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-overlap-negative.rs:2:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
+ --> $DIR/specialization-overlap-negative.rs:9:1
+ |
+LL | unsafe impl<T: Clone> Send for TestType<T> {}
+ | ------------------------------------------ positive implementation here
+LL | impl<T: MyTrait> !Send for TestType<T> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0751`.
diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs
new file mode 100644
index 000000000..b07efb2a5
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap-projection.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+// Test that impls on projected self types can resolve overlap, even when the
+// projections involve specialization, so long as the associated type is
+// provided by the most specialized impl.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Assoc {
+ type Output;
+}
+
+impl<T> Assoc for T {
+ default type Output = bool;
+}
+
+impl Assoc for u8 { type Output = u8; }
+impl Assoc for u16 { type Output = u16; }
+
+trait Foo {}
+impl Foo for u32 {}
+impl Foo for <u8 as Assoc>::Output {}
+impl Foo for <u16 as Assoc>::Output {}
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-overlap-projection.stderr b/tests/ui/specialization/specialization-overlap-projection.stderr
new file mode 100644
index 000000000..708c0817f
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap-projection.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-overlap-projection.rs:7:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-overlap.rs b/tests/ui/specialization/specialization-overlap.rs
new file mode 100644
index 000000000..6bee22ceb
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap.rs
@@ -0,0 +1,19 @@
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Foo { fn foo() {} }
+impl<T: Clone> Foo for T {}
+impl<T> Foo for Vec<T> {} //~ ERROR E0119
+
+trait Bar { fn bar() {} }
+impl<T> Bar for (T, u8) {}
+impl<T> Bar for (u8, T) {} //~ ERROR E0119
+
+trait Baz<U> { fn baz() {} }
+impl<T> Baz<T> for u8 {}
+impl<T> Baz<u8> for T {} //~ ERROR E0119
+
+trait Qux { fn qux() {} }
+impl<T: Clone> Qux for T {}
+impl<T: Eq> Qux for T {} //~ ERROR E0119
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-overlap.stderr b/tests/ui/specialization/specialization-overlap.stderr
new file mode 100644
index 000000000..098bf4a70
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap.stderr
@@ -0,0 +1,45 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-overlap.rs:1:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0119]: conflicting implementations of trait `Foo` for type `Vec<_>`
+ --> $DIR/specialization-overlap.rs:5:1
+ |
+LL | impl<T: Clone> Foo for T {}
+ | ------------------------ first implementation here
+LL | impl<T> Foo for Vec<T> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Vec<_>`
+
+error[E0119]: conflicting implementations of trait `Bar` for type `(u8, u8)`
+ --> $DIR/specialization-overlap.rs:9:1
+ |
+LL | impl<T> Bar for (T, u8) {}
+ | ----------------------- first implementation here
+LL | impl<T> Bar for (u8, T) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(u8, u8)`
+
+error[E0119]: conflicting implementations of trait `Baz<u8>` for type `u8`
+ --> $DIR/specialization-overlap.rs:13:1
+ |
+LL | impl<T> Baz<T> for u8 {}
+ | --------------------- first implementation here
+LL | impl<T> Baz<u8> for T {}
+ | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8`
+
+error[E0119]: conflicting implementations of trait `Qux`
+ --> $DIR/specialization-overlap.rs:17:1
+ |
+LL | impl<T: Clone> Qux for T {}
+ | ------------------------ first implementation here
+LL | impl<T: Eq> Qux for T {}
+ | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
+error: aborting due to 4 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/specialization-polarity.rs b/tests/ui/specialization/specialization-polarity.rs
new file mode 100644
index 000000000..b3cd8255b
--- /dev/null
+++ b/tests/ui/specialization/specialization-polarity.rs
@@ -0,0 +1,17 @@
+// Make sure specialization cannot change impl polarity
+
+#![feature(auto_traits)]
+#![feature(negative_impls)]
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+auto trait Foo {}
+
+impl<T> Foo for T {}
+impl !Foo for u8 {} //~ ERROR E0751
+
+auto trait Bar {}
+
+impl<T> !Bar for T {}
+impl Bar for u8 {} //~ ERROR E0751
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-polarity.stderr b/tests/ui/specialization/specialization-polarity.stderr
new file mode 100644
index 000000000..f287018ba
--- /dev/null
+++ b/tests/ui/specialization/specialization-polarity.stderr
@@ -0,0 +1,29 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-polarity.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0751]: found both positive and negative implementation of trait `Foo` for type `u8`:
+ --> $DIR/specialization-polarity.rs:10:1
+ |
+LL | impl<T> Foo for T {}
+ | ----------------- positive implementation here
+LL | impl !Foo for u8 {}
+ | ^^^^^^^^^^^^^^^^ negative implementation here
+
+error[E0751]: found both positive and negative implementation of trait `Bar` for type `u8`:
+ --> $DIR/specialization-polarity.rs:15:1
+ |
+LL | impl<T> !Bar for T {}
+ | ------------------ negative implementation here
+LL | impl Bar for u8 {}
+ | ^^^^^^^^^^^^^^^ positive implementation here
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0751`.
diff --git a/tests/ui/specialization/specialization-projection-alias.rs b/tests/ui/specialization/specialization-projection-alias.rs
new file mode 100644
index 000000000..f1f0b47bb
--- /dev/null
+++ b/tests/ui/specialization/specialization-projection-alias.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Regression test for ICE when combining specialized associated types and type
+// aliases
+
+trait Id_ {
+ type Out;
+}
+
+type Id<T> = <T as Id_>::Out;
+
+impl<T> Id_ for T {
+ default type Out = T;
+}
+
+fn test_proection() {
+ let x: Id<bool> = panic!();
+}
+
+fn main() {
+
+}
diff --git a/tests/ui/specialization/specialization-projection-alias.stderr b/tests/ui/specialization/specialization-projection-alias.stderr
new file mode 100644
index 000000000..c94d9ed07
--- /dev/null
+++ b/tests/ui/specialization/specialization-projection-alias.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-projection-alias.rs:5:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-projection.rs b/tests/ui/specialization/specialization-projection.rs
new file mode 100644
index 000000000..78afe7a94
--- /dev/null
+++ b/tests/ui/specialization/specialization-projection.rs
@@ -0,0 +1,42 @@
+// run-pass
+#![allow(dead_code)]
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Make sure we *can* project non-defaulted associated types
+// cf ui/specialization/specialization-default-projection.rs
+
+// First, do so without any use of specialization
+
+trait Foo {
+ type Assoc;
+}
+
+impl<T> Foo for T {
+ type Assoc = ();
+}
+
+fn generic_foo<T>() -> <T as Foo>::Assoc {
+ ()
+}
+
+// Next, allow for one layer of specialization
+
+trait Bar {
+ type Assoc;
+}
+
+impl<T> Bar for T {
+ default type Assoc = ();
+}
+
+impl<T: Clone> Bar for T {
+ type Assoc = u8;
+}
+
+fn generic_bar_clone<T: Clone>() -> <T as Bar>::Assoc {
+ 0u8
+}
+
+fn main() {
+}
diff --git a/tests/ui/specialization/specialization-projection.stderr b/tests/ui/specialization/specialization-projection.stderr
new file mode 100644
index 000000000..bfc4e0a0f
--- /dev/null
+++ b/tests/ui/specialization/specialization-projection.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-projection.rs:4:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-supertraits.rs b/tests/ui/specialization/specialization-supertraits.rs
new file mode 100644
index 000000000..fb85d8019
--- /dev/null
+++ b/tests/ui/specialization/specialization-supertraits.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+// Test that you can specialize via an explicit trait hierarchy
+
+// FIXME: this doesn't work yet...
+
+trait Parent {}
+trait Child: Parent {}
+
+trait Foo {}
+
+impl<T: Parent> Foo for T {}
+impl<T: Child> Foo for T {}
+
+fn main() {}
diff --git a/tests/ui/specialization/specialization-supertraits.stderr b/tests/ui/specialization/specialization-supertraits.stderr
new file mode 100644
index 000000000..e716bc215
--- /dev/null
+++ b/tests/ui/specialization/specialization-supertraits.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-supertraits.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-translate-projections-with-lifetimes.rs b/tests/ui/specialization/specialization-translate-projections-with-lifetimes.rs
new file mode 100644
index 000000000..904aeaa08
--- /dev/null
+++ b/tests/ui/specialization/specialization-translate-projections-with-lifetimes.rs
@@ -0,0 +1,33 @@
+// run-pass
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Iterator {
+ fn next(&self);
+}
+
+trait WithAssoc {
+ type Item;
+}
+
+impl<'a> WithAssoc for &'a () {
+ type Item = &'a u32;
+}
+
+struct Cloned<I>(#[allow(unused_tuple_struct_fields)] I);
+
+impl<'a, I, T: 'a> Iterator for Cloned<I>
+ where I: WithAssoc<Item=&'a T>, T: Clone
+{
+ fn next(&self) {}
+}
+
+impl<'a, I, T: 'a> Iterator for Cloned<I>
+ where I: WithAssoc<Item=&'a T>, T: Copy
+{
+
+}
+
+fn main() {
+ Cloned(&()).next();
+}
diff --git a/tests/ui/specialization/specialization-translate-projections-with-lifetimes.stderr b/tests/ui/specialization/specialization-translate-projections-with-lifetimes.stderr
new file mode 100644
index 000000000..c7aad3c0f
--- /dev/null
+++ b/tests/ui/specialization/specialization-translate-projections-with-lifetimes.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-translate-projections-with-lifetimes.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-translate-projections-with-params.rs b/tests/ui/specialization/specialization-translate-projections-with-params.rs
new file mode 100644
index 000000000..62d63590a
--- /dev/null
+++ b/tests/ui/specialization/specialization-translate-projections-with-params.rs
@@ -0,0 +1,32 @@
+// run-pass
+
+// Ensure that provided items are inherited properly even when impls vary in
+// type parameters *and* rely on projections, and the type parameters are input
+// types on the trait.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Trait<T> {
+ fn convert(&self) -> T;
+}
+trait WithAssoc {
+ type Item;
+ fn as_item(&self) -> &Self::Item;
+}
+
+impl<T, U> Trait<U> for T where T: WithAssoc<Item=U>, U: Clone {
+ fn convert(&self) -> U {
+ self.as_item().clone()
+ }
+}
+
+impl WithAssoc for u8 {
+ type Item = u8;
+ fn as_item(&self) -> &u8 { self }
+}
+
+impl Trait<u8> for u8 {}
+
+fn main() {
+ assert!(3u8.convert() == 3u8);
+}
diff --git a/tests/ui/specialization/specialization-translate-projections-with-params.stderr b/tests/ui/specialization/specialization-translate-projections-with-params.stderr
new file mode 100644
index 000000000..1c4fd9325
--- /dev/null
+++ b/tests/ui/specialization/specialization-translate-projections-with-params.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-translate-projections-with-params.rs:7:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/specialization-translate-projections.rs b/tests/ui/specialization/specialization-translate-projections.rs
new file mode 100644
index 000000000..92ea9e2b8
--- /dev/null
+++ b/tests/ui/specialization/specialization-translate-projections.rs
@@ -0,0 +1,33 @@
+// run-pass
+
+// Ensure that provided items are inherited properly even when impls vary in
+// type parameters *and* rely on projections.
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+use std::convert::Into;
+
+trait Trait {
+ fn to_u8(&self) -> u8;
+}
+trait WithAssoc {
+ type Item;
+ fn to_item(&self) -> Self::Item;
+}
+
+impl<T, U> Trait for T where T: WithAssoc<Item=U>, U: Into<u8> {
+ fn to_u8(&self) -> u8 {
+ self.to_item().into()
+ }
+}
+
+impl WithAssoc for u8 {
+ type Item = u8;
+ fn to_item(&self) -> u8 { *self }
+}
+
+impl Trait for u8 {}
+
+fn main() {
+ assert!(3u8.to_u8() == 3u8);
+}
diff --git a/tests/ui/specialization/specialization-translate-projections.stderr b/tests/ui/specialization/specialization-translate-projections.stderr
new file mode 100644
index 000000000..22bbb12a0
--- /dev/null
+++ b/tests/ui/specialization/specialization-translate-projections.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/specialization-translate-projections.rs:6:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/specialization/transmute-specialization.rs b/tests/ui/specialization/transmute-specialization.rs
new file mode 100644
index 000000000..499334d98
--- /dev/null
+++ b/tests/ui/specialization/transmute-specialization.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+
+trait Specializable { type Output; }
+
+impl<T> Specializable for T {
+ default type Output = u16;
+}
+
+fn main() {
+ unsafe {
+ std::mem::transmute::<u16, <() as Specializable>::Output>(0);
+ }
+}
diff --git a/tests/ui/specialization/transmute-specialization.stderr b/tests/ui/specialization/transmute-specialization.stderr
new file mode 100644
index 000000000..b1c26d7da
--- /dev/null
+++ b/tests/ui/specialization/transmute-specialization.stderr
@@ -0,0 +1,12 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/transmute-specialization.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+