diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 334ef30487ad..bd240c741331 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -354,25 +354,4 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { -> Option { self.tcx.associated_items(def_id).find(|item| item.name == item_name) } - - pub fn matches_return_type(&self, method: &ty::ImplOrTraitItem<'tcx>, - expected: ty::Ty<'tcx>) -> bool { - match *method { - ty::ImplOrTraitItem::MethodTraitItem(ref x) => { - self.can_sub_types(x.fty.sig.skip_binder().output, expected).is_ok() - } - _ => false, - } - } - - pub fn impl_or_return_item(&self, - def_id: DefId, - return_type: ty::Ty<'tcx>) - -> Option> { - self.tcx - .impl_or_trait_items(def_id) - .iter() - .map(|&did| self.tcx.impl_or_trait_item(did)) - .find(|m| self.matches_return_type(m, return_type)) - } } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 85a2fcd2ba12..e735360274e7 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -21,7 +21,8 @@ use rustc::ty::subst::{Subst, Substs}; use rustc::traits::{self, ObligationCause}; use rustc::ty::{self, Ty, ToPolyTraitRef, TraitRef, TypeFoldable}; use rustc::infer::type_variable::TypeVariableOrigin; -use rustc::util::nodemap::FxHashSet; +use rustc::util::nodemap::{FnvHashSet, FxHashSet}; +use rustc::infer::{self, InferOk, TypeOrigin}; use syntax::ast; use syntax_pos::Span; use rustc::hir; @@ -626,27 +627,27 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { Ok(()) } + pub fn matches_return_type(&self, method: &ty::ImplOrTraitItem<'tcx>, + expected: ty::Ty<'tcx>) -> bool { + match *method { + ty::ImplOrTraitItem::MethodTraitItem(ref x) => { + self.probe(|_| { + let output = self.replace_late_bound_regions_with_fresh_var( + self.span, infer::FnCall, &x.fty.sig.output()); + self.can_sub_types(output.0, expected).is_ok() + }) + } + _ => false, + } + } + fn assemble_extension_candidates_for_trait(&mut self, trait_def_id: DefId) -> Result<(), MethodError<'tcx>> { debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id); - // Check whether `trait_def_id` defines a method with suitable name: - let trait_items = self.tcx.associated_items(trait_def_id); - let maybe_item = match self.looking_for { - LookingFor::MethodName(item_name) => { - trait_items.iter() - .find(|item| item.name == item_name) - } - LookingFor::ReturnType(item_ty) => { - trait_items.iter() - .find(|item| { - self.fcx.matches_return_type(item, &item_ty) - }) - } - }; - let item = match maybe_item { + let item = match self.impl_or_trait_item(trait_def_id) { Some(i) => i, None => { return Ok(()); @@ -1351,7 +1352,11 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { self.fcx.impl_or_trait_item(def_id, name) } LookingFor::ReturnType(return_ty) => { - self.fcx.impl_or_return_item(def_id, return_ty) + self.tcx + .impl_or_trait_items(def_id) + .iter() + .map(|&did| self.tcx.impl_or_trait_item(did)) + .find(|m| self.matches_return_type(m, return_ty)) } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index dbb31b0e56cd..a176a1ddede8 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -652,7 +652,8 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "internal implementation detail", cfg_fn!(rustc_attrs))), - ("safe_suggestion", Whitelisted, Gated("safe_suggestion", + ("safe_suggestion", Whitelisted, Gated(Stability::Unstable, + "safe_suggestion", "the `#[safe_suggestion]` attribute \ is an experimental feature", cfg_fn!(safe_suggestion))),