]> git.proxmox.com Git - rustc.git/blobdiff - src/librustc_typeck/check/method/probe.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc_typeck / check / method / probe.rs
index 3cf182a0d8ff6ba941c45e0acc440ba804c07b23..0ffbbfea84ef0c5c946e18ce335bf3b26212926e 100644 (file)
@@ -15,16 +15,16 @@ use super::suggest;
 
 use check;
 use check::{FnCtxt, UnresolvedTypeAction};
-use middle::def_id::DefId;
-use middle::subst;
-use middle::subst::Subst;
-use middle::traits;
-use middle::ty::{self, NoPreference, Ty, ToPolyTraitRef, TraitRef, TypeFoldable};
-use middle::infer;
-use middle::infer::{InferCtxt, TypeOrigin};
+use hir::def_id::DefId;
+use hir::def::Def;
+use rustc::ty::subst;
+use rustc::ty::subst::Subst;
+use rustc::traits;
+use rustc::ty::{self, NoPreference, Ty, TyCtxt, ToPolyTraitRef, TraitRef, TypeFoldable};
+use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin};
 use syntax::ast;
 use syntax::codemap::{Span, DUMMY_SP};
-use rustc_front::hir;
+use rustc::hir;
 use std::collections::HashSet;
 use std::mem;
 use std::rc::Rc;
@@ -47,6 +47,9 @@ struct ProbeContext<'a, 'tcx:'a> {
     /// used for error reporting
     static_candidates: Vec<CandidateSource>,
 
+    /// Some(candidate) if there is a private candidate
+    private_candidate: Option<Def>,
+
     /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
     /// for error reporting
     unsatisfied_predicates: Vec<TraitRef<'tcx>>
@@ -186,7 +189,7 @@ pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                              steps,
                                              opt_simplified_steps);
         probe_cx.assemble_inherent_candidates();
-        try!(probe_cx.assemble_extension_candidates_for_traits_in_scope(scope_expr_id));
+        probe_cx.assemble_extension_candidates_for_traits_in_scope(scope_expr_id)?;
         probe_cx.pick()
     })
 }
@@ -200,7 +203,7 @@ fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     let (final_ty, dereferences, _) = check::autoderef(fcx,
                                                        span,
                                                        self_ty,
-                                                       None,
+                                                       || None,
                                                        UnresolvedTypeAction::Error,
                                                        NoPreference,
                                                        |t, d| {
@@ -247,6 +250,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             steps: Rc::new(steps),
             opt_simplified_steps: opt_simplified_steps,
             static_candidates: Vec::new(),
+            private_candidate: None,
             unsatisfied_predicates: Vec::new(),
         }
     }
@@ -256,9 +260,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         self.extension_candidates.clear();
         self.impl_dups.clear();
         self.static_candidates.clear();
+        self.private_candidate = None;
     }
 
-    fn tcx(&self) -> &'a ty::ctxt<'tcx> {
+    fn tcx(&self) -> &'a TyCtxt<'tcx> {
         self.fcx.tcx()
     }
 
@@ -407,6 +412,11 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             return self.record_static_candidate(ImplSource(impl_def_id));
         }
 
+        if !item.vis().is_accessible_from(self.fcx.body_id, &self.tcx().map) {
+            self.private_candidate = Some(item.def());
+            return
+        }
+
         let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
         let impl_ty = impl_ty.subst(self.tcx(), &impl_substs);
 
@@ -505,11 +515,11 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                 assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
                            trait_ref.substs.types.get_slice(subst::TypeSpace).len());
                 assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
-                           trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
+                           trait_ref.substs.regions.get_slice(subst::TypeSpace).len());
                 assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
                            trait_ref.substs.types.get_slice(subst::SelfSpace).len());
                 assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
-                           trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
+                           trait_ref.substs.regions.get_slice(subst::SelfSpace).len());
             }
 
             // Because this trait derives from a where-clause, it
@@ -568,7 +578,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         if let Some(applicable_traits) = opt_applicable_traits {
             for &trait_did in applicable_traits {
                 if duplicates.insert(trait_did) {
-                    try!(self.assemble_extension_candidates_for_trait(trait_did));
+                    self.assemble_extension_candidates_for_trait(trait_did)?;
                 }
             }
         }
@@ -579,7 +589,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         let mut duplicates = HashSet::new();
         for trait_info in suggest::all_traits(self.fcx.ccx) {
             if duplicates.insert(trait_info.def_id) {
-                try!(self.assemble_extension_candidates_for_trait(trait_info.def_id));
+                self.assemble_extension_candidates_for_trait(trait_info.def_id)?;
             }
         }
         Ok(())
@@ -612,7 +622,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
 
         self.assemble_extension_candidates_for_trait_impls(trait_def_id, item.clone());
 
-        try!(self.assemble_closure_candidates(trait_def_id, item.clone()));
+        self.assemble_closure_candidates(trait_def_id, item.clone())?;
 
         self.assemble_projection_candidates(trait_def_id, item.clone());
 
@@ -697,11 +707,11 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         // Check if this is one of the Fn,FnMut,FnOnce traits.
         let tcx = self.tcx();
         let kind = if Some(trait_def_id) == tcx.lang_items.fn_trait() {
-            ty::FnClosureKind
+            ty::ClosureKind::Fn
         } else if Some(trait_def_id) == tcx.lang_items.fn_mut_trait() {
-            ty::FnMutClosureKind
+            ty::ClosureKind::FnMut
         } else if Some(trait_def_id) == tcx.lang_items.fn_once_trait() {
-            ty::FnOnceClosureKind
+            ty::ClosureKind::FnOnce
         } else {
             return Ok(());
         };
@@ -846,6 +856,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         }
 
         let static_candidates = mem::replace(&mut self.static_candidates, vec![]);
+        let private_candidate = mem::replace(&mut self.private_candidate, None);
         let unsatisfied_predicates = mem::replace(&mut self.unsatisfied_predicates, vec![]);
 
         // things failed, so lets look at all traits, for diagnostic purposes now:
@@ -854,7 +865,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         let span = self.span;
         let tcx = self.tcx();
 
-        try!(self.assemble_extension_candidates_for_all_traits());
+        self.assemble_extension_candidates_for_all_traits()?;
 
         let out_of_scope_traits = match self.pick_core() {
             Some(Ok(p)) => vec![p.item.container().id()],
@@ -865,8 +876,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                         match tcx.trait_id_of_impl(impl_id) {
                             Some(id) => id,
                             None =>
-                                tcx.sess.span_bug(span,
-                                                  "found inherent method when looking at traits")
+                                span_bug!(span,
+                                          "found inherent method when looking at traits")
                         }
                     }
                 }
@@ -877,11 +888,15 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             }
             Some(Err(MethodError::ClosureAmbiguity(..))) => {
                 // this error only occurs when assembling candidates
-                tcx.sess.span_bug(span, "encountered ClosureAmbiguity from pick_core");
+                span_bug!(span, "encountered ClosureAmbiguity from pick_core");
             }
-            None => vec![],
+            _ => vec![],
         };
 
+        if let Some(def) = private_candidate {
+            return Err(MethodError::PrivateMatch(def));
+        }
+
         Err(MethodError::NoMatch(NoMatchData::new(static_candidates, unsatisfied_predicates,
                                                   out_of_scope_traits, self.mode)))
     }
@@ -1135,6 +1150,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
 
     fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> infer::UnitResult<'tcx> {
         self.infcx().sub_types(false, TypeOrigin::Misc(DUMMY_SP), sub, sup)
+            // FIXME(#32730) propagate obligations
+            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
     }
 
     fn has_applicable_self(&self, item: &ty::ImplOrTraitItem) -> bool {
@@ -1194,7 +1211,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         // method yet. So create fresh variables here for those too,
         // if there are any.
         assert_eq!(substs.types.len(subst::FnSpace), 0);
-        assert_eq!(substs.regions().len(subst::FnSpace), 0);
+        assert_eq!(substs.regions.len(subst::FnSpace), 0);
 
         if self.mode == Mode::Path {
             return impl_ty;
@@ -1278,7 +1295,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     }
 }
 
-fn impl_item<'tcx>(tcx: &ty::ctxt<'tcx>,
+fn impl_item<'tcx>(tcx: &TyCtxt<'tcx>,
                    impl_def_id: DefId,
                    item_name: ast::Name)
                    -> Option<ty::ImplOrTraitItem<'tcx>>
@@ -1293,7 +1310,7 @@ fn impl_item<'tcx>(tcx: &ty::ctxt<'tcx>,
 
 /// Find item with name `item_name` defined in `trait_def_id`
 /// and return it, or `None`, if no such item.
-fn trait_item<'tcx>(tcx: &ty::ctxt<'tcx>,
+fn trait_item<'tcx>(tcx: &TyCtxt<'tcx>,
                     trait_def_id: DefId,
                     item_name: ast::Name)
                     -> Option<ty::ImplOrTraitItem<'tcx>>