diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index cbd1345a57e..1961a6247ed 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -285,15 +285,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(steps) } - - pub fn find_attr(&self, def_id: DefId, attr_name: &str) -> Option { - for item in self.tcx.get_attrs(def_id).iter() { - if item.check_name(attr_name) { - return Some(item.clone()); - } - } - None - } } impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { @@ -918,21 +909,21 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { //Some(Ok(p)) => p.iter().map(|p| p.item.container().id()).collect(), Some(Err(MethodError::Ambiguity(v))) => { v.into_iter() - .map(|source| { - match source { - TraitSource(id) => id, - ImplSource(impl_id) => { - match tcx.trait_id_of_impl(impl_id) { - Some(id) => id, - None => { - span_bug!(span, - "found inherent method when looking at traits") - } + .map(|source| { + match source { + TraitSource(id) => id, + ImplSource(impl_id) => { + match tcx.trait_id_of_impl(impl_id) { + Some(id) => id, + None => { + span_bug!(span, + "found inherent method when looking at traits") } } } - }) - .collect() + } + }) + .collect() } Some(Err(MethodError::NoMatch(NoMatchData { out_of_scope_traits: others, .. }))) => { assert!(others.is_empty()); @@ -957,25 +948,27 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn pick_core(&mut self) -> Option> { let steps = self.steps.clone(); - let mut ret = Vec::new(); - for step in steps.iter() { - match self.pick_step(step) { - Some(Ok(mut elems)) => ret.append(&mut elems), - Some(Err(elem)) => { - match self.looking_for { - LookingFor::MethodName(_) => return Some(Err(elem)), - LookingFor::ReturnType(_) => {} + match self.looking_for { + LookingFor::MethodName(_) => steps.iter() + .filter_map(|step| self.pick_step(step)) + .next(), + LookingFor::ReturnType(_) => { + let mut ret = Vec::new(); + + for step in steps.iter() { + match self.pick_step(step) { + Some(Ok(mut elems)) => ret.append(&mut elems), + _ => {} } } - _ => {} + if ret.len() < 1 { + None + } else { + Some(Ok(ret)) + } } } - if ret.len() < 1 { - None - } else { - Some(Ok(ret)) - } } fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option> { @@ -1028,12 +1021,12 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // In general, during probing we erase regions. See // `impl_self_ty()` for an explanation. let region = tcx.mk_region(ty::ReErased); - let mut res = Vec::new(); // Search through mutabilities in order to find one where pick works: - for _ in [hir::MutImmutable, hir::MutMutable] - .iter() - .filter_map(|&m| { + let mut elements = [hir::MutImmutable, hir::MutMutable]; + let mut it = elements + .iter_mut() + .filter_map(|&mut m| { let autoref_ty = tcx.mk_ref(region, ty::TypeAndMut { ty: step.self_ty, @@ -1050,15 +1043,24 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { None }; } - res.append(&mut picks); + picks }) }) - }) {} + }); + match self.looking_for { + LookingFor::MethodName(_) => it.nth(0), + LookingFor::ReturnType(_) => { + let mut ret = Vec::new(); + it.filter_map(|entry| entry.ok()) + .map(|mut v| { ret.append(&mut v); }) + .all(|_| true); - if res.len() < 1 { - None - } else { - Some(Ok(res)) + if ret.len() < 1 { + None + } else { + Some(Ok(ret)) + } + } } } @@ -1089,7 +1091,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { probes: &[Candidate<'tcx>], possibly_unsatisfied_predicates: &mut Vec>) -> Option> { - let applicable_candidates: Vec<_> = probes.iter() + let mut applicable_candidates: Vec<_> = probes.iter() .filter(|&probe| self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates)) .collect(); @@ -1109,14 +1111,21 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { return Some(Err(MethodError::Ambiguity(sources))); } - let ret: Vec<_> = applicable_candidates.iter() - .map(|probe| probe.to_unadjusted_pick()) - .collect(); + match self.looking_for { + LookingFor::MethodName(_) => applicable_candidates + .pop() + .map(|probe| Ok(vec![probe.to_unadjusted_pick()])), + LookingFor::ReturnType(_) => { + let ret: Vec<_> = applicable_candidates.iter() + .map(|probe| probe.to_unadjusted_pick()) + .collect(); - if ret.len() < 1 { - None - } else { - Some(Ok(ret)) + if ret.len() < 1 { + None + } else { + Some(Ok(ret)) + } + } } } diff --git a/src/test/compile-fail/coerce_suggestions.rs b/src/test/compile-fail/coerce_suggestions.rs index decd589e6f4..3177e858ff4 100644 --- a/src/test/compile-fail/coerce_suggestions.rs +++ b/src/test/compile-fail/coerce_suggestions.rs @@ -8,34 +8,40 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(box_syntax)] + fn test(_x: &mut String) {} fn test2(_x: &mut i32) {} fn main() { let x: usize = String::new(); - //^ ERROR E0308 - //| NOTE expected type `usize` - //| NOTE found type `std::string::String` - //| NOTE here are some functions which might fulfill your needs: + //~^ ERROR E0308 + //~| NOTE expected usize, found struct `std::string::String` + //~| NOTE expected type `usize` + //~| NOTE found type `std::string::String` + //~| HELP here are some functions which might fulfill your needs: let x: &str = String::new(); - //^ ERROR E0308 - //| NOTE expected type `&str` - //| NOTE found type `std::string::String` - //| NOTE try with `&String::new()` + //~^ ERROR E0308 + //~| NOTE expected &str, found struct `std::string::String` + //~| NOTE expected type `&str` + //~| NOTE found type `std::string::String` + //~| HELP try with `&String::new()` let y = String::new(); test(&y); - //^ ERROR E0308 - //| NOTE expected type `&mut std::string::String` - //| NOTE found type `&std::string::String` - //| NOTE try with `&mut y` + //~^ ERROR E0308 + //~| NOTE types differ in mutability + //~| NOTE expected type `&mut std::string::String` + //~| NOTE found type `&std::string::String` + //~| HELP try with `&mut y` test2(&y); - //^ ERROR E0308 - //| NOTE expected type `&mut i32` - //| NOTE found type `&std::string::String` - //| NOTE try with `&mut y` + //~^ ERROR E0308 + //~| NOTE types differ in mutability + //~| NOTE expected type `&mut i32` + //~| NOTE found type `&std::string::String` let f; f = box f; - //^ ERROR E0308 - //| NOTE expected type `_` - //| NOTE found type `Box<_>` + //~^ ERROR E0308 + //~| NOTE cyclic type of infinite size + //~| NOTE expected type `_` + //~| NOTE found type `Box<_>` } diff --git a/src/test/compile-fail/coercion-slice.rs b/src/test/compile-fail/coercion-slice.rs index 6b468ff9662..f5090088399 100644 --- a/src/test/compile-fail/coercion-slice.rs +++ b/src/test/compile-fail/coercion-slice.rs @@ -14,6 +14,6 @@ fn main() { let _: &[i32] = [0]; //~^ ERROR mismatched types //~| expected type `&[i32]` - //~| found type `[{integer}; 1]` + //~| found type `[i32; 1]` //~| expected &[i32], found array of 1 elements } diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs index 672ff464718..975bc1300aa 100644 --- a/src/test/compile-fail/cross-borrow-trait.rs +++ b/src/test/compile-fail/cross-borrow-trait.rs @@ -22,4 +22,5 @@ pub fn main() { //~| expected type `&Trait` //~| found type `Box` //~| expected &Trait, found box + //~^^^^ ERROR E0277 } diff --git a/src/test/compile-fail/dst-bad-coercions.rs b/src/test/compile-fail/dst-bad-coercions.rs index 883c16b0895..728b016b30f 100644 --- a/src/test/compile-fail/dst-bad-coercions.rs +++ b/src/test/compile-fail/dst-bad-coercions.rs @@ -23,11 +23,13 @@ pub fn main() { let x: *const S = &S; let y: &S = x; //~ ERROR mismatched types let y: &T = x; //~ ERROR mismatched types + //~^ ERROR E0277 // Test that we cannot convert from *-ptr to &S and &T (mut version) let x: *mut S = &mut S; let y: &S = x; //~ ERROR mismatched types let y: &T = x; //~ ERROR mismatched types + //~^ ERROR E0277 // Test that we cannot convert an immutable ptr to a mutable one using *-ptrs let x: &mut T = &S; //~ ERROR mismatched types diff --git a/src/test/compile-fail/issue-13058.rs b/src/test/compile-fail/issue-13058.rs index de578257e46..df6675510ff 100644 --- a/src/test/compile-fail/issue-13058.rs +++ b/src/test/compile-fail/issue-13058.rs @@ -36,4 +36,5 @@ fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool fn main() { check((3, 5)); //~^ ERROR mismatched types +//~| HELP try with `&(3, 5)` }