Auto merge of #94144 - est31:let_else_trait_selection, r=cjgillot
rustc_trait_selection: adopt let else in more places Continuation of #89933, #91018, #91481, #93046, #93590, #94011. I have extended my clippy lint to also recognize tuple passing and match statements. The diff caused by fixing it is way above 1 thousand lines. Thus, I split it up into multiple pull requests to make reviewing easier. This PR handles rustc_trait_selection.
This commit is contained in:
commit
9323028156
@ -148,7 +148,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||||||
// traits::project will see that 'T: SomeTrait' is in our ParamEnv, allowing
|
// traits::project will see that 'T: SomeTrait' is in our ParamEnv, allowing
|
||||||
// SelectionContext to return it back to us.
|
// SelectionContext to return it back to us.
|
||||||
|
|
||||||
let (new_env, user_env) = match self.evaluate_predicates(
|
let Some((new_env, user_env)) = self.evaluate_predicates(
|
||||||
&infcx,
|
&infcx,
|
||||||
trait_did,
|
trait_did,
|
||||||
ty,
|
ty,
|
||||||
@ -156,9 +156,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||||||
orig_env,
|
orig_env,
|
||||||
&mut fresh_preds,
|
&mut fresh_preds,
|
||||||
false,
|
false,
|
||||||
) {
|
) else {
|
||||||
Some(e) => e,
|
return AutoTraitResult::NegativeImpl;
|
||||||
None => return AutoTraitResult::NegativeImpl,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (full_env, full_user_env) = self
|
let (full_env, full_user_env) = self
|
||||||
|
@ -328,18 +328,15 @@ fn negative_impl<'cx, 'tcx>(
|
|||||||
impl_trait_ref_and_oblig(selcx, impl1_env, impl2_def_id, impl2_substs);
|
impl_trait_ref_and_oblig(selcx, impl1_env, impl2_def_id, impl2_substs);
|
||||||
|
|
||||||
// do the impls unify? If not, not disjoint.
|
// do the impls unify? If not, not disjoint.
|
||||||
let more_obligations = match infcx
|
let Ok(InferOk { obligations: more_obligations, .. }) = infcx
|
||||||
.at(&ObligationCause::dummy(), impl1_env)
|
.at(&ObligationCause::dummy(), impl1_env)
|
||||||
.eq(impl1_trait_ref, impl2_trait_ref)
|
.eq(impl1_trait_ref, impl2_trait_ref)
|
||||||
{
|
else {
|
||||||
Ok(InferOk { obligations, .. }) => obligations,
|
debug!(
|
||||||
Err(_) => {
|
"explicit_disjoint: {:?} does not unify with {:?}",
|
||||||
debug!(
|
impl1_trait_ref, impl2_trait_ref
|
||||||
"explicit_disjoint: {:?} does not unify with {:?}",
|
);
|
||||||
impl1_trait_ref, impl2_trait_ref
|
return false;
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let opt_failing_obligation = obligations
|
let opt_failing_obligation = obligations
|
||||||
|
@ -804,9 +804,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let found_trait_ty = match found_trait_ref.self_ty().no_bound_vars() {
|
let Some(found_trait_ty) = found_trait_ref.self_ty().no_bound_vars() else {
|
||||||
Some(ty) => ty,
|
return;
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let found_did = match *found_trait_ty.kind() {
|
let found_did = match *found_trait_ty.kind() {
|
||||||
@ -2097,26 +2096,24 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
) {
|
) {
|
||||||
let (pred, item_def_id, span) = match (
|
let (
|
||||||
|
ty::PredicateKind::Trait(pred),
|
||||||
|
&ObligationCauseCode::BindingObligation(item_def_id, span),
|
||||||
|
) = (
|
||||||
obligation.predicate.kind().skip_binder(),
|
obligation.predicate.kind().skip_binder(),
|
||||||
obligation.cause.code().peel_derives(),
|
obligation.cause.code().peel_derives(),
|
||||||
) {
|
) else {
|
||||||
(
|
return;
|
||||||
ty::PredicateKind::Trait(pred),
|
|
||||||
&ObligationCauseCode::BindingObligation(item_def_id, span),
|
|
||||||
) => (pred, item_def_id, span),
|
|
||||||
_ => return,
|
|
||||||
};
|
};
|
||||||
debug!(
|
debug!(
|
||||||
"suggest_unsized_bound_if_applicable: pred={:?} item_def_id={:?} span={:?}",
|
"suggest_unsized_bound_if_applicable: pred={:?} item_def_id={:?} span={:?}",
|
||||||
pred, item_def_id, span
|
pred, item_def_id, span
|
||||||
);
|
);
|
||||||
let node = match (
|
let (Some(node), true) = (
|
||||||
self.tcx.hir().get_if_local(item_def_id),
|
self.tcx.hir().get_if_local(item_def_id),
|
||||||
Some(pred.def_id()) == self.tcx.lang_items().sized_trait(),
|
Some(pred.def_id()) == self.tcx.lang_items().sized_trait(),
|
||||||
) {
|
) else {
|
||||||
(Some(node), true) => node,
|
return;
|
||||||
_ => return,
|
|
||||||
};
|
};
|
||||||
self.maybe_suggest_unsized_generics(err, span, node);
|
self.maybe_suggest_unsized_generics(err, span, node);
|
||||||
}
|
}
|
||||||
@ -2127,9 +2124,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
node: Node<'hir>,
|
node: Node<'hir>,
|
||||||
) {
|
) {
|
||||||
let generics = match node.generics() {
|
let Some(generics) = node.generics() else {
|
||||||
Some(generics) => generics,
|
return;
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
let sized_trait = self.tcx.lang_items().sized_trait();
|
let sized_trait = self.tcx.lang_items().sized_trait();
|
||||||
debug!("maybe_suggest_unsized_generics: generics.params={:?}", generics.params);
|
debug!("maybe_suggest_unsized_generics: generics.params={:?}", generics.params);
|
||||||
@ -2142,9 +2138,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
.iter()
|
.iter()
|
||||||
.all(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) != sized_trait)
|
.all(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) != sized_trait)
|
||||||
});
|
});
|
||||||
let param = match param {
|
let Some(param) = param else {
|
||||||
Some(param) => param,
|
return;
|
||||||
_ => return,
|
|
||||||
};
|
};
|
||||||
let param_def_id = self.tcx.hir().local_def_id(param.hir_id).to_def_id();
|
let param_def_id = self.tcx.hir().local_def_id(param.hir_id).to_def_id();
|
||||||
let preds = generics.where_clause.predicates.iter();
|
let preds = generics.where_clause.predicates.iter();
|
||||||
|
@ -512,9 +512,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
| ObligationCauseCode::BuiltinDerivedObligation(cause) => cause.parent_trait_pred,
|
| ObligationCauseCode::BuiltinDerivedObligation(cause) => cause.parent_trait_pred,
|
||||||
_ => trait_pred,
|
_ => trait_pred,
|
||||||
};
|
};
|
||||||
let real_ty = match real_trait_pred.self_ty().no_bound_vars() {
|
let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else {
|
||||||
Some(ty) => ty,
|
return;
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() {
|
if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() {
|
||||||
@ -586,9 +585,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
) {
|
) {
|
||||||
let self_ty = match trait_pred.self_ty().no_bound_vars() {
|
let Some(self_ty) = trait_pred.self_ty().no_bound_vars() else {
|
||||||
None => return,
|
return;
|
||||||
Some(ty) => ty,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (def_id, output_ty, callable) = match *self_ty.kind() {
|
let (def_id, output_ty, callable) = match *self_ty.kind() {
|
||||||
@ -600,9 +598,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// `mk_trait_obligation_with_new_self_ty` only works for types with no escaping bound
|
// `mk_trait_obligation_with_new_self_ty` only works for types with no escaping bound
|
||||||
// variables, so bail out if we have any.
|
// variables, so bail out if we have any.
|
||||||
let output_ty = match output_ty.no_bound_vars() {
|
let Some(output_ty) = output_ty.no_bound_vars() else {
|
||||||
Some(ty) => ty,
|
return;
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_obligation =
|
let new_obligation =
|
||||||
@ -624,9 +621,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
..
|
..
|
||||||
})) => {
|
})) => {
|
||||||
err.span_label(*span, "consider calling this closure");
|
err.span_label(*span, "consider calling this closure");
|
||||||
let name = match self.get_closure_name(def_id, err, &msg) {
|
let Some(name) = self.get_closure_name(def_id, err, &msg) else {
|
||||||
Some(name) => name,
|
return;
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
let args = decl.inputs.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
|
let args = decl.inputs.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
|
||||||
let sugg = format!("({})", args);
|
let sugg = format!("({})", args);
|
||||||
@ -823,9 +819,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut suggested_ty = match trait_pred.self_ty().no_bound_vars() {
|
let Some(mut suggested_ty) = trait_pred.self_ty().no_bound_vars() else {
|
||||||
Some(ty) => ty,
|
return;
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for refs_remaining in 0..refs_number {
|
for refs_remaining in 0..refs_number {
|
||||||
@ -1039,9 +1034,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
|
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
|
||||||
let hir = self.tcx.hir();
|
let hir = self.tcx.hir();
|
||||||
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
||||||
let sig = match hir.find(parent_node) {
|
let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) = hir.find(parent_node) else {
|
||||||
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) => sig,
|
return None;
|
||||||
_ => return None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let hir::FnRetTy::Return(ret_ty) = sig.decl.output { Some(ret_ty.span) } else { None }
|
if let hir::FnRetTy::Return(ret_ty) = sig.decl.output { Some(ret_ty.span) } else { None }
|
||||||
@ -1491,11 +1485,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// Only continue if a generator was found.
|
// Only continue if a generator was found.
|
||||||
debug!(?generator, ?trait_ref, ?target_ty, "maybe_note_obligation_cause_for_async_await");
|
debug!(?generator, ?trait_ref, ?target_ty, "maybe_note_obligation_cause_for_async_await");
|
||||||
let (generator_did, trait_ref, target_ty) = match (generator, trait_ref, target_ty) {
|
let (Some(generator_did), Some(trait_ref), Some(target_ty)) = (generator, trait_ref, target_ty) else {
|
||||||
(Some(generator_did), Some(trait_ref), Some(target_ty)) => {
|
return false;
|
||||||
(generator_did, trait_ref, target_ty)
|
|
||||||
}
|
|
||||||
_ => return false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let span = self.tcx.def_span(generator_did);
|
let span = self.tcx.def_span(generator_did);
|
||||||
|
@ -340,19 +340,16 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||||||
"normalize_param_env_or_error: predicates=(non-outlives={:?}, outlives={:?})",
|
"normalize_param_env_or_error: predicates=(non-outlives={:?}, outlives={:?})",
|
||||||
predicates, outlives_predicates
|
predicates, outlives_predicates
|
||||||
);
|
);
|
||||||
let non_outlives_predicates = match do_normalize_predicates(
|
let Ok(non_outlives_predicates) = do_normalize_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
region_context,
|
region_context,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
elaborated_env,
|
elaborated_env,
|
||||||
predicates,
|
predicates,
|
||||||
) {
|
) else {
|
||||||
Ok(predicates) => predicates,
|
|
||||||
// An unnormalized env is better than nothing.
|
// An unnormalized env is better than nothing.
|
||||||
Err(ErrorReported) => {
|
debug!("normalize_param_env_or_error: errored resolving non-outlives predicates");
|
||||||
debug!("normalize_param_env_or_error: errored resolving non-outlives predicates");
|
return elaborated_env;
|
||||||
return elaborated_env;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("normalize_param_env_or_error: non-outlives predicates={:?}", non_outlives_predicates);
|
debug!("normalize_param_env_or_error: non-outlives predicates={:?}", non_outlives_predicates);
|
||||||
@ -367,19 +364,16 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||||||
unnormalized_env.reveal(),
|
unnormalized_env.reveal(),
|
||||||
unnormalized_env.constness(),
|
unnormalized_env.constness(),
|
||||||
);
|
);
|
||||||
let outlives_predicates = match do_normalize_predicates(
|
let Ok(outlives_predicates) = do_normalize_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
region_context,
|
region_context,
|
||||||
cause,
|
cause,
|
||||||
outlives_env,
|
outlives_env,
|
||||||
outlives_predicates,
|
outlives_predicates,
|
||||||
) {
|
) else {
|
||||||
Ok(predicates) => predicates,
|
|
||||||
// An unnormalized env is better than nothing.
|
// An unnormalized env is better than nothing.
|
||||||
Err(ErrorReported) => {
|
debug!("normalize_param_env_or_error: errored resolving outlives predicates");
|
||||||
debug!("normalize_param_env_or_error: errored resolving outlives predicates");
|
return elaborated_env;
|
||||||
return elaborated_env;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
debug!("normalize_param_env_or_error: outlives predicates={:?}", outlives_predicates);
|
debug!("normalize_param_env_or_error: outlives predicates={:?}", outlives_predicates);
|
||||||
|
|
||||||
@ -834,9 +828,8 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>(
|
|||||||
selcx.select(&obligation).unwrap()
|
selcx.select(&obligation).unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
let implsrc_traitcasting = match implsrc {
|
let Some(ImplSource::TraitUpcasting(implsrc_traitcasting)) = implsrc else {
|
||||||
Some(ImplSource::TraitUpcasting(data)) => data,
|
bug!();
|
||||||
_ => bug!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
implsrc_traitcasting.vtable_vptr_slot
|
implsrc_traitcasting.vtable_vptr_slot
|
||||||
|
@ -322,11 +322,8 @@ fn trait_has_sized_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
let sized_def_id = match tcx.lang_items().sized_trait() {
|
let Some(sized_def_id) = tcx.lang_items().sized_trait() else {
|
||||||
Some(def_id) => def_id,
|
return false; /* No Sized trait, can't require it! */
|
||||||
None => {
|
|
||||||
return false; /* No Sized trait, can't require it! */
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Search for a predicate like `Self : Sized` amongst the trait bounds.
|
// Search for a predicate like `Self : Sized` amongst the trait bounds.
|
||||||
|
@ -1830,9 +1830,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
|||||||
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
|
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
|
||||||
|
|
||||||
let param_env = obligation.param_env;
|
let param_env = obligation.param_env;
|
||||||
let assoc_ty = match assoc_def(selcx, impl_def_id, assoc_item_id) {
|
let Ok(assoc_ty) = assoc_def(selcx, impl_def_id, assoc_item_id) else {
|
||||||
Ok(assoc_ty) => assoc_ty,
|
return Progress { term: tcx.ty_error().into(), obligations: nested };
|
||||||
Err(ErrorReported) => return Progress { term: tcx.ty_error().into(), obligations: nested },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !assoc_ty.item.defaultness.has_value() {
|
if !assoc_ty.item.defaultness.has_value() {
|
||||||
|
@ -436,11 +436,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) {
|
) {
|
||||||
let kind = match self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) {
|
let Some(kind) = self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) else {
|
||||||
Some(k) => k,
|
return;
|
||||||
None => {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Okay to skip binder because the substs on closure types never
|
// Okay to skip binder because the substs on closure types never
|
||||||
@ -763,12 +760,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// T: Trait
|
// T: Trait
|
||||||
// so it seems ok if we (conservatively) fail to accept that `Unsize`
|
// so it seems ok if we (conservatively) fail to accept that `Unsize`
|
||||||
// obligation above. Should be possible to extend this in the future.
|
// obligation above. Should be possible to extend this in the future.
|
||||||
let source = match obligation.self_ty().no_bound_vars() {
|
let Some(source) = obligation.self_ty().no_bound_vars() else {
|
||||||
Some(t) => t,
|
// Don't add any candidates if there are bound regions.
|
||||||
None => {
|
return;
|
||||||
// Don't add any candidates if there are bound regions.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
|
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
|
||||||
|
|
||||||
|
@ -272,9 +272,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
bug!("unexpected builtin trait {:?}", trait_def)
|
bug!("unexpected builtin trait {:?}", trait_def)
|
||||||
};
|
};
|
||||||
let nested = match conditions {
|
let BuiltinImplConditions::Where(nested) = conditions else {
|
||||||
BuiltinImplConditions::Where(nested) => nested,
|
bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
|
||||||
_ => bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||||
@ -421,9 +420,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
let trait_predicate = self.infcx.replace_bound_vars_with_placeholders(obligation.predicate);
|
let trait_predicate = self.infcx.replace_bound_vars_with_placeholders(obligation.predicate);
|
||||||
let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
|
let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
|
||||||
let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref);
|
let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref);
|
||||||
let data = match *self_ty.kind() {
|
let ty::Dynamic(data, ..) = *self_ty.kind() else {
|
||||||
ty::Dynamic(data, ..) => data,
|
span_bug!(obligation.cause.span, "object candidate with non-object");
|
||||||
_ => span_bug!(obligation.cause.span, "object candidate with non-object"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let object_trait_ref = data.principal().unwrap_or_else(|| {
|
let object_trait_ref = data.principal().unwrap_or_else(|| {
|
||||||
@ -593,9 +591,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// touch bound regions, they just capture the in-scope
|
// touch bound regions, they just capture the in-scope
|
||||||
// type/region parameters.
|
// type/region parameters.
|
||||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
||||||
let (generator_def_id, substs) = match *self_ty.kind() {
|
let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else {
|
||||||
ty::Generator(id, substs, _) => (id, substs),
|
bug!("closure candidate for non-closure {:?}", obligation);
|
||||||
_ => bug!("closure candidate for non-closure {:?}", obligation),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate");
|
debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate");
|
||||||
@ -622,9 +619,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// touch bound regions, they just capture the in-scope
|
// touch bound regions, they just capture the in-scope
|
||||||
// type/region parameters.
|
// type/region parameters.
|
||||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
||||||
let (closure_def_id, substs) = match *self_ty.kind() {
|
let ty::Closure(closure_def_id, substs) = *self_ty.kind() else {
|
||||||
ty::Closure(id, substs) => (id, substs),
|
bug!("closure candidate for non-closure {:?}", obligation);
|
||||||
_ => bug!("closure candidate for non-closure {:?}", obligation),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
|
let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
|
||||||
|
@ -192,18 +192,15 @@ fn fulfill_implication<'a, 'tcx>(
|
|||||||
impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs);
|
impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs);
|
||||||
|
|
||||||
// do the impls unify? If not, no specialization.
|
// do the impls unify? If not, no specialization.
|
||||||
let more_obligations =
|
let Ok(InferOk { obligations: more_obligations, .. }) =
|
||||||
match infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref)
|
infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref)
|
||||||
{
|
else {
|
||||||
Ok(InferOk { obligations, .. }) => obligations,
|
debug!(
|
||||||
Err(_) => {
|
"fulfill_implication: {:?} does not unify with {:?}",
|
||||||
debug!(
|
source_trait_ref, target_trait_ref
|
||||||
"fulfill_implication: {:?} does not unify with {:?}",
|
);
|
||||||
source_trait_ref, target_trait_ref
|
return Err(());
|
||||||
);
|
};
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// attempt to prove all of the predicates for impl2 given those for impl1
|
// attempt to prove all of the predicates for impl2 given those for impl1
|
||||||
// (which are packed up in penv)
|
// (which are packed up in penv)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user