Skip to content

Commit 54e23e6

Browse files
committed
Unrolled build for #163051 in rollup 163139
Rollup merge of #163051 - asquared31415:actually_covariant_unsafe_cell, r=WaffleLapkin Make CovariantUnsafeCell actually covariant The "test" in `core` was not actually being run, due to core being weird. (filed #163045 to track that) The existing mechanism for inserting variance manually was only *priming* the solver, which happened to work for the other two types using this mechanism, but does not work for weakening variance explicitly. I changed this mechanism to additionally prevent the variance from being updated when solving. This blocks #159838 r? @WaffleLapkin as the implementor of `CovariantUnsafeCell`
2 parents 88638df + f5d4c29 commit 54e23e6

5 files changed

Lines changed: 61 additions & 14 deletions

File tree

‎compiler/rustc_hir_analysis/src/variance/solve.rs‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! optimal solution to the constraints. The final variance for each
66
//! inferred is then written into the `variance_map` in the tcx.
77
8+
use rustc_data_structures::fx::FxHashSet;
89
use rustc_hir::def_id::DefIdMap;
910
use rustc_middle::ty;
1011
use tracing::debug;
@@ -43,16 +44,26 @@ struct SolveContext<'a, 'tcx> {
4344
pub(crate) fn solve_constraints<'tcx>(
4445
constraints_cx: ConstraintContext<'_, 'tcx>,
4546
) -> ty::CrateVariancesMap<'tcx> {
46-
let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
47+
let ConstraintContext { terms_cx, mut constraints, .. } = constraints_cx;
4748

49+
let mut overridden_inferreds = FxHashSet::default();
4850
let mut solutions = vec![ty::Bivariant; terms_cx.inferred_terms.len()];
51+
// prime the solutions for certain lang items which have hard-coded variance
4952
for (id, variances) in &terms_cx.lang_items {
5053
let InferredIndex(start) = terms_cx.inferred_starts[id];
5154
for (i, &variance) in variances.iter().enumerate() {
5255
solutions[start + i] = variance;
56+
overridden_inferreds.insert(start + i);
5357
}
5458
}
5559

60+
// ensure the solutions for overridden inferreds are never constrained by anything else
61+
if !overridden_inferreds.is_empty() {
62+
constraints.retain(|Constraint { inferred: InferredIndex(inferred), .. }| {
63+
!overridden_inferreds.contains(inferred)
64+
});
65+
}
66+
5667
let mut solutions_cx = SolveContext { terms_cx, constraints, solutions };
5768
solutions_cx.solve();
5869
let variances = solutions_cx.create_map();

‎library/core/src/cell/covariant_unsafe_cell.rs‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,3 @@ impl<T: ?Sized> fmt::Debug for CovariantUnsafeCell<T> {
170170
f.debug_struct("CovariantUnsafeCell").finish_non_exhaustive()
171171
}
172172
}
173-
174-
#[cfg(test)]
175-
mod tests {
176-
use super::*;
177-
178-
fn _covarience<'short, 'long: 'short>(
179-
x: CovariantUnsafeCell<&'long ()>,
180-
) -> CovariantUnsafeCell<&'short ()> {
181-
x
182-
}
183-
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ build-pass
2+
3+
#![feature(covariant_unsafe_cell)]
4+
5+
use std::cell::CovariantUnsafeCell;
6+
7+
/// this function compiling ensures that CovariantUnsafeCell is actually covariant
8+
fn _assert_covariance<'short, 'long: 'short>(
9+
x: CovariantUnsafeCell<&'long ()>,
10+
) -> CovariantUnsafeCell<&'short ()> {
11+
x
12+
}
13+
14+
fn main () {}

‎tests/ui/variance/variance-types.rs‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#![allow(dead_code)]
21
#![feature(rustc_attrs)]
2+
#![feature(covariant_unsafe_cell)]
33

44
use std::cell::Cell;
55

@@ -38,4 +38,19 @@ enum Enum<A,B,C> { //~ ERROR [A: +, B: -, C: o]
3838
Zed(Covariant<C>,Contravariant<C>)
3939
}
4040

41+
#[rustc_dump_variances]
42+
struct PhantomDataIsCovariant<A> { //~ ERROR [A: +]
43+
t: std::marker::PhantomData<A>
44+
}
45+
46+
#[rustc_dump_variances]
47+
struct UnsafeCellIsInvariant<A> { //~ ERROR [A: o]
48+
t: std::cell::UnsafeCell<A>
49+
}
50+
51+
#[rustc_dump_variances]
52+
struct CovariantUnsafeCellIsCovariant<A> { //~ ERROR [A: +]
53+
t: std::cell::CovariantUnsafeCell<A>
54+
}
55+
4156
pub fn main() { }

‎tests/ui/variance/variance-types.stderr‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,23 @@ error: [A: +, B: -, C: o]
3434
LL | enum Enum<A,B,C> {
3535
| ^^^^^^^^^^^^^^^^
3636

37-
error: aborting due to 6 previous errors
37+
error: [A: +]
38+
--> $DIR/variance-types.rs:42:1
39+
|
40+
LL | struct PhantomDataIsCovariant<A> {
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42+
43+
error: [A: o]
44+
--> $DIR/variance-types.rs:47:1
45+
|
46+
LL | struct UnsafeCellIsInvariant<A> {
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48+
49+
error: [A: +]
50+
--> $DIR/variance-types.rs:52:1
51+
|
52+
LL | struct CovariantUnsafeCellIsCovariant<A> {
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54+
55+
error: aborting due to 9 previous errors
3856

0 commit comments

Comments
 (0)