Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the trait selection impl in method::probe #43880

Merged
merged 5 commits into from
Aug 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 80 additions & 106 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand Down Expand Up @@ -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)
});
}
})
}
}
Expand Down Expand Up @@ -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 :
Expand All @@ -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.
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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))
}

Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down
18 changes: 0 additions & 18 deletions src/librustc_typeck/check/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,24 +232,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
})
}

probe::ExtensionImplPick(impl_def_id) => {
// The method being invoked is the method as defined on the trait,
// so return the substitutions from the trait. Consider:
//
// impl<A,B,C> Trait<A,B> for Foo<C> { ... }
//
// If we instantiate A, B, and C with $A, $B, and $C
// respectively, then we want to return the type
// parameters from the trait ([$A,$B]), not those from
// the impl ([$A,$B,$C]) not the receiver type ([$C]).
let impl_polytype = self.impl_self_ty(self.span, impl_def_id);
let impl_trait_ref =
self.instantiate_type_scheme(self.span,
impl_polytype.substs,
&self.tcx.impl_trait_ref(impl_def_id).unwrap());
impl_trait_ref.substs
}

probe::TraitPick => {
let trait_def_id = pick.item.container.id();

Expand Down
12 changes: 7 additions & 5 deletions src/librustc_typeck/check/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,16 @@ pub enum MethodError<'tcx> {
// Multiple methods might apply.
Ambiguity(Vec<CandidateSource>),

// Using a `Fn`/`FnMut`/etc method on a raw closure type before we have inferred its kind.
ClosureAmbiguity(// DefId of fn trait
DefId),

// Found an applicable method, but it is not visible. The second argument contains a list of
// not-in-scope traits which may work.
PrivateMatch(Def, Vec<DefId>),

// Found a `Self: Sized` bound where `Self` is a trait object, also the caller may have
// forgotten to import a trait.
IllegalSizedBound(Vec<DefId>),

// Found a match, but the return type is wrong
BadReturnType,
}

// Contains a list of static methods that may apply, a list of unsatisfied trait predicates which
Expand Down Expand Up @@ -113,9 +112,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Ok(..) => true,
Err(NoMatch(..)) => false,
Err(Ambiguity(..)) => true,
Err(ClosureAmbiguity(..)) => true,
Err(PrivateMatch(..)) => allow_private,
Err(IllegalSizedBound(..)) => true,
Err(BadReturnType) => {
bug!("no return type expectations but got BadReturnType")
}

}
}

Expand Down
Loading