about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-08-08 19:59:44 +0000
committerMichael Goulet <michael@errs.io>2023-08-28 01:05:34 +0000
commit690bcc6619aad74d8c32a52c104d4f79fa2f6bf4 (patch)
tree2cc33b5ea6ef3e824a0be2d37ff2f6bb05b87040
parent32a9565223c05e6f7e60d783ad25e1864cd51d70 (diff)
downloadrust-690bcc6619aad74d8c32a52c104d4f79fa2f6bf4.tar.gz
rust-690bcc6619aad74d8c32a52c104d4f79fa2f6bf4.zip
Test variances of opaque captures
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/variance/test.rs15
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/variance.rs20
-rw-r--r--tests/ui/impl-trait/in-trait/variance.stderr26
-rw-r--r--tests/ui/impl-trait/variance.rs16
-rw-r--r--tests/ui/impl-trait/variance.stderr26
7 files changed, 105 insertions, 0 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 168cc16bb36..e745ef1ec07 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -813,6 +813,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     rustc_attr!(TEST, rustc_insignificant_dtor, Normal, template!(Word), WarnFollowing),
     rustc_attr!(TEST, rustc_strict_coherence, Normal, template!(Word), WarnFollowing),
     rustc_attr!(TEST, rustc_variance, Normal, template!(Word), WarnFollowing),
+    rustc_attr!(TEST, rustc_variance_of_opaques, Normal, template!(Word), WarnFollowing),
     rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
     rustc_attr!(TEST, rustc_abi, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
     rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing),
diff --git a/compiler/rustc_hir_analysis/src/variance/test.rs b/compiler/rustc_hir_analysis/src/variance/test.rs
index d57d05d7605..d98dc0e6b83 100644
--- a/compiler/rustc_hir_analysis/src/variance/test.rs
+++ b/compiler/rustc_hir_analysis/src/variance/test.rs
@@ -1,9 +1,24 @@
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::CRATE_DEF_ID;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 
 use crate::errors;
 
 pub fn test_variance(tcx: TyCtxt<'_>) {
+    if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
+        for id in tcx.hir().items() {
+            if matches!(tcx.def_kind(id.owner_id), DefKind::OpaqueTy) {
+                let variances_of = tcx.variances_of(id.owner_id);
+
+                tcx.sess.emit_err(errors::VariancesOf {
+                    span: tcx.def_span(id.owner_id),
+                    variances_of: format!("{variances_of:?}"),
+                });
+            }
+        }
+    }
+
     // For unit testing: check for a special "rustc_variance"
     // attribute and report an error with various results if found.
     for id in tcx.hir().items() {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9d4f49f9453..656deebb5d0 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1366,6 +1366,7 @@ symbols! {
         rustc_trivial_field_reads,
         rustc_unsafe_specialization_marker,
         rustc_variance,
+        rustc_variance_of_opaques,
         rustdoc,
         rustdoc_internals,
         rustdoc_missing_doc_code_examples,
diff --git a/tests/ui/impl-trait/in-trait/variance.rs b/tests/ui/impl-trait/in-trait/variance.rs
new file mode 100644
index 00000000000..f8e4ab88c19
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/variance.rs
@@ -0,0 +1,20 @@
+#![feature(rustc_attrs, return_position_impl_trait_in_trait)]
+#![allow(internal_features)]
+#![rustc_variance_of_opaques]
+
+trait Captures<'a> {}
+impl<T> Captures<'_> for T {}
+
+trait Foo<'i> {
+    fn implicit_capture_early<'a: 'a>() -> impl Sized {}
+    //~^ [o, *, *, o, o]
+    // Self, 'i, 'a, 'i_duplicated, 'a_duplicated
+
+    fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [o, *, *, o, o]
+
+    fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} //~ [o, *, o, o]
+
+    fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o, *, o, o]
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/variance.stderr b/tests/ui/impl-trait/in-trait/variance.stderr
new file mode 100644
index 00000000000..8cae5a92f0d
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/variance.stderr
@@ -0,0 +1,26 @@
+error: [o, *, *, o, o]
+  --> $DIR/variance.rs:9:44
+   |
+LL |     fn implicit_capture_early<'a: 'a>() -> impl Sized {}
+   |                                            ^^^^^^^^^^
+
+error: [o, *, *, o, o]
+  --> $DIR/variance.rs:13:44
+   |
+LL |     fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: [o, *, o, o]
+  --> $DIR/variance.rs:15:48
+   |
+LL |     fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
+   |                                                ^^^^^^^^^^
+
+error: [o, *, o, o]
+  --> $DIR/variance.rs:17:48
+   |
+LL |     fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
+   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/impl-trait/variance.rs b/tests/ui/impl-trait/variance.rs
new file mode 100644
index 00000000000..d6212f8f393
--- /dev/null
+++ b/tests/ui/impl-trait/variance.rs
@@ -0,0 +1,16 @@
+#![feature(rustc_attrs)]
+#![allow(internal_features)]
+#![rustc_variance_of_opaques]
+
+trait Captures<'a> {}
+impl<T> Captures<'_> for T {}
+
+fn not_captured_early<'a: 'a>() -> impl Sized {} //~ [*]
+
+fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [*, o]
+
+fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} //~ []
+
+fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o]
+
+fn main() {}
diff --git a/tests/ui/impl-trait/variance.stderr b/tests/ui/impl-trait/variance.stderr
new file mode 100644
index 00000000000..64473675410
--- /dev/null
+++ b/tests/ui/impl-trait/variance.stderr
@@ -0,0 +1,26 @@
+error: [*]
+  --> $DIR/variance.rs:8:36
+   |
+LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
+   |                                    ^^^^^^^^^^
+
+error: [*, o]
+  --> $DIR/variance.rs:10:32
+   |
+LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: []
+  --> $DIR/variance.rs:12:40
+   |
+LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
+   |                                        ^^^^^^^^^^
+
+error: [o]
+  --> $DIR/variance.rs:14:36
+   |
+LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+