about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorBryanskiy <ivakin.kir@gmail.com>2025-03-06 20:36:44 +0300
committerBryanskiy <ivakin.kir@gmail.com>2025-04-03 14:59:39 +0300
commit581c5fbc40f9f242f75924153199759f0009e3ac (patch)
tree49f057bd466a966f817f7bc8565747b93f32a068 /tests
parent79de6c0bbe76904ac7086b05327ee5756fb302b1 (diff)
downloadrust-581c5fbc40f9f242f75924153199759f0009e3ac.tar.gz
rust-581c5fbc40f9f242f75924153199759f0009e3ac.zip
Initial support for auto traits with default bounds
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs25
-rw-r--r--tests/ui/traits/default_auto_traits/default-bounds.rs41
-rw-r--r--tests/ui/traits/default_auto_traits/default-bounds.stderr31
-rw-r--r--tests/ui/traits/default_auto_traits/extern-types.current.stderr17
-rw-r--r--tests/ui/traits/default_auto_traits/extern-types.next.stderr17
-rw-r--r--tests/ui/traits/default_auto_traits/extern-types.rs49
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs61
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr23
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs115
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr71
10 files changed, 450 insertions, 0 deletions
diff --git a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs
new file mode 100644
index 00000000000..3818456d3a6
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+//@ compile-flags: -Zexperimental-default-bounds
+
+#![feature(auto_traits, lang_items, no_core, rustc_attrs, trait_alias)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "default_trait1"]
+auto trait DefaultTrait1 {}
+
+#[lang = "default_trait2"]
+auto trait DefaultTrait2 {}
+
+trait Trait<Rhs: ?Sized = Self> {}
+trait Trait1 : Trait {}
+
+trait Trait2 {
+    type Type;
+}
+trait Trait3<T> = Trait2<Type = T>;
+
+fn main() {}
diff --git a/tests/ui/traits/default_auto_traits/default-bounds.rs b/tests/ui/traits/default_auto_traits/default-bounds.rs
new file mode 100644
index 00000000000..64733a40034
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/default-bounds.rs
@@ -0,0 +1,41 @@
+//@ compile-flags: -Zexperimental-default-bounds
+
+#![feature(
+    auto_traits,
+    lang_items,
+    negative_impls,
+    no_core,
+    rustc_attrs
+)]
+#![allow(incomplete_features)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+pub trait Copy {}
+
+#[lang = "default_trait1"]
+auto trait Leak {}
+
+#[lang = "default_trait2"]
+auto trait SyncDrop {}
+
+struct Forbidden;
+
+impl !Leak for Forbidden {}
+impl !SyncDrop for Forbidden {}
+
+struct Accepted;
+
+fn bar<T: Leak>(_: T) {}
+
+fn main() {
+    // checking that bounds can be added explicitly
+    bar(Forbidden);
+    //~^ ERROR the trait bound `Forbidden: Leak` is not satisfied
+    //~| ERROR the trait bound `Forbidden: SyncDrop` is not satisfied
+    bar(Accepted);
+}
diff --git a/tests/ui/traits/default_auto_traits/default-bounds.stderr b/tests/ui/traits/default_auto_traits/default-bounds.stderr
new file mode 100644
index 00000000000..10fdcc43417
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/default-bounds.stderr
@@ -0,0 +1,31 @@
+error[E0277]: the trait bound `Forbidden: SyncDrop` is not satisfied
+  --> $DIR/default-bounds.rs:37:9
+   |
+LL |     bar(Forbidden);
+   |     --- ^^^^^^^^^ the trait `SyncDrop` is not implemented for `Forbidden`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `bar`
+  --> $DIR/default-bounds.rs:33:8
+   |
+LL | fn bar<T: Leak>(_: T) {}
+   |        ^ required by this bound in `bar`
+
+error[E0277]: the trait bound `Forbidden: Leak` is not satisfied
+  --> $DIR/default-bounds.rs:37:9
+   |
+LL |     bar(Forbidden);
+   |     --- ^^^^^^^^^ the trait `Leak` is not implemented for `Forbidden`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `bar`
+  --> $DIR/default-bounds.rs:33:11
+   |
+LL | fn bar<T: Leak>(_: T) {}
+   |           ^^^^ required by this bound in `bar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/default_auto_traits/extern-types.current.stderr b/tests/ui/traits/default_auto_traits/extern-types.current.stderr
new file mode 100644
index 00000000000..e1bd99b900f
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/extern-types.current.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied
+  --> $DIR/extern-types.rs:44:13
+   |
+LL |         foo(x);
+   |         --- ^ the trait `Leak` is not implemented for `extern_non_leak::Opaque`
+   |         |
+   |         required by a bound introduced by this call
+   |
+note: required by a bound in `foo`
+  --> $DIR/extern-types.rs:20:8
+   |
+LL | fn foo<T: ?Sized>(_: &T) {}
+   |        ^ required by this bound in `foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/default_auto_traits/extern-types.next.stderr b/tests/ui/traits/default_auto_traits/extern-types.next.stderr
new file mode 100644
index 00000000000..e1bd99b900f
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/extern-types.next.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied
+  --> $DIR/extern-types.rs:44:13
+   |
+LL |         foo(x);
+   |         --- ^ the trait `Leak` is not implemented for `extern_non_leak::Opaque`
+   |         |
+   |         required by a bound introduced by this call
+   |
+note: required by a bound in `foo`
+  --> $DIR/extern-types.rs:20:8
+   |
+LL | fn foo<T: ?Sized>(_: &T) {}
+   |        ^ required by this bound in `foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/default_auto_traits/extern-types.rs b/tests/ui/traits/default_auto_traits/extern-types.rs
new file mode 100644
index 00000000000..822d4c0637f
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/extern-types.rs
@@ -0,0 +1,49 @@
+//@  compile-flags:  -Zexperimental-default-bounds
+//@ revisions: current next
+//@ [next] compile-flags: -Znext-solver
+
+#![feature(auto_traits, extern_types, lang_items, negative_impls, no_core, rustc_attrs)]
+#![allow(incomplete_features)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+pub trait Copy {}
+
+#[lang = "default_trait1"]
+auto trait Leak {}
+
+// implicit T: Leak here
+fn foo<T: ?Sized>(_: &T) {}
+
+mod extern_leak {
+    use crate::*;
+
+    extern "C" {
+        type Opaque;
+    }
+
+    fn forward_extern_ty(x: &Opaque) {
+        // ok, extern type leak by default
+        crate::foo(x);
+    }
+}
+
+mod extern_non_leak {
+    use crate::*;
+
+    extern "C" {
+        type Opaque;
+    }
+
+    impl !Leak for Opaque {}
+    fn forward_extern_ty(x: &Opaque) {
+        foo(x);
+        //~^ ERROR: the trait bound `extern_non_leak::Opaque: Leak` is not satisfied
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs
new file mode 100644
index 00000000000..49f2faba146
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs
@@ -0,0 +1,61 @@
+//@ compile-flags: -Zexperimental-default-bounds
+
+#![feature(
+    auto_traits,
+    lang_items,
+    more_maybe_bounds,
+    negative_impls,
+    no_core,
+    rustc_attrs
+)]
+#![allow(internal_features)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+pub trait Copy {}
+impl<'a, T: ?Sized> Copy for &'a T {}
+
+#[lang = "legacy_receiver"]
+trait Receiver {}
+impl<T: ?Sized + ?Leak> Receiver for &T {}
+
+#[lang = "unsize"]
+trait Unsize<T: ?Sized + ?Leak> {}
+
+#[lang = "coerce_unsized"]
+trait CoerceUnsized<T: ?Leak + ?Sized> {}
+impl<'a, 'b: 'a, T: ?Sized + ?Leak + Unsize<U>, U: ?Sized + ?Leak> CoerceUnsized<&'a U> for &'b T {}
+
+#[lang = "dispatch_from_dyn"]
+trait DispatchFromDyn<T: ?Leak> {}
+impl<'a, T: ?Sized + ?Leak + Unsize<U>, U: ?Sized + ?Leak> DispatchFromDyn<&'a U> for &'a T {}
+
+#[lang = "default_trait1"]
+auto trait Leak {}
+
+struct NonLeakS;
+impl !Leak for NonLeakS {}
+struct LeakS;
+
+trait Trait {
+    fn leak_foo(&self) {}
+    fn maybe_leak_foo(&self) where Self: ?Leak {}
+}
+
+impl Trait for NonLeakS {}
+impl Trait for LeakS {}
+
+fn main() {
+    let _: &dyn Trait = &NonLeakS;
+    //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
+    let _: &dyn Trait = &LeakS;
+    let _: &(dyn Trait + ?Leak) = &LeakS;
+    let x: &(dyn Trait + ?Leak) = &NonLeakS;
+    x.leak_foo();
+    //~^ ERROR the trait bound `dyn Trait: Leak` is not satisfied
+    x.maybe_leak_foo();
+}
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr
new file mode 100644
index 00000000000..b7ffb66e60b
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:53:25
+   |
+LL |     let _: &dyn Trait = &NonLeakS;
+   |                         ^^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS`
+   |
+   = note: required for the cast from `&NonLeakS` to `&dyn Trait + Leak`
+
+error[E0277]: the trait bound `dyn Trait: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:58:7
+   |
+LL |     x.leak_foo();
+   |       ^^^^^^^^ the trait `Leak` is not implemented for `dyn Trait`
+   |
+note: required by a bound in `Trait::leak_foo`
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:45:5
+   |
+LL |     fn leak_foo(&self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs
new file mode 100644
index 00000000000..761f22d1be5
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs
@@ -0,0 +1,115 @@
+//@ compile-flags: -Zexperimental-default-bounds
+
+#![feature(
+    auto_traits,
+    associated_type_defaults,
+    generic_const_items,
+    lang_items,
+    more_maybe_bounds,
+    negative_impls,
+    no_core,
+    rustc_attrs
+)]
+#![allow(incomplete_features)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "legacy_receiver"]
+trait LegacyReceiver {}
+impl<T: ?Sized + ?Leak> LegacyReceiver for &T {}
+impl<T: ?Sized> LegacyReceiver for &mut T {}
+
+#[lang = "default_trait1"]
+auto trait Leak {}
+
+struct NonLeakS;
+impl !Leak for NonLeakS {}
+struct LeakS;
+
+mod supertraits {
+    use crate::*;
+
+    trait MaybeLeakT1: ?Leak {}
+    trait MaybeLeakT2 where Self: ?Leak {}
+
+    impl MaybeLeakT1 for NonLeakS {}
+    impl MaybeLeakT2 for NonLeakS {}
+}
+
+mod maybe_self_assoc_type {
+    use crate::*;
+
+    trait TestBase1<T: ?Sized> {}
+    trait TestBase2<T: ?Leak + ?Sized> {}
+
+    trait Test1<T> {
+        type MaybeLeakSelf: TestBase1<Self> where Self: ?Leak;
+        //~^ ERROR the trait bound `Self: Leak` is not satisfied
+        type LeakSelf: TestBase1<Self>;
+    }
+
+    trait Test2<T> {
+        type MaybeLeakSelf: TestBase2<Self> where Self: ?Leak;
+        type LeakSelf: TestBase2<Self>;
+    }
+
+    trait Test3 {
+        type Leak1 = LeakS;
+        type Leak2 = NonLeakS;
+        //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
+    }
+
+    trait Test4 {
+        type MaybeLeak1: ?Leak = LeakS;
+        type MaybeLeak2: ?Leak = NonLeakS;
+    }
+
+    trait Test5: ?Leak {
+        // ok, because assoc types have implicit where Self: Leak
+        type MaybeLeakSelf1: TestBase1<Self>;
+        type MaybeLeakSelf2: TestBase2<Self>;
+    }
+}
+
+mod maybe_self_assoc_const {
+    use crate::*;
+
+    const fn size_of<T: ?Sized>() -> usize {
+        0
+    }
+
+    trait Trait {
+        const CLeak: usize = size_of::<Self>();
+        const CNonLeak: usize = size_of::<Self>() where Self: ?Leak;
+        //~^ ERROR the trait bound `Self: Leak` is not satisfied
+    }
+}
+
+mod methods {
+    use crate::*;
+
+    trait Trait {
+        fn leak_foo(&self) {}
+        fn maybe_leak_foo(&self) where Self: ?Leak {}
+        fn mut_leak_foo(&mut self) {}
+        // there is no relax bound on corresponding Receiver impl
+        fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {}
+        //~^  `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types`
+    }
+
+    impl Trait for NonLeakS {}
+    impl Trait for LeakS {}
+
+    fn foo() {
+        LeakS.leak_foo();
+        LeakS.maybe_leak_foo();
+        NonLeakS.leak_foo();
+        //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
+        NonLeakS.maybe_leak_foo();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr
new file mode 100644
index 00000000000..3dd8418b100
--- /dev/null
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr
@@ -0,0 +1,71 @@
+error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:61:22
+   |
+LL |         type Leak2 = NonLeakS;
+   |                      ^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS`
+   |
+note: required by a bound in `Test3::Leak2`
+  --> $DIR/maybe-bounds-in-traits.rs:61:9
+   |
+LL |         type Leak2 = NonLeakS;
+   |         ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Test3::Leak2`
+
+error[E0277]: the trait bound `Self: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:49:29
+   |
+LL |         type MaybeLeakSelf: TestBase1<Self> where Self: ?Leak;
+   |                             ^^^^^^^^^^^^^^^ the trait `Leak` is not implemented for `Self`
+   |
+note: required by a bound in `TestBase1`
+  --> $DIR/maybe-bounds-in-traits.rs:45:21
+   |
+LL |     trait TestBase1<T: ?Sized> {}
+   |                     ^ required by this bound in `TestBase1`
+help: consider further restricting `Self`
+   |
+LL |     trait Test1<T>: Leak {
+   |                   ++++++
+
+error[E0658]: `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+  --> $DIR/maybe-bounds-in-traits.rs:99:31
+   |
+LL |         fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {}
+   |                               ^^^^^^^^^
+   |
+   = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
+   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
+
+error[E0277]: the trait bound `Self: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:86:43
+   |
+LL |         const CNonLeak: usize = size_of::<Self>() where Self: ?Leak;
+   |                                           ^^^^ the trait `Leak` is not implemented for `Self`
+   |
+note: required by a bound in `size_of`
+  --> $DIR/maybe-bounds-in-traits.rs:80:22
+   |
+LL |     const fn size_of<T: ?Sized>() -> usize {
+   |                      ^ required by this bound in `size_of`
+help: consider further restricting `Self`
+   |
+LL |     trait Trait: Leak {
+   |                ++++++
+
+error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:109:18
+   |
+LL |         NonLeakS.leak_foo();
+   |                  ^^^^^^^^ the trait `Leak` is not implemented for `NonLeakS`
+   |
+note: required by a bound in `methods::Trait::leak_foo`
+  --> $DIR/maybe-bounds-in-traits.rs:95:9
+   |
+LL |         fn leak_foo(&self) {}
+   |         ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0658.
+For more information about an error, try `rustc --explain E0277`.