|
5 | 5 | //! optimal solution to the constraints. The final variance for each |
6 | 6 | //! inferred is then written into the `variance_map` in the tcx. |
7 | 7 |
|
| 8 | +use rustc_data_structures::fx::FxHashSet; |
8 | 9 | use rustc_hir::def_id::DefIdMap; |
9 | 10 | use rustc_middle::ty; |
10 | 11 | use tracing::debug; |
@@ -43,16 +44,26 @@ struct SolveContext<'a, 'tcx> { |
43 | 44 | pub(crate) fn solve_constraints<'tcx>( |
44 | 45 | constraints_cx: ConstraintContext<'_, 'tcx>, |
45 | 46 | ) -> ty::CrateVariancesMap<'tcx> { |
46 | | - let ConstraintContext { terms_cx, constraints, .. } = constraints_cx; |
| 47 | + let ConstraintContext { terms_cx, mut constraints, .. } = constraints_cx; |
47 | 48 |
|
| 49 | + let mut overridden_inferreds = FxHashSet::default(); |
48 | 50 | let mut solutions = vec![ty::Bivariant; terms_cx.inferred_terms.len()]; |
| 51 | + // prime the solutions for certain lang items which have hard-coded variance |
49 | 52 | for (id, variances) in &terms_cx.lang_items { |
50 | 53 | let InferredIndex(start) = terms_cx.inferred_starts[id]; |
51 | 54 | for (i, &variance) in variances.iter().enumerate() { |
52 | 55 | solutions[start + i] = variance; |
| 56 | + overridden_inferreds.insert(start + i); |
53 | 57 | } |
54 | 58 | } |
55 | 59 |
|
| 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 | + |
56 | 67 | let mut solutions_cx = SolveContext { terms_cx, constraints, solutions }; |
57 | 68 | solutions_cx.solve(); |
58 | 69 | let variances = solutions_cx.create_map(); |
|
0 commit comments