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,
|
ProjectionCandidate,
|
||||||
|
|
||||||
/// Implementation of a `Fn`-family trait by one of the anonymous types
|
/// Implementation of a `Fn`-family trait by one of the anonymous types
|
||||||
/// generated for a `||` expression. The ty::ClosureKind informs the
|
/// generated for a `||` expression.
|
||||||
/// confirmation step what ClosureKind obligation to emit.
|
ClosureCandidate,
|
||||||
ClosureCandidate(/* closure */ DefId, ty::ClosureSubsts<'tcx>, ty::ClosureKind),
|
|
||||||
|
|
||||||
/// Implementation of a `Generator` trait by one of the anonymous types
|
/// Implementation of a `Generator` trait by one of the anonymous types
|
||||||
/// generated for a generator.
|
/// generated for a generator.
|
||||||
GeneratorCandidate(/* function / closure */ DefId, ty::ClosureSubsts<'tcx>),
|
GeneratorCandidate,
|
||||||
|
|
||||||
/// Implementation of a `Fn`-family trait by one of the anonymous
|
/// Implementation of a `Fn`-family trait by one of the anonymous
|
||||||
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
|
/// 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,
|
ObjectCandidate => ObjectCandidate,
|
||||||
BuiltinObjectCandidate => BuiltinObjectCandidate,
|
BuiltinObjectCandidate => BuiltinObjectCandidate,
|
||||||
BuiltinUnsizeCandidate => BuiltinUnsizeCandidate,
|
BuiltinUnsizeCandidate => BuiltinUnsizeCandidate,
|
||||||
|
ClosureCandidate => ClosureCandidate,
|
||||||
|
GeneratorCandidate => GeneratorCandidate,
|
||||||
|
|
||||||
ParamCandidate(ref trait_ref) => {
|
ParamCandidate(ref trait_ref) => {
|
||||||
return tcx.lift(trait_ref).map(ParamCandidate);
|
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
|
// touch bound regions, they just capture the in-scope
|
||||||
// type/region parameters
|
// type/region parameters
|
||||||
let self_ty = *obligation.self_ty().skip_binder();
|
let self_ty = *obligation.self_ty().skip_binder();
|
||||||
let (closure_def_id, substs) = match self_ty.sty {
|
match self_ty.sty {
|
||||||
ty::TyGenerator(id, substs, _) => (id, substs),
|
ty::TyGenerator(..) => {
|
||||||
|
debug!("assemble_generator_candidates: self_ty={:?} obligation={:?}",
|
||||||
|
self_ty,
|
||||||
|
obligation);
|
||||||
|
|
||||||
|
candidates.vec.push(GeneratorCandidate);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
ty::TyInfer(ty::TyVar(_)) => {
|
ty::TyInfer(ty::TyVar(_)) => {
|
||||||
debug!("assemble_generator_candidates: ambiguous self-type");
|
debug!("assemble_generator_candidates: ambiguous self-type");
|
||||||
candidates.ambiguous = true;
|
candidates.ambiguous = true;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
_ => { 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 :
|
/// 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
|
// ok to skip binder because the substs on closure types never
|
||||||
// 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 = *obligation.self_ty().skip_binder();
|
match obligation.self_ty().skip_binder().sty {
|
||||||
let (closure_def_id, substs) = match self_ty.sty {
|
ty::TyClosure(closure_def_id, _) => {
|
||||||
ty::TyClosure(id, substs) => (id, substs),
|
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(_)) => {
|
ty::TyInfer(ty::TyVar(_)) => {
|
||||||
debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
|
debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
|
||||||
candidates.ambiguous = true;
|
candidates.ambiguous = true;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
_ => { 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.
|
/// 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");
|
when there are other valid candidates");
|
||||||
}
|
}
|
||||||
ImplCandidate(..) |
|
ImplCandidate(..) |
|
||||||
ClosureCandidate(..) |
|
ClosureCandidate |
|
||||||
GeneratorCandidate(..) |
|
GeneratorCandidate |
|
||||||
FnPointerCandidate |
|
FnPointerCandidate |
|
||||||
BuiltinObjectCandidate |
|
BuiltinObjectCandidate |
|
||||||
BuiltinUnsizeCandidate |
|
BuiltinUnsizeCandidate |
|
||||||
@ -2245,15 +2230,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id)))
|
Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
ClosureCandidate(closure_def_id, substs, kind) => {
|
ClosureCandidate => {
|
||||||
let vtable_closure =
|
let vtable_closure = self.confirm_closure_candidate(obligation)?;
|
||||||
self.confirm_closure_candidate(obligation, closure_def_id, substs, kind)?;
|
|
||||||
Ok(VtableClosure(vtable_closure))
|
Ok(VtableClosure(vtable_closure))
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneratorCandidate(closure_def_id, substs) => {
|
GeneratorCandidate => {
|
||||||
let vtable_generator =
|
let vtable_generator = self.confirm_generator_candidate(obligation)?;
|
||||||
self.confirm_generator_candidate(obligation, closure_def_id, substs)?;
|
|
||||||
Ok(VtableGenerator(vtable_generator))
|
Ok(VtableGenerator(vtable_generator))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2590,21 +2573,34 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_generator_candidate(&mut self,
|
fn confirm_generator_candidate(&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>)
|
||||||
closure_def_id: DefId,
|
-> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
|
||||||
substs: ty::ClosureSubsts<'tcx>)
|
|
||||||
-> Result<VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
|
|
||||||
SelectionError<'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({:?},{:?},{:?})",
|
debug!("confirm_generator_candidate({:?},{:?},{:?})",
|
||||||
obligation,
|
obligation,
|
||||||
closure_def_id,
|
closure_def_id,
|
||||||
substs);
|
substs);
|
||||||
|
|
||||||
|
let trait_ref =
|
||||||
|
self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
|
||||||
let Normalized {
|
let Normalized {
|
||||||
value: trait_ref,
|
value: trait_ref,
|
||||||
obligations
|
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={:?})",
|
debug!("confirm_generator_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
|
||||||
closure_def_id,
|
closure_def_id,
|
||||||
@ -2624,22 +2620,36 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_closure_candidate(&mut self,
|
fn confirm_closure_candidate(&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>)
|
||||||
closure_def_id: DefId,
|
|
||||||
substs: ty::ClosureSubsts<'tcx>,
|
|
||||||
kind: ty::ClosureKind)
|
|
||||||
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
|
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
|
||||||
SelectionError<'tcx>>
|
SelectionError<'tcx>>
|
||||||
{
|
{
|
||||||
debug!("confirm_closure_candidate({:?},{:?},{:?})",
|
debug!("confirm_closure_candidate({:?})", obligation);
|
||||||
obligation,
|
|
||||||
closure_def_id,
|
|
||||||
substs);
|
|
||||||
|
|
||||||
|
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 {
|
let Normalized {
|
||||||
value: trait_ref,
|
value: trait_ref,
|
||||||
mut obligations
|
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={:?})",
|
debug!("confirm_closure_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
|
||||||
closure_def_id,
|
closure_def_id,
|
||||||
@ -3106,24 +3116,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
ty::Binder(trait_ref)
|
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,
|
fn generator_trait_ref_unnormalized(&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
closure_def_id: DefId,
|
closure_def_id: DefId,
|
||||||
@ -3145,24 +3137,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||||||
ty::Binder(trait_ref)
|
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
|
/// Returns the obligations that are implied by instantiating an
|
||||||
/// impl or trait. The obligations are substituted and fully
|
/// impl or trait. The obligations are substituted and fully
|
||||||
/// normalized. This is used when confirming an impl or default
|
/// normalized. This is used when confirming an impl or default
|
||||||
|
Loading…
Reference in New Issue
Block a user