Skip to content

Commit a1dfd18

Browse files
committed
---
yaml --- r: 227677 b: refs/heads/try c: 9932870 h: refs/heads/master i: 227675: 53daa1b v: v3
1 parent cb4721b commit a1dfd18

File tree

4 files changed

+100
-48
lines changed

4 files changed

+100
-48
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 3f8a70b613d9e41dc6db11f1d267025bb26bf73d
4+
refs/heads/try: 9932870833a3d2c13431c0454a4a91bf54a0e5ab
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc_typeck/check/method/suggest.rs

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ use CrateCtxt;
1515

1616
use astconv::AstConv;
1717
use check::{self, FnCtxt};
18-
use middle::ty::{self, Ty};
18+
use middle::ty::{self, Ty, ToPolyTraitRef, AsPredicate};
1919
use middle::def;
20+
use middle::lang_items::FnOnceTraitLangItem;
21+
use middle::subst::Substs;
22+
use middle::traits::{Obligation, SelectionContext};
2023
use metadata::{csearch, cstore, decoder};
2124

2225
use syntax::{ast, ast_util};
@@ -65,31 +68,38 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
6568
if let Some(field) = fields.iter().find(|f| f.name == item_name) {
6669
let expr_string = match cx.sess.codemap().span_to_snippet(expr.span) {
6770
Ok(expr_string) => expr_string,
68-
_ => "s".into() // default to generic placeholder for expression
71+
_ => "s".into() // Default to a generic placeholder for the
72+
// expression when we can't generate a string
73+
// snippet
6974
};
7075

71-
// TODO Fix when closure note is displayed
72-
// below commented code from eddyb on irc
73-
// let substs = subst::Substs::new_trait(vec![fcx.inh.infcx.next_ty_var()], Vec::new(), field_ty);
74-
// let trait_ref = ty::TraitRef::new(trait_def_id, fcx.tcx().mk_substs(substs));
75-
// let poly_trait_ref = trait_ref.to_poly_trait_ref();
76-
// let obligation = traits::Obligation::misc(span, fcx.body_id, poly_trait_ref.as_predicate());
77-
// let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx);
78-
// if selcx.evaluate_obligation(&obligation) { /* suggest */ }
79-
80-
match ty::lookup_field_type(cx, did, field.id, substs).sty {
81-
ty::TyClosure(_, _) | ty::TyBareFn(_,_) => {
82-
cx.sess.span_note(span,
83-
&format!("use `({0}.{1})(...)` if you meant to call the \
84-
function stored in the `{1}` field",
85-
expr_string, item_name));
86-
},
87-
_ => {
88-
cx.sess.span_note(span,
89-
&format!("did you mean to write `{0}.{1}`?",
90-
expr_string, item_name));
91-
},
76+
// Determine if the field can be used as a function in some way
77+
let fn_once_trait_did = match cx.lang_items.require(FnOnceTraitLangItem) {
78+
Ok(trait_did) => trait_did,
79+
Err(err) => cx.sess.fatal(&err[..])
9280
};
81+
82+
let field_ty = ty::lookup_field_type(cx, did, field.id, substs);
83+
let field_ty_substs = Substs::new_trait(vec![fcx.inh.infcx.next_ty_var()],
84+
Vec::new(),
85+
field_ty);
86+
let trait_ref = ty::TraitRef::new(fn_once_trait_did,
87+
cx.mk_substs(field_ty_substs));
88+
let poly_trait_ref = trait_ref.to_poly_trait_ref();
89+
let obligation = Obligation::misc(span,
90+
fcx.body_id,
91+
poly_trait_ref.as_predicate());
92+
let mut selcx = SelectionContext::new(fcx.infcx(), fcx);
93+
94+
if selcx.evaluate_obligation(&obligation) {
95+
cx.sess.span_note(span,
96+
&format!("use `({0}.{1})(...)` if you meant to call the \
97+
function stored in the `{1}` field",
98+
expr_string, item_name));
99+
} else {
100+
cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?",
101+
expr_string, item_name));
102+
}
93103
}
94104
}
95105

branches/try/src/test/compile-fail/issue-18343.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,10 @@
1010

1111
struct Obj<F> where F: FnMut() -> u32 {
1212
closure: F,
13-
nfn: usize,
14-
}
15-
16-
struct S<F> where F: FnMut() -> u32 {
17-
v: Obj<F>,
18-
}
19-
20-
fn func() -> u32 {
21-
0
2213
}
2314

2415
fn main() {
25-
let o = Obj { closure: || 42, nfn: 42 };
16+
let o = Obj { closure: || 42 };
2617
o.closure(); //~ ERROR no method named `closure` found
2718
//~^ NOTE use `(o.closure)(...)` if you meant to call the function stored in the `closure` field
28-
29-
// TODO move these to a new test for #2392
30-
let x = o.nfn(); //~ ERROR no method named `nfn` found
31-
//~^ NOTE did you mean to write `o.nfn`?
32-
33-
let b = Obj { closure: func, nfn: 5 };
34-
b.closure(); //~ ERROR no method named `closure` found
35-
//~^ NOTE use `(b.closure)(...)` if you meant to call the function stored in the `closure` field
36-
37-
let s = S { v: b };
38-
s.v.closure();//~ ERROR no method named `closure` found
39-
//~^ NOTE use `(s.v.closure)(...)` if you meant to call the function stored in the `closure` field
40-
s.v.nfn();//~ ERROR no method named `nfn` found
41-
//~^ NOTE did you mean to write `s.v.nfn`?
4219
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(core)]
12+
use std::boxed::FnBox;
13+
14+
struct Obj<F> where F: FnOnce() -> u32 {
15+
closure: F,
16+
not_closure: usize,
17+
}
18+
19+
struct BoxedObj {
20+
boxed_closure: Box<FnBox() -> u32>,
21+
}
22+
23+
struct Wrapper<F> where F: FnMut() -> u32 {
24+
wrap: Obj<F>,
25+
}
26+
27+
fn func() -> u32 {
28+
0
29+
}
30+
31+
fn check_expression() -> Obj<Box<FnBox() -> u32>> {
32+
Obj { closure: Box::new(|| 42_u32) as Box<FnBox() -> u32>, not_closure: 42 }
33+
}
34+
35+
fn main() {
36+
// test variations of function
37+
let o_closure = Obj { closure: || 42, not_closure: 42 };
38+
o_closure.closure(); //~ ERROR no method named `closure` found
39+
//~^ NOTE use `(o_closure.closure)(...)` if you meant to call the function stored in the `closure` field
40+
41+
o_closure.not_closure(); //~ ERROR no method named `not_closure` found
42+
//~^ NOTE did you mean to write `o_closure.not_closure`?
43+
44+
let o_func = Obj { closure: func, not_closure: 5 };
45+
o_func.closure(); //~ ERROR no method named `closure` found
46+
//~^ NOTE use `(o_func.closure)(...)` if you meant to call the function stored in the `closure` field
47+
48+
let boxed_fn = BoxedObj { boxed_closure: Box::new(func) };
49+
boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found
50+
//~^ NOTE use `(boxed_fn.boxed_closure)(...)` if you meant to call the function stored in the `boxed_closure` field
51+
52+
let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box<FnBox() -> u32> };
53+
boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found
54+
//~^ NOTE use `(boxed_closure.boxed_closure)(...)` if you meant to call the function stored in the `boxed_closure` field
55+
56+
// test expression writing in the notes
57+
let w = Wrapper { wrap: o_func };
58+
w.wrap.closure();//~ ERROR no method named `closure` found
59+
//~^ NOTE use `(w.wrap.closure)(...)` if you meant to call the function stored in the `closure` field
60+
w.wrap.not_closure();//~ ERROR no method named `not_closure` found
61+
//~^ NOTE did you mean to write `w.wrap.not_closure`?
62+
63+
check_expression().closure();//~ ERROR no method named `closure` found
64+
//~^ NOTE use `(check_expression().closure)(...)` if you meant to call the function stored in the `closure` field
65+
}

0 commit comments

Comments
 (0)