Skip to content

Commit 690bcc6

Browse files
Test variances of opaque captures
1 parent 32a9565 commit 690bcc6

File tree

7 files changed

+105
-0
lines changed

7 files changed

+105
-0
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
813813
rustc_attr!(TEST, rustc_insignificant_dtor, Normal, template!(Word), WarnFollowing),
814814
rustc_attr!(TEST, rustc_strict_coherence, Normal, template!(Word), WarnFollowing),
815815
rustc_attr!(TEST, rustc_variance, Normal, template!(Word), WarnFollowing),
816+
rustc_attr!(TEST, rustc_variance_of_opaques, Normal, template!(Word), WarnFollowing),
816817
rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
817818
rustc_attr!(TEST, rustc_abi, Normal, template!(List: "field1, field2, ..."), WarnFollowing),
818819
rustc_attr!(TEST, rustc_regions, Normal, template!(Word), WarnFollowing),

compiler/rustc_hir_analysis/src/variance/test.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
1+
use rustc_hir::def::DefKind;
2+
use rustc_hir::def_id::CRATE_DEF_ID;
13
use rustc_middle::ty::TyCtxt;
24
use rustc_span::symbol::sym;
35

46
use crate::errors;
57

68
pub fn test_variance(tcx: TyCtxt<'_>) {
9+
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
10+
for id in tcx.hir().items() {
11+
if matches!(tcx.def_kind(id.owner_id), DefKind::OpaqueTy) {
12+
let variances_of = tcx.variances_of(id.owner_id);
13+
14+
tcx.sess.emit_err(errors::VariancesOf {
15+
span: tcx.def_span(id.owner_id),
16+
variances_of: format!("{variances_of:?}"),
17+
});
18+
}
19+
}
20+
}
21+
722
// For unit testing: check for a special "rustc_variance"
823
// attribute and report an error with various results if found.
924
for id in tcx.hir().items() {

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,7 @@ symbols! {
13661366
rustc_trivial_field_reads,
13671367
rustc_unsafe_specialization_marker,
13681368
rustc_variance,
1369+
rustc_variance_of_opaques,
13691370
rustdoc,
13701371
rustdoc_internals,
13711372
rustdoc_missing_doc_code_examples,
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![feature(rustc_attrs, return_position_impl_trait_in_trait)]
2+
#![allow(internal_features)]
3+
#![rustc_variance_of_opaques]
4+
5+
trait Captures<'a> {}
6+
impl<T> Captures<'_> for T {}
7+
8+
trait Foo<'i> {
9+
fn implicit_capture_early<'a: 'a>() -> impl Sized {}
10+
//~^ [o, *, *, o, o]
11+
// Self, 'i, 'a, 'i_duplicated, 'a_duplicated
12+
13+
fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [o, *, *, o, o]
14+
15+
fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} //~ [o, *, o, o]
16+
17+
fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o, *, o, o]
18+
}
19+
20+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: [o, *, *, o, o]
2+
--> $DIR/variance.rs:9:44
3+
|
4+
LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {}
5+
| ^^^^^^^^^^
6+
7+
error: [o, *, *, o, o]
8+
--> $DIR/variance.rs:13:44
9+
|
10+
LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: [o, *, o, o]
14+
--> $DIR/variance.rs:15:48
15+
|
16+
LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
17+
| ^^^^^^^^^^
18+
19+
error: [o, *, o, o]
20+
--> $DIR/variance.rs:17:48
21+
|
22+
LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
error: aborting due to 4 previous errors
26+

tests/ui/impl-trait/variance.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(rustc_attrs)]
2+
#![allow(internal_features)]
3+
#![rustc_variance_of_opaques]
4+
5+
trait Captures<'a> {}
6+
impl<T> Captures<'_> for T {}
7+
8+
fn not_captured_early<'a: 'a>() -> impl Sized {} //~ [*]
9+
10+
fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [*, o]
11+
12+
fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} //~ []
13+
14+
fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o]
15+
16+
fn main() {}

tests/ui/impl-trait/variance.stderr

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: [*]
2+
--> $DIR/variance.rs:8:36
3+
|
4+
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
5+
| ^^^^^^^^^^
6+
7+
error: [*, o]
8+
--> $DIR/variance.rs:10:32
9+
|
10+
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: []
14+
--> $DIR/variance.rs:12:40
15+
|
16+
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
17+
| ^^^^^^^^^^
18+
19+
error: [o]
20+
--> $DIR/variance.rs:14:36
21+
|
22+
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
error: aborting due to 4 previous errors
26+

0 commit comments

Comments
 (0)