|
3 | 3 | use std::iter; |
4 | 4 |
|
5 | 5 | use super::assembly::{self, AssemblyCtxt}; |
6 | | -use super::{CanonicalGoal, EvalCtxt, Goal, QueryResult}; |
| 6 | +use super::{CanonicalGoal, Certainty, EvalCtxt, Goal, QueryResult}; |
7 | 7 | use rustc_hir::def_id::DefId; |
8 | 8 | use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime}; |
9 | 9 | use rustc_infer::traits::query::NoSolution; |
@@ -39,6 +39,9 @@ pub(super) enum CandidateSource { |
39 | 39 | AliasBound(usize), |
40 | 40 | /// Implementation of `Trait` or its supertraits for a `dyn Trait + Send + Sync`. |
41 | 41 | ObjectBound(usize), |
| 42 | + /// Implementation of `Send` or other explicitly listed *auto* traits for |
| 43 | + /// a `dyn Trait + Send + Sync` |
| 44 | + ObjectAutoBound(usize), |
42 | 45 | /// A builtin implementation for some specific traits, used in cases |
43 | 46 | /// where we cannot rely an ordinary library implementations. |
44 | 47 | /// |
@@ -161,6 +164,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { |
161 | 164 | ); |
162 | 165 | } |
163 | 166 | } |
| 167 | + |
| 168 | + for (idx, predicate) in object_bounds.iter().enumerate() { |
| 169 | + let ty::ExistentialPredicate::AutoTrait(def_id) = predicate.skip_binder() else { continue }; |
| 170 | + if def_id != goal.predicate.def_id() { |
| 171 | + continue; |
| 172 | + } |
| 173 | + acx.try_insert_candidate(CandidateSource::ObjectAutoBound(idx), Certainty::Yes); |
| 174 | + } |
164 | 175 | } |
165 | 176 | } |
166 | 177 |
|
@@ -254,6 +265,7 @@ impl<'tcx> EvalCtxt<'tcx> { |
254 | 265 | | (CandidateSource::ParamEnv(_), _) |
255 | 266 | | (CandidateSource::AliasBound(_), _) |
256 | 267 | | (CandidateSource::ObjectBound(_), _) |
| 268 | + | (CandidateSource::ObjectAutoBound(_), _) |
257 | 269 | | (CandidateSource::Builtin, _) |
258 | 270 | | (CandidateSource::AutoImpl, _) => unimplemented!(), |
259 | 271 | } |
|
0 commit comments