Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5cfc9f3

Browse files
committedNov 21, 2023
Extract find_candidate function
1 parent 2d0b397 commit 5cfc9f3

File tree

1 file changed

+89
-86
lines changed
  • compiler/rustc_hir_analysis/src/astconv

1 file changed

+89
-86
lines changed
 

‎compiler/rustc_hir_analysis/src/astconv/mod.rs

+89-86
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ use rustc_infer::traits::ObligationCause;
3131
use rustc_middle::middle::stability::AllowUnstable;
3232
use rustc_middle::ty::GenericParamDefKind;
3333
use rustc_middle::ty::{
34-
self, Const, GenericArgKind, GenericArgsRef, IsSuggestable, Ty, TyCtxt, TypeVisitableExt,
34+
self, Const, GenericArgKind, GenericArgsRef, IsSuggestable, ParamEnv, Ty, TyCtxt,
35+
TypeVisitableExt,
3536
};
3637
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
3738
use rustc_span::edit_distance::find_best_match_for_name;
@@ -1607,7 +1608,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16071608
let param_env = tcx.param_env(block.owner);
16081609
let cause = ObligationCause::misc(span, block.owner.def_id);
16091610

1610-
let mut fulfillment_errors = Vec::new();
16111611
infcx.probe(|_| {
16121612
let mut universes = if self_ty.has_escaping_bound_vars() {
16131613
vec![None; self_ty.outer_exclusive_binder().as_usize()]
@@ -1620,99 +1620,102 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16201620
&mut universes,
16211621
self_ty,
16221622
|self_ty| {
1623-
let InferOk { value: self_ty, obligations } =
1624-
infcx.at(&cause, param_env).normalize(self_ty);
1623+
self.find_candidate(
1624+
infcx, self_ty, name, segment, block, span, cause, param_env, candidates,
1625+
)
1626+
},
1627+
)
1628+
})
1629+
}
16251630

1626-
let mut applicable_candidates: Vec<_> = candidates
1627-
.iter()
1628-
.copied()
1629-
.filter(|&(impl_, _)| {
1630-
infcx.probe(|_| {
1631-
let ocx = ObligationCtxt::new(&infcx);
1632-
ocx.register_obligations(obligations.clone());
1633-
1634-
let impl_args = infcx.fresh_args_for_item(span, impl_);
1635-
let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
1636-
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
1637-
1638-
// Check that the self types can be related.
1639-
if ocx
1640-
.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty)
1641-
.is_err()
1642-
{
1643-
return false;
1644-
}
1631+
fn find_candidate(
1632+
&self,
1633+
infcx: &InferCtxt<'tcx>,
1634+
self_ty: Ty<'tcx>,
1635+
name: Ident,
1636+
segment: &hir::PathSegment<'_>,
1637+
block: hir::HirId,
1638+
span: Span,
1639+
cause: ObligationCause<'tcx>,
1640+
param_env: ParamEnv<'tcx>,
1641+
candidates: Vec<(DefId, (DefId, DefId))>,
1642+
) -> Result<Option<(Ty<'tcx>, DefId)>, ErrorGuaranteed> {
1643+
let mut fulfillment_errors = Vec::new();
1644+
let tcx = self.tcx();
1645+
let InferOk { value: self_ty, obligations } =
1646+
infcx.at(&cause, param_env).normalize(self_ty);
16451647

1646-
// Check whether the impl imposes obligations we have to worry about.
1647-
let impl_bounds =
1648-
tcx.predicates_of(impl_).instantiate(tcx, impl_args);
1649-
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
1650-
let impl_obligations = traits::predicates_for_generics(
1651-
|_, _| cause.clone(),
1652-
param_env,
1653-
impl_bounds,
1654-
);
1655-
ocx.register_obligations(impl_obligations);
1648+
let mut applicable_candidates: Vec<_> = candidates
1649+
.iter()
1650+
.copied()
1651+
.filter(|&(impl_, _)| {
1652+
infcx.probe(|_| {
1653+
let ocx = ObligationCtxt::new(&infcx);
1654+
ocx.register_obligations(obligations.clone());
1655+
1656+
let impl_args = infcx.fresh_args_for_item(span, impl_);
1657+
let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
1658+
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
1659+
1660+
// Check that the self types can be related.
1661+
if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
1662+
return false;
1663+
}
16561664

1657-
let mut errors = ocx.select_where_possible();
1658-
if !errors.is_empty() {
1659-
fulfillment_errors.append(&mut errors);
1660-
return false;
1661-
}
1665+
// Check whether the impl imposes obligations we have to worry about.
1666+
let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
1667+
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
1668+
let impl_obligations = traits::predicates_for_generics(
1669+
|_, _| cause.clone(),
1670+
param_env,
1671+
impl_bounds,
1672+
);
1673+
ocx.register_obligations(impl_obligations);
16621674

1663-
true
1664-
})
1665-
})
1666-
.collect();
1667-
1668-
if applicable_candidates.len() > 1 {
1669-
return Err(self.complain_about_ambiguous_inherent_assoc_type(
1670-
name,
1671-
applicable_candidates
1672-
.into_iter()
1673-
.map(|(_, (candidate, _))| candidate)
1674-
.collect(),
1675-
span,
1676-
));
1675+
let mut errors = ocx.select_where_possible();
1676+
if !errors.is_empty() {
1677+
fulfillment_errors.append(&mut errors);
1678+
return false;
16771679
}
16781680

1679-
if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
1680-
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
1681-
1682-
// FIXME(fmease): Currently creating throwaway `parent_args` to please
1683-
// `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1684-
// not require the parent args logic.
1685-
let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1686-
let args = self.create_args_for_associated_item(
1687-
span,
1688-
assoc_item,
1689-
segment,
1690-
parent_args,
1691-
);
1692-
let args = tcx.mk_args_from_iter(
1693-
std::iter::once(ty::GenericArg::from(self_ty))
1694-
.chain(args.into_iter().skip(parent_args.len())),
1695-
);
1681+
true
1682+
})
1683+
})
1684+
.collect();
16961685

1697-
let ty = Ty::new_alias(
1698-
tcx,
1699-
ty::Inherent,
1700-
ty::AliasTy::new(tcx, assoc_item, args),
1701-
);
1686+
if applicable_candidates.len() > 1 {
1687+
return Err(self.complain_about_ambiguous_inherent_assoc_type(
1688+
name,
1689+
applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
1690+
span,
1691+
));
1692+
}
17021693

1703-
return Ok(Some((ty, assoc_item)));
1704-
}
1694+
if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
1695+
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
1696+
1697+
// FIXME(fmease): Currently creating throwaway `parent_args` to please
1698+
// `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1699+
// not require the parent args logic.
1700+
let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1701+
let args = self.create_args_for_associated_item(span, assoc_item, segment, parent_args);
1702+
let args = tcx.mk_args_from_iter(
1703+
std::iter::once(ty::GenericArg::from(self_ty))
1704+
.chain(args.into_iter().skip(parent_args.len())),
1705+
);
17051706

1706-
Err(self.complain_about_inherent_assoc_type_not_found(
1707-
name,
1708-
self_ty,
1709-
candidates,
1710-
fulfillment_errors,
1711-
span,
1712-
))
1713-
},
1714-
)
1715-
})
1707+
let ty = Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new(tcx, assoc_item, args));
1708+
1709+
return Ok(Some((ty, assoc_item)));
1710+
}
1711+
1712+
Err(self.complain_about_inherent_assoc_type_not_found(
1713+
name,
1714+
self_ty,
1715+
candidates,
1716+
fulfillment_errors,
1717+
span,
1718+
))
17161719
}
17171720

17181721
fn lookup_assoc_ty(

0 commit comments

Comments
 (0)
Please sign in to comment.