about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-14 18:10:51 +0000
committerbors <bors@rust-lang.org>2022-09-14 18:10:51 +0000
commit6153d3cbe6abc74fb37e4ebe48cc825484fd6bbf (patch)
treebef7759236490fe278aa160a8ac63f41d37ecd27 /src/test
parenta92669638461836f41f54f95e396f9082bb91391 (diff)
parent0faafbf1d91f7b9ea4c775cd33cf12008575a35b (diff)
downloadrust-6153d3cbe6abc74fb37e4ebe48cc825484fd6bbf.tar.gz
rust-6153d3cbe6abc74fb37e4ebe48cc825484fd6bbf.zip
Auto merge of #101212 - eholk:dyn-star, r=compiler-errors
Initial implementation of dyn*

This PR adds extremely basic and incomplete support for [dyn*](https://smallcultfollowing.com/babysteps//blog/2022/03/29/dyn-can-we-make-dyn-sized/). The goal is to get something in tree behind a flag to make collaboration easier, and also to make sure the implementation so far is not unreasonable. This PR does quite a few things:

* Introduce `dyn_star` feature flag
* Adds parsing for `dyn* Trait` types
* Defines `dyn* Trait` as a sized type
* Adds support for explicit casts, like `42usize as dyn* Debug`
  * Including const evaluation of such casts
* Adds codegen for drop glue so things are cleaned up properly when a `dyn* Trait` object goes out of scope
* Adds codegen for method calls, at least for methods that take `&self`

Quite a bit is still missing, but this gives us a starting point. Note that this is never intended to become stable surface syntax for Rust, but rather `dyn*` is planned to be used as an implementation detail for async functions in dyn traits.

Joint work with `@nikomatsakis` and `@compiler-errors.`

r? `@bjorn3`
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/dyn-star/const.rs14
-rw-r--r--src/test/ui/dyn-star/drop.rs23
-rw-r--r--src/test/ui/dyn-star/drop.run.stdout1
-rw-r--r--src/test/ui/dyn-star/error.rs13
-rw-r--r--src/test/ui/dyn-star/error.stderr9
-rw-r--r--src/test/ui/dyn-star/feature-gate-dyn_star.rs9
-rw-r--r--src/test/ui/dyn-star/feature-gate-dyn_star.stderr12
-rw-r--r--src/test/ui/dyn-star/make-dyn-star.rs13
-rw-r--r--src/test/ui/dyn-star/method.rs26
-rw-r--r--src/test/ui/dyn-star/syntax.rs11
-rw-r--r--src/test/ui/parser/trait-object-delimiters.rs2
-rw-r--r--src/test/ui/parser/trait-object-delimiters.stderr4
12 files changed, 134 insertions, 3 deletions
diff --git a/src/test/ui/dyn-star/const.rs b/src/test/ui/dyn-star/const.rs
new file mode 100644
index 00000000000..e49caf649f8
--- /dev/null
+++ b/src/test/ui/dyn-star/const.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![feature(dyn_star)]
+#![allow(unused, incomplete_features)]
+
+use std::fmt::Debug;
+
+fn make_dyn_star() {
+    let i = 42usize;
+    let dyn_i: dyn* Debug = i as dyn* Debug;
+}
+
+fn main() {
+    make_dyn_star();
+}
diff --git a/src/test/ui/dyn-star/drop.rs b/src/test/ui/dyn-star/drop.rs
new file mode 100644
index 00000000000..46b232f3dd3
--- /dev/null
+++ b/src/test/ui/dyn-star/drop.rs
@@ -0,0 +1,23 @@
+// run-pass
+// check-run-results
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+#[derive(Debug)]
+struct Foo(usize);
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("destructor called");
+    }
+}
+
+fn make_dyn_star(i: Foo) {
+    let _dyn_i: dyn* Debug = i as dyn* Debug;
+}
+
+fn main() {
+    make_dyn_star(Foo(42));
+}
diff --git a/src/test/ui/dyn-star/drop.run.stdout b/src/test/ui/dyn-star/drop.run.stdout
new file mode 100644
index 00000000000..dadb33ccf3a
--- /dev/null
+++ b/src/test/ui/dyn-star/drop.run.stdout
@@ -0,0 +1 @@
+destructor called
diff --git a/src/test/ui/dyn-star/error.rs b/src/test/ui/dyn-star/error.rs
new file mode 100644
index 00000000000..33eff80a5fe
--- /dev/null
+++ b/src/test/ui/dyn-star/error.rs
@@ -0,0 +1,13 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo {}
+
+fn make_dyn_star() {
+    let i = 42;
+    let dyn_i: dyn* Foo = i as dyn* Foo; //~ ERROR trait bound `{integer}: Foo` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/error.stderr b/src/test/ui/dyn-star/error.stderr
new file mode 100644
index 00000000000..d612ccc630e
--- /dev/null
+++ b/src/test/ui/dyn-star/error.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `{integer}: Foo` is not satisfied
+  --> $DIR/error.rs:10:27
+   |
+LL |     let dyn_i: dyn* Foo = i as dyn* Foo;
+   |                           ^ the trait `Foo` is not implemented for `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dyn-star/feature-gate-dyn_star.rs b/src/test/ui/dyn-star/feature-gate-dyn_star.rs
new file mode 100644
index 00000000000..4756661cf41
--- /dev/null
+++ b/src/test/ui/dyn-star/feature-gate-dyn_star.rs
@@ -0,0 +1,9 @@
+// Feature gate test for dyn_star
+
+/// dyn* is not necessarily the final surface syntax (if we have one at all),
+/// but for now we will support it to aid in writing tests independently.
+pub fn dyn_star_parameter(_: &dyn* Send) {
+    //~^ dyn* trait objects are unstable
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/feature-gate-dyn_star.stderr b/src/test/ui/dyn-star/feature-gate-dyn_star.stderr
new file mode 100644
index 00000000000..2767e9478e2
--- /dev/null
+++ b/src/test/ui/dyn-star/feature-gate-dyn_star.stderr
@@ -0,0 +1,12 @@
+error[E0658]: dyn* trait objects are unstable
+  --> $DIR/feature-gate-dyn_star.rs:5:31
+   |
+LL | pub fn dyn_star_parameter(_: &dyn* Send) {
+   |                               ^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(dyn_star)]` 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/src/test/ui/dyn-star/make-dyn-star.rs b/src/test/ui/dyn-star/make-dyn-star.rs
new file mode 100644
index 00000000000..708ffa25d6f
--- /dev/null
+++ b/src/test/ui/dyn-star/make-dyn-star.rs
@@ -0,0 +1,13 @@
+// run-pass
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn make_dyn_star(i: usize) {
+    let _dyn_i: dyn* Debug = i as dyn* Debug;
+}
+
+fn main() {
+    make_dyn_star(42);
+}
diff --git a/src/test/ui/dyn-star/method.rs b/src/test/ui/dyn-star/method.rs
new file mode 100644
index 00000000000..d04958ca2aa
--- /dev/null
+++ b/src/test/ui/dyn-star/method.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+trait Foo {
+    fn get(&self) -> usize;
+}
+
+impl Foo for usize {
+    fn get(&self) -> usize {
+        *self
+    }
+}
+
+fn invoke_dyn_star(i: dyn* Foo) -> usize {
+    i.get()
+}
+
+fn make_and_invoke_dyn_star(i: usize) -> usize {
+    let dyn_i: dyn* Foo = i as dyn* Foo;
+    invoke_dyn_star(dyn_i)
+}
+
+fn main() {
+    println!("{}", make_and_invoke_dyn_star(42));
+}
diff --git a/src/test/ui/dyn-star/syntax.rs b/src/test/ui/dyn-star/syntax.rs
new file mode 100644
index 00000000000..618c72562b2
--- /dev/null
+++ b/src/test/ui/dyn-star/syntax.rs
@@ -0,0 +1,11 @@
+// Make sure we can parse the `dyn* Trait` syntax
+//
+// check-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+pub fn dyn_star_parameter(_: dyn* Send) {
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/trait-object-delimiters.rs b/src/test/ui/parser/trait-object-delimiters.rs
index b5258eebb90..cc04ac05204 100644
--- a/src/test/ui/parser/trait-object-delimiters.rs
+++ b/src/test/ui/parser/trait-object-delimiters.rs
@@ -6,7 +6,7 @@ fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type
 fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
 
 fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
-//~^ ERROR expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
+//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
 //~| ERROR at least one trait is required for an object type
 
 fn foo4(_: &dyn <Drop + AsRef<str>>) {} //~ ERROR expected identifier, found `<`
diff --git a/src/test/ui/parser/trait-object-delimiters.stderr b/src/test/ui/parser/trait-object-delimiters.stderr
index 6eb9c7238cb..99c4515459d 100644
--- a/src/test/ui/parser/trait-object-delimiters.stderr
+++ b/src/test/ui/parser/trait-object-delimiters.stderr
@@ -22,11 +22,11 @@ error: expected parameter name, found `{`
 LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
    |                 ^ expected parameter name
 
-error: expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
+error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
   --> $DIR/trait-object-delimiters.rs:8:17
    |
 LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
-   |                -^ expected one of 9 possible tokens
+   |                -^ expected one of 10 possible tokens
    |                |
    |                help: missing `,`