Skip to content

Commit 15547e1

Browse files
committed
rollup merge of #18346 : aochagavia/closure-fields
2 parents cfeff3e + 2ce77b3 commit 15547e1

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/librustc/middle/typeck/check/method.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,17 +223,37 @@ pub fn report_error(fcx: &FnCtxt,
223223
{
224224
match error {
225225
NoMatch(static_sources) => {
226+
let cx = fcx.tcx();
227+
let method_ustring = method_name.user_string(cx);
228+
229+
// True if the type is a struct and contains a field with
230+
// the same name as the not-found method
231+
let is_field = match ty::get(rcvr_ty).sty {
232+
ty_struct(did, _) =>
233+
ty::lookup_struct_fields(cx, did)
234+
.iter()
235+
.any(|f| f.name.user_string(cx) == method_ustring),
236+
_ => false
237+
};
238+
226239
fcx.type_error_message(
227240
span,
228241
|actual| {
229242
format!("type `{}` does not implement any \
230243
method in scope named `{}`",
231244
actual,
232-
method_name.user_string(fcx.tcx()))
245+
method_ustring)
233246
},
234247
rcvr_ty,
235248
None);
236249

250+
// If the method has the name of a field, give a help note
251+
if is_field {
252+
cx.sess.span_note(span,
253+
format!("use `(s.{0})(...)` if you meant to call the \
254+
function stored in the `{0}` field", method_ustring).as_slice());
255+
}
256+
237257
if static_sources.len() > 0 {
238258
fcx.tcx().sess.fileline_note(
239259
span,

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
struct Obj<'a> {
12+
closure: ||: 'a -> u32
13+
}
14+
15+
fn main() {
16+
let o = Obj { closure: || 42 };
17+
o.closure(); //~ ERROR type `Obj<'_>` does not implement any method in scope named `closure`
18+
//~^ NOTE use `(s.closure)(...)` if you meant to call the function stored in the `closure` field
19+
}

0 commit comments

Comments
 (0)