mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
remove the data from ClosureCandidate
the data serves no purpose - it can be recovered from the obligation - and I think may leak stale inference variables into global caches.
This commit is contained in:
parent
9be155d88e
commit
6c11b47745
@ -194,13 +194,12 @@ enum SelectionCandidate<'tcx> {
|
||||
ProjectionCandidate,
|
||||
|
||||
/// Implementation of a `Fn`-family trait by one of the anonymous types
|
||||
/// generated for a `||` expression. The ty::ClosureKind informs the
|
||||
/// confirmation step what ClosureKind obligation to emit.
|
||||
ClosureCandidate(/* closure */ DefId, ty::ClosureSubsts<'tcx>, ty::ClosureKind),
|
||||
/// generated for a `||` expression.
|
||||
ClosureCandidate,
|
||||
|
||||
/// Implementation of a `Generator` trait by one of the anonymous types
|
||||
/// generated for a generator.
|
||||
GeneratorCandidate(/* function / closure */ DefId, ty::ClosureSubsts<'tcx>),
|
||||
GeneratorCandidate,
|
||||
|
||||
/// Implementation of a `Fn`-family trait by one of the anonymous
|
||||
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
|
||||
@ -229,20 +228,12 @@ impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> {
|
||||
ObjectCandidate => ObjectCandidate,
|
||||
BuiltinObjectCandidate => BuiltinObjectCandidate,
|
||||
BuiltinUnsizeCandidate => BuiltinUnsizeCandidate,
|
||||
ClosureCandidate => ClosureCandidate,
|
||||
GeneratorCandidate => GeneratorCandidate,
|
||||
|
||||
ParamCandidate(ref trait_ref) => {
|
||||
return tcx.lift(trait_ref).map(ParamCandidate);
|
||||
}
|
||||
GeneratorCandidate(def_id, ref substs) => {
|
||||
return tcx.lift(substs).map(|substs| {
|
||||
GeneratorCandidate(def_id, substs)
|
||||
});
|
||||
}
|
||||
ClosureCandidate(def_id, ref substs, kind) => {
|
||||
return tcx.lift(substs).map(|substs| {
|
||||
ClosureCandidate(def_id, substs, kind)
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1518,23 +1509,22 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters
|
||||
let self_ty = *obligation.self_ty().skip_binder();
|
||||
let (closure_def_id, substs) = match self_ty.sty {
|
||||
ty::TyGenerator(id, substs, _) => (id, substs),
|
||||
match self_ty.sty {
|
||||
ty::TyGenerator(..) => {
|
||||
debug!("assemble_generator_candidates: self_ty={:?} obligation={:?}",
|
||||
self_ty,
|
||||
obligation);
|
||||
|
||||
candidates.vec.push(GeneratorCandidate);
|
||||
Ok(())
|
||||
}
|
||||
ty::TyInfer(ty::TyVar(_)) => {
|
||||
debug!("assemble_generator_candidates: ambiguous self-type");
|
||||
candidates.ambiguous = true;
|
||||
return Ok(());
|
||||
}
|
||||
_ => { return Ok(()); }
|
||||
};
|
||||
|
||||
debug!("assemble_generator_candidates: self_ty={:?} obligation={:?}",
|
||||
self_ty,
|
||||
obligation);
|
||||
|
||||
candidates.vec.push(GeneratorCandidate(closure_def_id, substs));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Check for the artificial impl that the compiler will create for an obligation like `X :
|
||||
@ -1556,36 +1546,31 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
// ok to skip binder because the substs on closure types never
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters
|
||||
let self_ty = *obligation.self_ty().skip_binder();
|
||||
let (closure_def_id, substs) = match self_ty.sty {
|
||||
ty::TyClosure(id, substs) => (id, substs),
|
||||
match obligation.self_ty().skip_binder().sty {
|
||||
ty::TyClosure(closure_def_id, _) => {
|
||||
debug!("assemble_unboxed_candidates: kind={:?} obligation={:?}",
|
||||
kind, obligation);
|
||||
match self.infcx.closure_kind(closure_def_id) {
|
||||
Some(closure_kind) => {
|
||||
debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
|
||||
if closure_kind.extends(kind) {
|
||||
candidates.vec.push(ClosureCandidate);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
debug!("assemble_unboxed_candidates: closure_kind not yet known");
|
||||
candidates.vec.push(ClosureCandidate);
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
ty::TyInfer(ty::TyVar(_)) => {
|
||||
debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
|
||||
candidates.ambiguous = true;
|
||||
return Ok(());
|
||||
}
|
||||
_ => { return Ok(()); }
|
||||
};
|
||||
|
||||
debug!("assemble_unboxed_candidates: self_ty={:?} kind={:?} obligation={:?}",
|
||||
self_ty,
|
||||
kind,
|
||||
obligation);
|
||||
|
||||
match self.infcx.closure_kind(closure_def_id) {
|
||||
Some(closure_kind) => {
|
||||
debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
|
||||
if closure_kind.extends(kind) {
|
||||
candidates.vec.push(ClosureCandidate(closure_def_id, substs, kind));
|
||||
}
|
||||
}
|
||||
None => {
|
||||
debug!("assemble_unboxed_candidates: closure_kind not yet known");
|
||||
candidates.vec.push(ClosureCandidate(closure_def_id, substs, kind));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Implement one of the `Fn()` family for a fn pointer.
|
||||
@ -1902,8 +1887,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
when there are other valid candidates");
|
||||
}
|
||||
ImplCandidate(..) |
|
||||
ClosureCandidate(..) |
|
||||
GeneratorCandidate(..) |
|
||||
ClosureCandidate |
|
||||
GeneratorCandidate |
|
||||
FnPointerCandidate |
|
||||
BuiltinObjectCandidate |
|
||||
BuiltinUnsizeCandidate |
|
||||
@ -2245,15 +2230,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id)))
|
||||
}
|
||||
|
||||
ClosureCandidate(closure_def_id, substs, kind) => {
|
||||
let vtable_closure =
|
||||
self.confirm_closure_candidate(obligation, closure_def_id, substs, kind)?;
|
||||
ClosureCandidate => {
|
||||
let vtable_closure = self.confirm_closure_candidate(obligation)?;
|
||||
Ok(VtableClosure(vtable_closure))
|
||||
}
|
||||
|
||||
GeneratorCandidate(closure_def_id, substs) => {
|
||||
let vtable_generator =
|
||||
self.confirm_generator_candidate(obligation, closure_def_id, substs)?;
|
||||
GeneratorCandidate => {
|
||||
let vtable_generator = self.confirm_generator_candidate(obligation)?;
|
||||
Ok(VtableGenerator(vtable_generator))
|
||||
}
|
||||
|
||||
@ -2590,21 +2573,34 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn confirm_generator_candidate(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
substs: ty::ClosureSubsts<'tcx>)
|
||||
-> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
|
||||
obligation: &TraitObligation<'tcx>)
|
||||
-> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
|
||||
SelectionError<'tcx>>
|
||||
{
|
||||
// ok to skip binder because the substs on generator types never
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters
|
||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
||||
let (closure_def_id, substs) = match self_ty.sty {
|
||||
ty::TyGenerator(id, substs, _) => (id, substs),
|
||||
_ => bug!("closure candidate for non-closure {:?}", obligation)
|
||||
};
|
||||
|
||||
debug!("confirm_generator_candidate({:?},{:?},{:?})",
|
||||
obligation,
|
||||
closure_def_id,
|
||||
substs);
|
||||
|
||||
let trait_ref =
|
||||
self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
|
||||
let Normalized {
|
||||
value: trait_ref,
|
||||
obligations
|
||||
} = self.generator_trait_ref(obligation, closure_def_id, substs);
|
||||
} = normalize_with_depth(self,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth+1,
|
||||
&trait_ref);
|
||||
|
||||
debug!("confirm_generator_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
|
||||
closure_def_id,
|
||||
@ -2624,22 +2620,36 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn confirm_closure_candidate(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
substs: ty::ClosureSubsts<'tcx>,
|
||||
kind: ty::ClosureKind)
|
||||
obligation: &TraitObligation<'tcx>)
|
||||
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
|
||||
SelectionError<'tcx>>
|
||||
{
|
||||
debug!("confirm_closure_candidate({:?},{:?},{:?})",
|
||||
obligation,
|
||||
closure_def_id,
|
||||
substs);
|
||||
debug!("confirm_closure_candidate({:?})", obligation);
|
||||
|
||||
let kind = match self.tcx().lang_items.fn_trait_kind(obligation.predicate.0.def_id()) {
|
||||
Some(k) => k,
|
||||
None => bug!("closure candidate for non-fn trait {:?}", obligation)
|
||||
};
|
||||
|
||||
// ok to skip binder because the substs on closure types never
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters
|
||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
||||
let (closure_def_id, substs) = match self_ty.sty {
|
||||
ty::TyClosure(id, substs) => (id, substs),
|
||||
_ => bug!("closure candidate for non-closure {:?}", obligation)
|
||||
};
|
||||
|
||||
let trait_ref =
|
||||
self.closure_trait_ref_unnormalized(obligation, closure_def_id, substs);
|
||||
let Normalized {
|
||||
value: trait_ref,
|
||||
mut obligations
|
||||
} = self.closure_trait_ref(obligation, closure_def_id, substs);
|
||||
} = normalize_with_depth(self,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth+1,
|
||||
&trait_ref);
|
||||
|
||||
debug!("confirm_closure_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
|
||||
closure_def_id,
|
||||
@ -3106,24 +3116,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
ty::Binder(trait_ref)
|
||||
}
|
||||
|
||||
fn closure_trait_ref(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
substs: ty::ClosureSubsts<'tcx>)
|
||||
-> Normalized<'tcx, ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
let trait_ref = self.closure_trait_ref_unnormalized(
|
||||
obligation, closure_def_id, substs);
|
||||
|
||||
// A closure signature can contain associated types which
|
||||
// must be normalized.
|
||||
normalize_with_depth(self,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth+1,
|
||||
&trait_ref)
|
||||
}
|
||||
|
||||
fn generator_trait_ref_unnormalized(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
@ -3145,24 +3137,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
ty::Binder(trait_ref)
|
||||
}
|
||||
|
||||
fn generator_trait_ref(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
substs: ty::ClosureSubsts<'tcx>)
|
||||
-> Normalized<'tcx, ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
let trait_ref = self.generator_trait_ref_unnormalized(
|
||||
obligation, closure_def_id, substs);
|
||||
|
||||
// A generator signature can contain associated types which
|
||||
// must be normalized.
|
||||
normalize_with_depth(self,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth+1,
|
||||
&trait_ref)
|
||||
}
|
||||
|
||||
/// Returns the obligations that are implied by instantiating an
|
||||
/// impl or trait. The obligations are substituted and fully
|
||||
/// normalized. This is used when confirming an impl or default
|
||||
|
Loading…
Reference in New Issue
Block a user