Fix coercion ICE

This commit is contained in:
Guillaume Gomez 2016-10-28 01:04:16 +02:00
parent 8057d485d4
commit b2d0ec0eb4
3 changed files with 24 additions and 39 deletions

View File

@ -354,25 +354,4 @@ pub fn associated_item(&self, def_id: DefId, item_name: ast::Name)
-> Option<ty::AssociatedItem> {
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<ty::ImplOrTraitItem<'tcx>> {
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))
}
}

View File

@ -21,7 +21,8 @@
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 @@ fn assemble_extension_candidates_for_all_traits(&mut self) -> Result<(), MethodE
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 @@ fn impl_or_trait_item(&self, def_id: DefId) -> Option<ty::ImplOrTraitItem<'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))
}
}
}

View File

@ -652,7 +652,8 @@ pub fn deprecated_attributes() -> Vec<&'static (&'static str, AttributeType, Att
"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))),