diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 1c4e498c57e..5690b6536bb 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -184,7 +184,7 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq { // `dyn Trait1` can be unsized to `dyn Trait2` if they are the same trait, or // if `Trait2` is a (transitive) supertrait of `Trait2`. - fn consider_builtin_dyn_unsize_candidates( + fn consider_builtin_dyn_upcast_candidates( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> Vec>; @@ -334,7 +334,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // There may be multiple unsize candidates for a trait with several supertraits: // `trait Foo: Bar + Bar` and `dyn Foo: Unsize>` if lang_items.unsize_trait() == Some(trait_def_id) { - for result in G::consider_builtin_dyn_unsize_candidates(self, goal) { + for result in G::consider_builtin_dyn_upcast_candidates(self, goal) { candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result }); } } diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index f9506446aba..879f18843c9 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -562,7 +562,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { bug!("`Unsize` does not have an associated type: {:?}", goal); } - fn consider_builtin_dyn_unsize_candidates( + fn consider_builtin_dyn_upcast_candidates( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> Vec> { diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index c79f1f05512..29ee9da38e0 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -262,11 +262,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // `T` -> `dyn Trait` unsizing (_, &ty::Dynamic(data, region, ty::Dyn)) => { // Can only unsize to an object-safe type - // FIXME: Can auto traits be *not* object safe? if data - .auto_traits() - .chain(data.principal_def_id()) - .any(|def_id| !tcx.is_object_safe(def_id)) + .principal_def_id() + .map_or(false, |def_id| !tcx.check_is_object_safe(def_id)) { return Err(NoSolution); } @@ -365,7 +363,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { }) } - fn consider_builtin_dyn_unsize_candidates( + fn consider_builtin_dyn_upcast_candidates( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> Vec> { @@ -387,9 +385,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return vec![]; } - let mut responses = vec![]; let mut unsize_dyn_to_principal = |principal: Option>| { - let _ = ecx.infcx.probe(|_| -> Result<(), NoSolution> { + ecx.infcx.probe(|_| -> Result<_, NoSolution> { // Require that all of the trait predicates from A match B, except for // the auto traits. We do this by constructing a new A type with B's // auto traits, and equating these types. @@ -414,16 +411,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { goal.with(tcx, ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region))), ); - responses.push(ecx.evaluate_all_and_make_canonical_response(nested_obligations)?); - - Ok(()) - }); + ecx.evaluate_all_and_make_canonical_response(nested_obligations) + }) }; + let mut responses = vec![]; // If the principal def ids match (or are both none), then we're not doing // trait upcasting. We're just removing auto traits (or shortening the lifetime). if a_data.principal_def_id() == b_data.principal_def_id() { - unsize_dyn_to_principal(a_data.principal()); + if let Ok(response) = unsize_dyn_to_principal(a_data.principal()) { + responses.push(response); + } } else if let Some(a_principal) = a_data.principal() && let Some(b_principal) = b_data.principal() { @@ -433,7 +431,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } let erased_trait_ref = super_trait_ref .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); - unsize_dyn_to_principal(Some(erased_trait_ref)); + if let Ok(response) = unsize_dyn_to_principal(Some(erased_trait_ref)) { + responses.push(response); + } } } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index b5005c1d8d8..41e837e8b75 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -426,10 +426,6 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet