Fix coercion ICE
This commit is contained in:
parent
8057d485d4
commit
b2d0ec0eb4
3 changed files with 24 additions and 39 deletions
|
|
@ -354,25 +354,4 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
-> 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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue