commit
4f5edf9e38
2 changed files with 53 additions and 22 deletions
|
@ -92,31 +92,39 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
|
|
||||||
// Determine if the field can be used as a function in some way
|
// Determine if the field can be used as a function in some way
|
||||||
let field_ty = field.ty(cx, substs);
|
let field_ty = field.ty(cx, substs);
|
||||||
if let Ok(fn_once_trait_did) = cx.lang_items.require(FnOnceTraitLangItem) {
|
|
||||||
let infcx = fcx.infcx();
|
|
||||||
infcx.probe(|_| {
|
|
||||||
let fn_once_substs = Substs::new_trait(vec![infcx.next_ty_var()],
|
|
||||||
Vec::new(),
|
|
||||||
field_ty);
|
|
||||||
let trait_ref = ty::TraitRef::new(fn_once_trait_did,
|
|
||||||
cx.mk_substs(fn_once_substs));
|
|
||||||
let poly_trait_ref = trait_ref.to_poly_trait_ref();
|
|
||||||
let obligation = Obligation::misc(span,
|
|
||||||
fcx.body_id,
|
|
||||||
poly_trait_ref.to_predicate());
|
|
||||||
let mut selcx = SelectionContext::new(infcx);
|
|
||||||
|
|
||||||
if selcx.evaluate_obligation(&obligation) {
|
match field_ty.sty {
|
||||||
span_stored_function();
|
// Not all of these (e.g. unsafe fns) implement FnOnce
|
||||||
|
// so we look for these beforehand
|
||||||
|
ty::TyClosure(..) | ty::TyBareFn(..) => span_stored_function(),
|
||||||
|
// If it's not a simple function, look for things which implement FnOnce
|
||||||
|
_ => {
|
||||||
|
if let Ok(fn_once_trait_did) =
|
||||||
|
cx.lang_items.require(FnOnceTraitLangItem) {
|
||||||
|
let infcx = fcx.infcx();
|
||||||
|
infcx.probe(|_| {
|
||||||
|
let fn_once_substs = Substs::new_trait(vec![
|
||||||
|
infcx.next_ty_var()],
|
||||||
|
Vec::new(),
|
||||||
|
field_ty);
|
||||||
|
let trait_ref = ty::TraitRef::new(fn_once_trait_did,
|
||||||
|
cx.mk_substs(fn_once_substs));
|
||||||
|
let poly_trait_ref = trait_ref.to_poly_trait_ref();
|
||||||
|
let obligation = Obligation::misc(span,
|
||||||
|
fcx.body_id,
|
||||||
|
poly_trait_ref
|
||||||
|
.to_predicate());
|
||||||
|
let mut selcx = SelectionContext::new(infcx);
|
||||||
|
|
||||||
|
if selcx.evaluate_obligation(&obligation) {
|
||||||
|
span_stored_function();
|
||||||
|
} else {
|
||||||
|
span_did_you_mean();
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
span_did_you_mean();
|
span_did_you_mean()
|
||||||
}
|
}
|
||||||
});
|
|
||||||
} else {
|
|
||||||
match field_ty.sty {
|
|
||||||
// fallback to matching a closure or function pointer
|
|
||||||
ty::TyClosure(..) | ty::TyBareFn(..) => span_stored_function(),
|
|
||||||
_ => span_did_you_mean(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,16 @@
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
use std::boxed::FnBox;
|
use std::boxed::FnBox;
|
||||||
|
|
||||||
|
struct FuncContainer {
|
||||||
|
f1: fn(data: u8),
|
||||||
|
f2: extern "C" fn(data: u8),
|
||||||
|
f3: unsafe fn(data: u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FuncContainerOuter {
|
||||||
|
container: Box<FuncContainer>
|
||||||
|
}
|
||||||
|
|
||||||
struct Obj<F> where F: FnOnce() -> u32 {
|
struct Obj<F> where F: FnOnce() -> u32 {
|
||||||
closure: F,
|
closure: F,
|
||||||
not_closure: usize,
|
not_closure: usize,
|
||||||
|
@ -66,3 +76,16 @@ fn main() {
|
||||||
check_expression().closure();//~ ERROR no method named `closure` found
|
check_expression().closure();//~ ERROR no method named `closure` found
|
||||||
//~^ NOTE use `(check_expression().closure)(...)` if you meant to call the function stored
|
//~^ NOTE use `(check_expression().closure)(...)` if you meant to call the function stored
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FuncContainerOuter {
|
||||||
|
fn run(&self) {
|
||||||
|
unsafe {
|
||||||
|
(*self.container).f1(1); //~ ERROR no method named `f1` found
|
||||||
|
//~^ NOTE use `(*self.container.f1)(...)`
|
||||||
|
(*self.container).f2(1); //~ ERROR no method named `f2` found
|
||||||
|
//~^ NOTE use `(*self.container.f2)(...)`
|
||||||
|
(*self.container).f3(1); //~ ERROR no method named `f3` found
|
||||||
|
//~^ NOTE use `(*self.container.f3)(...)`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue