Skip to content

Commit 3ee85d8

Browse files
committed
Kill dead code
1 parent 87edbea commit 3ee85d8

File tree

1 file changed

+0
-279
lines changed

1 file changed

+0
-279
lines changed

src/librustc/middle/traits/select.rs

Lines changed: 0 additions & 279 deletions
Original file line numberDiff line numberDiff line change
@@ -412,285 +412,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
412412
})
413413
}
414414

415-
///////////////////////////////////////////////////////////////////////////
416-
// METHOD MATCHING
417-
//
418-
// Method matching is a variation on the normal select/evaluation
419-
// situation. In this scenario, rather than having a full trait
420-
// reference to select from, we start with an expression like
421-
// `receiver.method(...)`. This means that we have `rcvr_ty`, the
422-
// type of the receiver, and we have a possible trait that
423-
// supplies `method`. We must determine whether the receiver is
424-
// applicable, taking into account the transformed self type
425-
// declared on `method`. We also must consider the possibility
426-
// that `receiver` can be *coerced* into a suitable type (for
427-
// example, a receiver type like `&(Any+Send)` might be coerced
428-
// into a receiver like `&Any` to allow for method dispatch). See
429-
// the body of `evaluate_method_obligation()` for more details on
430-
// the algorithm.
431-
432-
/// Determine whether a trait-method is applicable to a receiver of
433-
/// type `rcvr_ty`. *Does not affect the inference state.*
434-
///
435-
/// - `rcvr_ty` -- type of the receiver
436-
/// - `xform_self_ty` -- transformed self type declared on the method, with `Self`
437-
/// to a fresh type variable
438-
/// - `obligation` -- a reference to the trait where the method is declared, with
439-
/// the input types on the trait replaced with fresh type variables
440-
pub fn evaluate_method_obligation(&mut self,
441-
rcvr_ty: Ty<'tcx>,
442-
xform_self_ty: Ty<'tcx>,
443-
obligation: &Obligation<'tcx>)
444-
-> MethodMatchResult
445-
{
446-
// Here is the situation. We have a trait method declared (say) like so:
447-
//
448-
// trait TheTrait {
449-
// fn the_method(self: Rc<Self>, ...) { ... }
450-
// }
451-
//
452-
// And then we have a call looking (say) like this:
453-
//
454-
// let x: Rc<Foo> = ...;
455-
// x.the_method()
456-
//
457-
// Now we want to decide if `TheTrait` is applicable. As a
458-
// human, we can see that `TheTrait` is applicable if there is
459-
// an impl for the type `Foo`. But how does the compiler know
460-
// what impl to look for, given that our receiver has type
461-
// `Rc<Foo>`? We need to take the method's self type into
462-
// account.
463-
//
464-
// On entry to this function, we have the following inputs:
465-
//
466-
// - `rcvr_ty = Rc<Foo>`
467-
// - `xform_self_ty = Rc<$0>`
468-
// - `obligation = $0 as TheTrait`
469-
//
470-
// We do the match in two phases. The first is a *precise
471-
// match*, which means that no coercion is required. This is
472-
// the preferred way to match. It works by first making
473-
// `rcvr_ty` a subtype of `xform_self_ty`. This unifies `$0`
474-
// and `Foo`. We can then evaluate (roughly as normal) the
475-
// trait reference `Foo as TheTrait`.
476-
//
477-
// If this fails, we fallback to a coercive match, described below.
478-
479-
match self.infcx.probe(|| self.match_method_precise(rcvr_ty, xform_self_ty, obligation)) {
480-
Ok(()) => { return MethodMatched(PreciseMethodMatch); }
481-
Err(_) => { }
482-
}
483-
484-
// Coercive matches work slightly differently and cannot
485-
// completely reuse the normal trait matching machinery
486-
// (though they employ many of the same bits and pieces). To
487-
// see how it works, let's continue with our previous example,
488-
// but with the following declarations:
489-
//
490-
// ```
491-
// trait Foo : Bar { .. }
492-
// trait Bar : Baz { ... }
493-
// trait Baz { ... }
494-
// impl TheTrait for Bar {
495-
// fn the_method(self: Rc<Bar>, ...) { ... }
496-
// }
497-
// ```
498-
//
499-
// Now we see that the receiver type `Rc<Foo>` is actually an
500-
// object type. And in fact the impl we want is an impl on the
501-
// supertrait `Rc<Bar>`. The precise matching procedure won't
502-
// find it, however, because `Rc<Foo>` is not a subtype of
503-
// `Rc<Bar>` -- it is *coercible* to `Rc<Bar>` (actually, such
504-
// coercions are not yet implemented, but let's leave that
505-
// aside for now).
506-
//
507-
// To handle this case, we employ a different procedure. Recall
508-
// that our initial state is as follows:
509-
//
510-
// - `rcvr_ty = Rc<Foo>`
511-
// - `xform_self_ty = Rc<$0>`
512-
// - `obligation = $0 as TheTrait`
513-
//
514-
// We now go through each impl and instantiate all of its type
515-
// variables, yielding the trait reference that the impl
516-
// provides. In our example, the impl would provide `Bar as
517-
// TheTrait`. Next we (try to) unify the trait reference that
518-
// the impl provides with the input obligation. This would
519-
// unify `$0` and `Bar`. Now we can see whether the receiver
520-
// type (`Rc<Foo>`) is *coercible to* the transformed self
521-
// type (`Rc<$0> == Rc<Bar>`). In this case, the answer is
522-
// yes, so the impl is considered a candidate.
523-
//
524-
// Note that there is the possibility of ambiguity here, even
525-
// when all types are known. In our example, this might occur
526-
// if there was *also* an impl of `TheTrait` for `Baz`. In
527-
// this case, `Rc<Foo>` would be coercible to both `Rc<Bar>`
528-
// and `Rc<Baz>`. (Note that it is not a *coherence violation*
529-
// to have impls for both `Bar` and `Baz`, despite this
530-
// ambiguity). In this case, we report an error, listing all
531-
// the applicable impls. The user can explicitly "up-coerce"
532-
// to the type they want.
533-
//
534-
// Note that this coercion step only considers actual impls
535-
// found in the source. This is because all the
536-
// compiler-provided impls (such as those for unboxed
537-
// closures) do not have relevant coercions. This simplifies
538-
// life immensely.
539-
540-
let mut impls =
541-
self.assemble_method_candidates_from_impls(rcvr_ty, xform_self_ty, obligation);
542-
543-
if impls.len() > 1 {
544-
impls.retain(|&c| self.winnow_method_impl(c, rcvr_ty, xform_self_ty, obligation));
545-
}
546-
547-
if impls.len() > 1 {
548-
return MethodAmbiguous(impls);
549-
}
550-
551-
match impls.pop() {
552-
Some(def_id) => MethodMatched(CoerciveMethodMatch(def_id)),
553-
None => MethodDidNotMatch
554-
}
555-
}
556-
557-
/// Given the successful result of a method match, this function "confirms" the result, which
558-
/// basically repeats the various matching operations, but outside of any snapshot so that
559-
/// their effects are committed into the inference state.
560-
pub fn confirm_method_match(&mut self,
561-
rcvr_ty: Ty<'tcx>,
562-
xform_self_ty: Ty<'tcx>,
563-
obligation: &Obligation<'tcx>,
564-
data: MethodMatchedData)
565-
{
566-
let is_ok = match data {
567-
PreciseMethodMatch => {
568-
self.match_method_precise(rcvr_ty, xform_self_ty, obligation).is_ok()
569-
}
570-
571-
CoerciveMethodMatch(impl_def_id) => {
572-
self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation).is_ok()
573-
}
574-
};
575-
576-
if !is_ok {
577-
self.tcx().sess.span_bug(
578-
obligation.cause.span,
579-
format!("match not repeatable: {}, {}, {}, {}",
580-
rcvr_ty.repr(self.tcx()),
581-
xform_self_ty.repr(self.tcx()),
582-
obligation.repr(self.tcx()),
583-
data)[]);
584-
}
585-
}
586-
587-
/// Implements the *precise method match* procedure described in
588-
/// `evaluate_method_obligation()`.
589-
fn match_method_precise(&mut self,
590-
rcvr_ty: Ty<'tcx>,
591-
xform_self_ty: Ty<'tcx>,
592-
obligation: &Obligation<'tcx>)
593-
-> Result<(),()>
594-
{
595-
self.infcx.commit_if_ok(|| {
596-
match self.infcx.sub_types(false, infer::RelateSelfType(obligation.cause.span),
597-
rcvr_ty, xform_self_ty) {
598-
Ok(()) => { }
599-
Err(_) => { return Err(()); }
600-
}
601-
602-
if self.evaluate_obligation(obligation) {
603-
Ok(())
604-
} else {
605-
Err(())
606-
}
607-
})
608-
}
609-
610-
/// Assembles a list of potentially applicable impls using the *coercive match* procedure
611-
/// described in `evaluate_method_obligation()`.
612-
fn assemble_method_candidates_from_impls(&mut self,
613-
rcvr_ty: Ty<'tcx>,
614-
xform_self_ty: Ty<'tcx>,
615-
obligation: &Obligation<'tcx>)
616-
-> Vec<ast::DefId>
617-
{
618-
let mut candidates = Vec::new();
619-
620-
let all_impls = self.all_impls(obligation.trait_ref.def_id);
621-
for &impl_def_id in all_impls.iter() {
622-
self.infcx.probe(|| {
623-
match self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation) {
624-
Ok(_) => { candidates.push(impl_def_id); }
625-
Err(_) => { }
626-
}
627-
});
628-
}
629-
630-
candidates
631-
}
632-
633-
/// Applies the *coercive match* procedure described in `evaluate_method_obligation()` to a
634-
/// particular impl.
635-
fn match_method_coerce(&mut self,
636-
impl_def_id: ast::DefId,
637-
rcvr_ty: Ty<'tcx>,
638-
xform_self_ty: Ty<'tcx>,
639-
obligation: &Obligation<'tcx>)
640-
-> Result<Substs<'tcx>, ()>
641-
{
642-
// This is almost always expected to succeed. It
643-
// causes the impl's self-type etc to be unified with
644-
// the type variable that is shared between
645-
// obligation/xform_self_ty. In our example, after
646-
// this is done, the type of `xform_self_ty` would
647-
// change from `Rc<$0>` to `Rc<Foo>` (because $0 is
648-
// unified with `Foo`).
649-
let substs = try!(self.match_impl(impl_def_id, obligation));
650-
651-
// Next, check whether we can coerce. For now we require
652-
// that the coercion be a no-op.
653-
let origin = infer::Misc(obligation.cause.span);
654-
match infer::mk_coercety(self.infcx, true, origin,
655-
rcvr_ty, xform_self_ty) {
656-
Ok(None) => { /* Fallthrough */ }
657-
Ok(Some(_)) | Err(_) => { return Err(()); }
658-
}
659-
660-
Ok(substs)
661-
}
662-
663-
/// A version of `winnow_impl` applicable to coerice method matching. This is basically the
664-
/// same as `winnow_impl` but it uses the method matching procedure and is specific to impls.
665-
fn winnow_method_impl(&mut self,
666-
impl_def_id: ast::DefId,
667-
rcvr_ty: Ty<'tcx>,
668-
xform_self_ty: Ty<'tcx>,
669-
obligation: &Obligation<'tcx>)
670-
-> bool
671-
{
672-
debug!("winnow_method_impl: impl_def_id={} rcvr_ty={} xform_self_ty={} obligation={}",
673-
impl_def_id.repr(self.tcx()),
674-
rcvr_ty.repr(self.tcx()),
675-
xform_self_ty.repr(self.tcx()),
676-
obligation.repr(self.tcx()));
677-
678-
self.infcx.probe(|| {
679-
match self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation) {
680-
Ok(substs) => {
681-
let vtable_impl = self.vtable_impl(impl_def_id,
682-
substs,
683-
obligation.cause,
684-
obligation.recursion_depth + 1);
685-
self.winnow_selection(None, VtableImpl(vtable_impl)).may_apply()
686-
}
687-
Err(()) => {
688-
false
689-
}
690-
}
691-
})
692-
}
693-
694415
///////////////////////////////////////////////////////////////////////////
695416
// CANDIDATE ASSEMBLY
696417
//

0 commit comments

Comments
 (0)