Skip to content
Permalink
Browse files

rustdoc: refactor(?) synthetic impl building.

  • Loading branch information...
eddyb committed Apr 22, 2019
1 parent c835607 commit be9f43e0d4f365b9c1fa895946404693b624236d
@@ -44,7 +44,6 @@ impl<A> AutoTraitResult<A> {
pub struct AutoTraitInfo<'cx> {
pub full_user_env: ty::ParamEnv<'cx>,
pub region_data: RegionConstraintData<'cx>,
pub names_map: FxHashSet<String>,
pub vid_to_region: FxHashMap<ty::RegionVid, ty::Region<'cx>>,
}

@@ -78,15 +77,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
pub fn find_auto_trait_generics<A>(
&self,
ty: Ty<'tcx>,
param_env_def_id: DefId,
orig_env: ty::ParamEnv<'tcx>,
trait_did: DefId,
generics: &ty::Generics,
auto_trait_callback: impl for<'i> Fn(&InferCtxt<'_, 'tcx, 'i>, AutoTraitInfo<'i>) -> A,
) -> AutoTraitResult<A> {
let tcx = self.tcx;

let orig_params = tcx.param_env(param_env_def_id);

let trait_ref = ty::TraitRef {
def_id: trait_did,
substs: tcx.mk_substs_trait(ty, &[]),
@@ -98,16 +94,16 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let mut selcx = SelectionContext::with_negative(&infcx, true);
let result = selcx.select(&Obligation::new(
ObligationCause::dummy(),
orig_params,
orig_env,
trait_pred.to_poly_trait_predicate(),
));

match result {
Ok(Some(Vtable::VtableImpl(_))) => {
debug!(
"find_auto_trait_generics(ty={:?}, trait_did={:?}, generics={:?}): \
"find_auto_trait_generics({:?}): \
manual impl found, bailing out",
ty, trait_did, generics
trait_ref
);
true
}
@@ -160,8 +156,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
&mut infcx,
trait_did,
ty,
orig_params.clone(),
orig_params,
orig_env,
orig_env,
&mut fresh_preds,
false,
) {
@@ -173,21 +169,21 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
&mut infcx,
trait_did,
ty,
new_env.clone(),
new_env,
user_env,
&mut fresh_preds,
true,
).unwrap_or_else(|| {
panic!(
"Failed to fully process: {:?} {:?} {:?}",
ty, trait_did, orig_params
ty, trait_did, orig_env
)
});

debug!(
"find_auto_trait_generics(ty={:?}, trait_did={:?}, generics={:?}): fulfilling \
"find_auto_trait_generics({:?}): fulfilling \
with {:?}",
ty, trait_did, generics, full_env
trait_ref, full_env
);
infcx.clear_caches();

@@ -209,23 +205,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
)
});

let names_map: FxHashSet<String> = generics
.params
.iter()
.filter_map(|param| match param.kind {
ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
_ => None,
})
.collect();

let body_id_map: FxHashMap<_, _> = infcx
.region_obligations
.borrow()
.iter()
.map(|&(id, _)| (id, vec![]))
.collect();

infcx.process_registered_region_obligations(&body_id_map, None, full_env.clone());
infcx.process_registered_region_obligations(&body_id_map, None, full_env);

let region_data = infcx
.borrow_region_constraints()
@@ -237,7 +224,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let info = AutoTraitInfo {
full_user_env,
region_data,
names_map,
vid_to_region,
};

@@ -284,7 +270,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// the final synthesized generics: we don't want our generated docs page to contain something
// like 'T: Copy + Clone', as that's redundant. Therefore, we keep track of a separate
// 'user_env', which only holds the predicates that will actually be displayed to the user.
pub fn evaluate_predicates<'b, 'gcx, 'c>(
fn evaluate_predicates<'b, 'gcx, 'c>(
&self,
infcx: &InferCtxt<'b, 'tcx, 'c>,
trait_did: DefId,
@@ -311,13 +297,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let mut user_computed_preds: FxHashSet<_> =
user_env.caller_bounds.iter().cloned().collect();

let mut new_env = param_env.clone();
let mut new_env = param_env;
let dummy_cause = ObligationCause::misc(DUMMY_SP, hir::DUMMY_HIR_ID);

while let Some(pred) = predicates.pop_front() {
infcx.clear_caches();

if !already_visited.insert(pred.clone()) {
if !already_visited.insert(pred) {
continue;
}

@@ -365,7 +351,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
already_visited.remove(&pred);
self.add_user_pred(
&mut user_computed_preds,
ty::Predicate::Trait(pred.clone()),
ty::Predicate::Trait(pred),
);
predicates.push_back(pred);
} else {
@@ -384,7 +370,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {

computed_preds.extend(user_computed_preds.iter().cloned());
let normalized_preds =
elaborate_predicates(tcx, computed_preds.clone().into_iter().collect());
elaborate_predicates(tcx, computed_preds.iter().cloned().collect());
new_env = ty::ParamEnv::new(
tcx.mk_predicates(normalized_preds),
param_env.reveal,
@@ -519,28 +505,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
}
}

pub fn region_name(&self, region: Region<'_>) -> Option<String> {
match region {
&ty::ReEarlyBound(r) => Some(r.name.to_string()),
_ => None,
}
}

pub fn get_lifetime(&self, region: Region<'_>,
names_map: &FxHashMap<String, String>) -> String {
self.region_name(region)
.map(|name|
names_map.get(&name).unwrap_or_else(||
panic!("Missing lifetime with name {:?} for {:?}", name, region)
)
)
.cloned()
.unwrap_or_else(|| "'static".to_owned())
}

// This is very similar to handle_lifetimes. However, instead of matching ty::Region's
// to each other, we match ty::RegionVid's to ty::Region's
pub fn map_vid_to_region<'cx>(
fn map_vid_to_region<'cx>(
&self,
regions: &RegionConstraintData<'cx>,
) -> FxHashMap<ty::RegionVid, ty::Region<'cx>> {
@@ -650,7 +617,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
}
}

pub fn evaluate_nested_obligations<
fn evaluate_nested_obligations<
'b,
'c,
'd,
@@ -669,10 +636,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let dummy_cause = ObligationCause::misc(DUMMY_SP, hir::DUMMY_HIR_ID);

for (obligation, mut predicate) in nested
.map(|o| (o.clone(), o.predicate.clone()))
.map(|o| (o.clone(), o.predicate))
{
let is_new_pred =
fresh_preds.insert(self.clean_pred(select.infcx(), predicate.clone()));
fresh_preds.insert(self.clean_pred(select.infcx(), predicate));

// Resolve any inference variables that we can, to help selection succeed
predicate = select.infcx().resolve_type_vars_if_possible(&predicate);
@@ -690,14 +657,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// We check this by calling is_of_param on the relevant types
// from the various possible predicates
match &predicate {
&ty::Predicate::Trait(ref p) => {
&ty::Predicate::Trait(p) => {
if self.is_param_no_infer(p.skip_binder().trait_ref.substs)
&& !only_projections
&& is_new_pred {

self.add_user_pred(computed_preds, predicate);
}
predicates.push_back(p.clone());
predicates.push_back(p);
}
&ty::Predicate::Projection(p) => {
debug!("evaluate_nested_obligations: examining projection predicate {:?}",
@@ -739,7 +706,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
if p.ty().skip_binder().has_infer_types() {
debug!("Projecting and unifying projection predicate {:?}",
predicate);
match poly_project_and_unify_type(select, &obligation.with(p.clone())) {
match poly_project_and_unify_type(select, &obligation.with(p)) {
Err(e) => {
debug!(
"evaluate_nested_obligations: Unable to unify predicate \
Oops, something went wrong.

0 comments on commit be9f43e

Please sign in to comment.
You can’t perform that action at this time.