]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/method/probe.rs
rustc: use DefKind instead of Def, where possible.
[rust.git] / src / librustc_typeck / check / method / probe.rs
index 40dd62173359474308ba30429af5a302434ce1f2..8c61a127d1014cbca72211e373140e777e8c3db5 100644 (file)
@@ -6,7 +6,7 @@
 use crate::check::autoderef::{self, Autoderef};
 use crate::check::FnCtxt;
 use crate::hir::def_id::DefId;
-use crate::hir::def::Def;
+use crate::hir::def::DefKind;
 use crate::namespace::Namespace;
 
 use rustc_data_structures::sync::Lrc;
@@ -21,6 +21,7 @@
 use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TraitRef, TypeFoldable};
 use rustc::ty::GenericParamDefKind;
 use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::unify_key::ConstVariableOrigin;
 use rustc::util::nodemap::FxHashSet;
 use rustc::infer::{self, InferOk};
 use rustc::infer::canonical::{Canonical, QueryResponse};
@@ -67,7 +68,7 @@ struct ProbeContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     allow_similar_names: bool,
 
     /// Some(candidate) if there is a private candidate
-    private_candidate: Option<Def>,
+    private_candidate: Option<(DefKind, DefId)>,
 
     /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
     /// for error reporting
@@ -519,7 +520,8 @@ fn push_candidate(&mut self,
                 self.extension_candidates.push(candidate);
             }
         } else if self.private_candidate.is_none() {
-            self.private_candidate = Some(candidate.item.def());
+            self.private_candidate =
+                Some((candidate.item.def_kind(), candidate.item.def_id));
         }
     }
 
@@ -860,9 +862,9 @@ pub fn matches_return_type(&self,
                                method: &ty::AssociatedItem,
                                self_ty: Option<Ty<'tcx>>,
                                expected: Ty<'tcx>) -> bool {
-        match method.def() {
-            Def::Method(def_id) => {
-                let fty = self.tcx.fn_sig(def_id);
+        match method.kind {
+            ty::AssociatedKind::Method => {
+                let fty = self.tcx.fn_sig(method.def_id);
                 self.probe(|_| {
                     let substs = self.fresh_substs_for_item(self.span, method.def_id);
                     let fty = fty.subst(self.tcx, substs);
@@ -896,20 +898,36 @@ fn assemble_extension_candidates_for_trait(&mut self,
         let trait_substs = self.fresh_item_substs(trait_def_id);
         let trait_ref = ty::TraitRef::new(trait_def_id, trait_substs);
 
-        for item in self.impl_or_trait_item(trait_def_id) {
-            // Check whether `trait_def_id` defines a method with suitable name:
-            if !self.has_applicable_self(&item) {
-                debug!("method has inapplicable self");
-                self.record_static_candidate(TraitSource(trait_def_id));
-                continue;
-            }
+        if self.tcx.is_trait_alias(trait_def_id) {
+            // For trait aliases, assume all super-traits are relevant.
+            let bounds = iter::once(trait_ref.to_poly_trait_ref());
+            self.elaborate_bounds(bounds, |this, new_trait_ref, item| {
+                let new_trait_ref = this.erase_late_bound_regions(&new_trait_ref);
+
+                let (xform_self_ty, xform_ret_ty) =
+                    this.xform_self_ty(&item, new_trait_ref.self_ty(), new_trait_ref.substs);
+                this.push_candidate(Candidate {
+                    xform_self_ty, xform_ret_ty, item, import_id,
+                    kind: TraitCandidate(new_trait_ref),
+                }, true);
+            });
+        } else {
+            debug_assert!(self.tcx.is_trait(trait_def_id));
+            for item in self.impl_or_trait_item(trait_def_id) {
+                // Check whether `trait_def_id` defines a method with suitable name.
+                if !self.has_applicable_self(&item) {
+                    debug!("method has inapplicable self");
+                    self.record_static_candidate(TraitSource(trait_def_id));
+                    continue;
+                }
 
-            let (xform_self_ty, xform_ret_ty) =
-                self.xform_self_ty(&item, trait_ref.self_ty(), trait_substs);
-            self.push_candidate(Candidate {
-                xform_self_ty, xform_ret_ty, item, import_id,
-                kind: TraitCandidate(trait_ref),
-            }, false);
+                let (xform_self_ty, xform_ret_ty) =
+                    self.xform_self_ty(&item, trait_ref.self_ty(), trait_substs);
+                self.push_candidate(Candidate {
+                    xform_self_ty, xform_ret_ty, item, import_id,
+                    kind: TraitCandidate(trait_ref),
+                }, false);
+            }
         }
         Ok(())
     }
@@ -930,7 +948,7 @@ fn candidate_method_names(&self) -> Vec<ast::Ident> {
             .filter(|&name| set.insert(name))
             .collect();
 
-        // sort them by the name so we have a stable result
+        // Sort them by the name so we have a stable result.
         names.sort_by_cached_key(|n| n.as_str());
         names
     }
@@ -945,6 +963,8 @@ fn pick(mut self) -> PickResult<'tcx> {
             return r;
         }
 
+        debug!("pick: actual search failed, assemble diagnotics");
+
         let static_candidates = mem::replace(&mut self.static_candidates, vec![]);
         let private_candidate = self.private_candidate.take();
         let unsatisfied_predicates = mem::replace(&mut self.unsatisfied_predicates, vec![]);
@@ -985,8 +1005,8 @@ fn pick(mut self) -> PickResult<'tcx> {
             _ => vec![],
         };
 
-        if let Some(def) = private_candidate {
-            return Err(MethodError::PrivateMatch(def, out_of_scope_traits));
+        if let Some((kind, def_id)) = private_candidate {
+            return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits));
         }
         let lev_candidate = self.probe_for_lev_candidate()?;
 
@@ -1061,7 +1081,7 @@ fn pick_autorefd_method(&mut self,
 
         // In general, during probing we erase regions. See
         // `impl_self_ty()` for an explanation.
-        let region = tcx.types.re_erased;
+        let region = tcx.lifetimes.re_erased;
 
         let autoref_ty = tcx.mk_ref(region,
                                     ty::TypeAndMut {
@@ -1527,7 +1547,7 @@ fn xform_method_sig(&self,
                         GenericParamDefKind::Lifetime => {
                             // In general, during probe we erase regions. See
                             // `impl_self_ty()` for an explanation.
-                            self.tcx.types.re_erased.into()
+                            self.tcx.lifetimes.re_erased.into()
                         }
                         GenericParamDefKind::Type { .. }
                         | GenericParamDefKind::Const => {
@@ -1548,13 +1568,15 @@ fn impl_ty_and_substs(&self, impl_def_id: DefId) -> (Ty<'tcx>, SubstsRef<'tcx>)
     fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx> {
         InternalSubsts::for_item(self.tcx, def_id, |param, _| {
             match param.kind {
-                GenericParamDefKind::Lifetime => self.tcx.types.re_erased.into(),
+                GenericParamDefKind::Lifetime => self.tcx.lifetimes.re_erased.into(),
                 GenericParamDefKind::Type { .. } => {
                     self.next_ty_var(TypeVariableOrigin::SubstitutionPlaceholder(
                         self.tcx.def_span(def_id))).into()
                 }
                 GenericParamDefKind::Const { .. } => {
-                    unimplemented!() // FIXME(const_generics)
+                    let span = self.tcx.def_span(def_id);
+                    let origin = ConstVariableOrigin::SubstitutionPlaceholder(span);
+                    self.next_const_var(self.tcx.type_of(param.def_id), origin).into()
                 }
             }
         })