about summary refs log tree commit diff
path: root/tests/ui/impl-trait
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2025-09-11 13:08:36 +0200
committerlcnr <rust@lcnr.de>2025-09-18 12:58:38 +0200
commitf4e19c68786211f3c3cf2593442629599678800a (patch)
treee4eafc26e6dad3c7fb9bf418ab476ac64b555fab /tests/ui/impl-trait
parentd1ed52b1f5b78bf66127b670af813b84d57aeedb (diff)
downloadrust-f4e19c68786211f3c3cf2593442629599678800a.tar.gz
rust-f4e19c68786211f3c3cf2593442629599678800a.zip
support calls on opaque types :<
Diffstat (limited to 'tests/ui/impl-trait')
-rw-r--r--tests/ui/impl-trait/non-defining-uses/ambiguous-ops.current.stderr62
-rw-r--r--tests/ui/impl-trait/non-defining-uses/ambiguous-ops.rs117
-rw-r--r--tests/ui/impl-trait/non-defining-uses/function-call-on-infer.rs73
-rw-r--r--tests/ui/impl-trait/non-defining-uses/impl-deref-function-call.rs56
-rw-r--r--tests/ui/impl-trait/non-defining-uses/shex_compat-regression-test.rs19
5 files changed, 327 insertions, 0 deletions
diff --git a/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.current.stderr b/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.current.stderr
new file mode 100644
index 00000000000..c54c1bba028
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.current.stderr
@@ -0,0 +1,62 @@
+error[E0369]: cannot add `{integer}` to `impl Sized`
+  --> $DIR/ambiguous-ops.rs:17:15
+   |
+LL |         add() + 1
+   |         ----- ^ - {integer}
+   |         |
+   |         impl Sized
+
+error[E0368]: binary assignment operation `*=` cannot be applied to type `impl Sized`
+  --> $DIR/ambiguous-ops.rs:31:9
+   |
+LL |         temp *= 2;
+   |         ----^^^^^
+   |         |
+   |         cannot use `*=` on type `impl Sized`
+
+error[E0614]: type `DerefWrapper<impl Sized>` cannot be dereferenced
+  --> $DIR/ambiguous-ops.rs:57:22
+   |
+LL |         let _rarw = &*explicit_deref();
+   |                      ^^^^^^^^^^^^^^^^^ can't be dereferenced
+
+error[E0614]: type `DerefWrapper<impl Sized>` cannot be dereferenced
+  --> $DIR/ambiguous-ops.rs:69:9
+   |
+LL |         *explicit_deref_mut() = 1;
+   |         ^^^^^^^^^^^^^^^^^^^^^ can't be dereferenced
+
+error[E0277]: the type `impl Sized` cannot be indexed by `_`
+  --> $DIR/ambiguous-ops.rs:94:18
+   |
+LL |         let _y = explicit_index()[0];
+   |                  ^^^^^^^^^^^^^^^^ `impl Sized` cannot be indexed by `_`
+   |
+   = help: the trait `Index<_>` is not implemented for `impl Sized`
+note: required for `IndexWrapper<impl Sized>` to implement `Index<_>`
+  --> $DIR/ambiguous-ops.rs:81:22
+   |
+LL | impl<T: Index<U>, U> Index<U> for IndexWrapper<T> {
+   |         --------     ^^^^^^^^     ^^^^^^^^^^^^^^^
+   |         |
+   |         unsatisfied trait bound introduced here
+
+error[E0277]: the type `impl Sized` cannot be indexed by `_`
+  --> $DIR/ambiguous-ops.rs:106:9
+   |
+LL |         explicit_index_mut()[0] = 1;
+   |         ^^^^^^^^^^^^^^^^^^^^ `impl Sized` cannot be indexed by `_`
+   |
+   = help: the trait `Index<_>` is not implemented for `impl Sized`
+note: required for `IndexWrapper<impl Sized>` to implement `Index<_>`
+  --> $DIR/ambiguous-ops.rs:81:22
+   |
+LL | impl<T: Index<U>, U> Index<U> for IndexWrapper<T> {
+   |         --------     ^^^^^^^^     ^^^^^^^^^^^^^^^
+   |         |
+   |         unsatisfied trait bound introduced here
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0277, E0368, E0369, E0614.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.rs b/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.rs
new file mode 100644
index 00000000000..0aa5715339d
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.rs
@@ -0,0 +1,117 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] check-pass
+
+// Make sure we support non-call operations for opaque types even if
+// its not part of its item bounds.
+
+use std::ops::{Deref, DerefMut, Index, IndexMut};
+
+fn mk<T>() -> T {
+    todo!()
+}
+
+fn add() -> impl Sized {
+    let unconstrained = if false {
+        add() + 1
+        //[current]~^ ERROR cannot add `{integer}` to `impl Sized
+    } else {
+        let with_infer = mk();
+        let _ = with_infer + 1;
+        with_infer
+    };
+    let _: u32 = unconstrained;
+    1u32
+}
+
+fn mul_assign() -> impl Sized {
+    if false {
+        let mut temp = mul_assign();
+        temp *= 2;
+        //[current]~^ ERROR binary assignment operation `*=` cannot be applied to type `impl Sized`
+    }
+
+    let mut with_infer = mk();
+    with_infer *= 2;
+    let _: u32 = with_infer;
+
+    1u32
+}
+
+struct DerefWrapper<T>(T);
+impl<T: Deref> Deref for DerefWrapper<T> {
+    type Target = T::Target;
+    fn deref(&self) -> &Self::Target {
+        &*self.0
+    }
+}
+impl<T: DerefMut> DerefMut for DerefWrapper<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut *self.0
+    }
+}
+
+fn explicit_deref() -> DerefWrapper<impl Sized> {
+    if false {
+        let _rarw = &*explicit_deref();
+        //[current]~^ ERROR type `DerefWrapper<impl Sized>` cannot be dereferenced
+
+        let mut with_infer = DerefWrapper(mk());
+        let _rarw = &*with_infer;
+        with_infer
+    } else {
+        DerefWrapper(&1u32)
+    }
+}
+fn explicit_deref_mut() -> DerefWrapper<impl Sized> {
+    if false {
+        *explicit_deref_mut() = 1;
+        //[current]~^ ERROR type `DerefWrapper<impl Sized>` cannot be dereferenced
+
+        let mut with_infer = DerefWrapper(Default::default());
+        *with_infer = 1;
+        with_infer
+    } else {
+        DerefWrapper(Box::new(1u32))
+    }
+}
+
+struct IndexWrapper<T>(T);
+impl<T: Index<U>, U> Index<U> for IndexWrapper<T> {
+    type Output = T::Output;
+    fn index(&self, index: U) -> &Self::Output {
+        &self.0[index]
+    }
+}
+impl<T: IndexMut<U>, U> IndexMut<U> for IndexWrapper<T> {
+    fn index_mut(&mut self, index: U) -> &mut Self::Output {
+        &mut self.0[index]
+    }
+}
+fn explicit_index() -> IndexWrapper<impl Sized> {
+    if false {
+        let _y = explicit_index()[0];
+        //[current]~^ ERROR the type `impl Sized` cannot be indexed by `_`
+
+        let with_infer = IndexWrapper(Default::default());
+        let _y = with_infer[0];
+        with_infer
+    } else {
+        IndexWrapper([1u32])
+    }
+}
+fn explicit_index_mut() -> IndexWrapper<impl Sized> {
+    if false {
+        explicit_index_mut()[0] = 1;
+        //[current]~^ ERROR the type `impl Sized` cannot be indexed by `_`
+
+        let mut with_infer = IndexWrapper(Default::default());
+        with_infer[0] = 1;
+        with_infer
+    } else {
+        IndexWrapper([1u32])
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/function-call-on-infer.rs b/tests/ui/impl-trait/non-defining-uses/function-call-on-infer.rs
new file mode 100644
index 00000000000..9b9156ee4c7
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/function-call-on-infer.rs
@@ -0,0 +1,73 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#181. Make sure calling
+// opaque types works.
+
+fn fn_trait() -> impl Fn() {
+    if false {
+        let f = fn_trait();
+        f();
+    }
+
+    || ()
+}
+
+fn fn_trait_ref() -> impl Fn() {
+    if false {
+        let f = &fn_trait();
+        f();
+    }
+    || ()
+}
+
+fn fn_mut() -> impl FnMut() -> usize {
+    if false {
+        let mut f = fn_mut();
+        f();
+    }
+
+    let mut state = 0;
+    move || {
+        state += 1;
+        state
+    }
+}
+
+fn fn_mut_ref() -> impl FnMut() -> usize {
+    if false {
+        let mut f = &mut fn_mut();
+        f();
+    }
+
+    let mut state = 0;
+    move || {
+        state += 1;
+        state
+    }
+}
+
+
+fn fn_once() -> impl FnOnce() {
+    if false {
+        let mut f = fn_once();
+        f();
+    }
+
+    let string = String::new();
+    move || drop(string)
+}
+
+fn fn_once_ref() -> impl FnOnce() {
+    if false {
+        let mut f = Box::new(fn_once_ref());
+        f();
+    }
+
+    let string = String::new();
+    move || drop(string)
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/impl-deref-function-call.rs b/tests/ui/impl-trait/non-defining-uses/impl-deref-function-call.rs
new file mode 100644
index 00000000000..5ff0dae55cc
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/impl-deref-function-call.rs
@@ -0,0 +1,56 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#181. We want to
+// be able to step through `impl Deref` in its defining scope.
+use std::ops::{Deref, DerefMut};
+fn impl_deref_fn() -> impl Deref<Target = fn(fn(&str) -> usize)> {
+    if false {
+        let func = impl_deref_fn();
+        func(|s| s.len());
+    }
+
+    &((|_| ()) as fn(_))
+}
+
+fn impl_deref_impl_fn() -> impl Deref<Target = impl Fn()> {
+    if false {
+        let func = impl_deref_impl_fn();
+        func();
+    }
+
+    &|| ()
+}
+
+fn impl_deref_impl_deref_impl_fn() -> impl Deref<Target = impl Deref<Target = impl Fn()>> {
+    if false {
+        let func = impl_deref_impl_deref_impl_fn();
+        func();
+    }
+
+    &&|| ()
+}
+
+
+fn impl_deref_mut_impl_fn() -> impl DerefMut<Target = impl Fn()> {
+    if false {
+        let func = impl_deref_impl_fn();
+        func();
+    }
+
+    Box::new(|| ())
+}
+
+
+fn impl_deref_mut_impl_fn_mut() -> impl DerefMut<Target = impl FnMut()> {
+    if false {
+        let mut func = impl_deref_mut_impl_fn_mut();
+        func();
+    }
+
+    let mut state = 0;
+    Box::new(move || state += 1)
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/shex_compat-regression-test.rs b/tests/ui/impl-trait/non-defining-uses/shex_compat-regression-test.rs
new file mode 100644
index 00000000000..aa1b51d6906
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/shex_compat-regression-test.rs
@@ -0,0 +1,19 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#181.
+
+struct ShExCompactPrinter;
+
+struct TripleExpr;
+
+impl ShExCompactPrinter {
+    fn pp_triple_expr(&self) -> impl Fn(&TripleExpr, &ShExCompactPrinter) + '_ {
+        move |te, printer| {
+            printer.pp_triple_expr()(te, printer);
+        }
+    }
+}
+fn main() {}