Test variances of opaque captures

This commit is contained in:
Michael Goulet 2023-08-08 19:59:44 +00:00
parent 32a9565223
commit 690bcc6619
7 changed files with 105 additions and 0 deletions

View File

@ -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),

View File

@ -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() {

View File

@ -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,

View File

@ -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() {}

View File

@ -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

View File

@ -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() {}

View File

@ -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