Skip to content

Commit d1dcd1d

Browse files
committed
Extend suggestion support for traits and foreign items
1 parent 34cefbe commit d1dcd1d

File tree

3 files changed

+161
-17
lines changed

3 files changed

+161
-17
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3858,11 +3858,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38583858
Some(Node::Item(hir::Item {
38593859
node: ItemKind::Fn(.., body_id),
38603860
..
3861+
})) |
3862+
Some(Node::ImplItem(hir::ImplItem {
3863+
node: hir::ImplItemKind::Method(_, body_id),
3864+
..
3865+
})) |
3866+
Some(Node::TraitItem(hir::TraitItem {
3867+
node: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
3868+
..
38613869
})) => {
38623870
let body = hir.body(*body_id);
38633871
sugg_call = body.arguments.iter()
38643872
.map(|arg| match &arg.pat.node {
3865-
hir::PatKind::Binding(_, _, ident, None) => ident.to_string(),
3873+
hir::PatKind::Binding(_, _, ident, None)
3874+
if ident.name != kw::SelfLower => ident.to_string(),
38663875
_ => "_".to_string(),
38673876
}).collect::<Vec<_>>().join(", ");
38683877
}
@@ -3878,6 +3887,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38783887
_ => {}
38793888
}
38803889
}
3890+
Some(Node::ForeignItem(hir::ForeignItem {
3891+
node: hir::ForeignItemKind::Fn(_, idents, _),
3892+
..
3893+
})) |
3894+
Some(Node::TraitItem(hir::TraitItem {
3895+
node: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
3896+
..
3897+
})) => sugg_call = idents.iter()
3898+
.map(|ident| if ident.name != kw::SelfLower {
3899+
ident.to_string()
3900+
} else {
3901+
"_".to_string()
3902+
}).collect::<Vec<_>>()
3903+
.join(", "),
38813904
_ => {}
38823905
}
38833906
};

src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,18 @@ struct V();
1111

1212
trait T {
1313
fn baz(x: usize, y: usize) -> usize { x }
14-
fn bat() -> usize { 42 }
14+
fn bat(x: usize) -> usize { 42 }
15+
fn bax(x: usize) -> usize { 42 }
16+
fn bach(x: usize) -> usize;
17+
fn ban(&self) -> usize { 42 }
18+
fn bal(&self) -> usize;
19+
}
20+
21+
struct X;
22+
23+
impl T for X {
24+
fn bach(x: usize) -> usize { 42 }
25+
fn bal(&self) -> usize { 42 }
1526
}
1627

1728
fn main() {
@@ -23,4 +34,12 @@ fn main() {
2334
let _: usize = T::bat; //~ ERROR mismatched types
2435
let _: E = E::A; //~ ERROR mismatched types
2536
let _: E = E::B; //~ ERROR expected value, found struct variant `E::B`
37+
let _: usize = X::baz; //~ ERROR mismatched types
38+
let _: usize = X::bat; //~ ERROR mismatched types
39+
let _: usize = X::bax; //~ ERROR mismatched types
40+
let _: usize = X::bach; //~ ERROR mismatched types
41+
let _: usize = X::ban; //~ ERROR mismatched types
42+
let _: usize = X::bal; //~ ERROR mismatched types
43+
let _: usize = X.ban; //~ ERROR attempted to take value of method
44+
let _: usize = X.bal; //~ ERROR attempted to take value of method
2645
}

src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr

Lines changed: 117 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0423]: expected value, found struct variant `E::B`
2-
--> $DIR/fn-or-tuple-struct-without-args.rs:25:16
2+
--> $DIR/fn-or-tuple-struct-without-args.rs:36:16
33
|
44
LL | let _: E = E::B;
55
| ^^^-
@@ -8,7 +8,7 @@ LL | let _: E = E::B;
88
| did you mean `E::B { /* fields */ }`?
99

1010
error[E0308]: mismatched types
11-
--> $DIR/fn-or-tuple-struct-without-args.rs:18:20
11+
--> $DIR/fn-or-tuple-struct-without-args.rs:29:20
1212
|
1313
LL | fn foo(a: usize, b: usize) -> usize { a }
1414
| ----------------------------------- fn(usize, usize) -> usize {foo} defined here
@@ -23,7 +23,7 @@ LL | let _: usize = foo;
2323
found type `fn(usize, usize) -> usize {foo}`
2424

2525
error[E0308]: mismatched types
26-
--> $DIR/fn-or-tuple-struct-without-args.rs:19:16
26+
--> $DIR/fn-or-tuple-struct-without-args.rs:30:16
2727
|
2828
LL | struct S(usize, usize);
2929
| ----------------------- fn(usize, usize) -> S {S} defined here
@@ -38,7 +38,7 @@ LL | let _: S = S;
3838
found type `fn(usize, usize) -> S {S}`
3939

4040
error[E0308]: mismatched types
41-
--> $DIR/fn-or-tuple-struct-without-args.rs:20:20
41+
--> $DIR/fn-or-tuple-struct-without-args.rs:31:20
4242
|
4343
LL | fn bar() -> usize { 42 }
4444
| ----------------- fn() -> usize {bar} defined here
@@ -53,7 +53,7 @@ LL | let _: usize = bar;
5353
found type `fn() -> usize {bar}`
5454

5555
error[E0308]: mismatched types
56-
--> $DIR/fn-or-tuple-struct-without-args.rs:21:16
56+
--> $DIR/fn-or-tuple-struct-without-args.rs:32:16
5757
|
5858
LL | struct V();
5959
| ----------- fn() -> V {V} defined here
@@ -68,7 +68,7 @@ LL | let _: V = V;
6868
found type `fn() -> V {V}`
6969

7070
error[E0308]: mismatched types
71-
--> $DIR/fn-or-tuple-struct-without-args.rs:22:20
71+
--> $DIR/fn-or-tuple-struct-without-args.rs:33:20
7272
|
7373
LL | fn baz(x: usize, y: usize) -> usize { x }
7474
| ----------------------------------- fn(usize, usize) -> usize {<_ as T>::baz} defined here
@@ -77,28 +77,28 @@ LL | let _: usize = T::baz;
7777
| ^^^^^^
7878
| |
7979
| expected usize, found fn item
80-
| help: use parentheses to call this function: `T::baz(...)`
80+
| help: use parentheses to call this function: `T::baz(x, y)`
8181
|
8282
= note: expected type `usize`
8383
found type `fn(usize, usize) -> usize {<_ as T>::baz}`
8484

8585
error[E0308]: mismatched types
86-
--> $DIR/fn-or-tuple-struct-without-args.rs:23:20
86+
--> $DIR/fn-or-tuple-struct-without-args.rs:34:20
8787
|
88-
LL | fn bat() -> usize { 42 }
89-
| ----------------- fn() -> usize {<_ as T>::bat} defined here
88+
LL | fn bat(x: usize) -> usize { 42 }
89+
| ------------------------- fn(usize) -> usize {<_ as T>::bat} defined here
9090
...
9191
LL | let _: usize = T::bat;
9292
| ^^^^^^
9393
| |
9494
| expected usize, found fn item
95-
| help: use parentheses to call this function: `T::bat()`
95+
| help: use parentheses to call this function: `T::bat(x)`
9696
|
9797
= note: expected type `usize`
98-
found type `fn() -> usize {<_ as T>::bat}`
98+
found type `fn(usize) -> usize {<_ as T>::bat}`
9999

100100
error[E0308]: mismatched types
101-
--> $DIR/fn-or-tuple-struct-without-args.rs:24:16
101+
--> $DIR/fn-or-tuple-struct-without-args.rs:35:16
102102
|
103103
LL | A(usize),
104104
| -------- fn(usize) -> E {E::A} defined here
@@ -112,7 +112,109 @@ LL | let _: E = E::A;
112112
= note: expected type `E`
113113
found type `fn(usize) -> E {E::A}`
114114

115-
error: aborting due to 8 previous errors
115+
error[E0308]: mismatched types
116+
--> $DIR/fn-or-tuple-struct-without-args.rs:37:20
117+
|
118+
LL | fn baz(x: usize, y: usize) -> usize { x }
119+
| ----------------------------------- fn(usize, usize) -> usize {<X as T>::baz} defined here
120+
...
121+
LL | let _: usize = X::baz;
122+
| ^^^^^^
123+
| |
124+
| expected usize, found fn item
125+
| help: use parentheses to call this function: `X::baz(x, y)`
126+
|
127+
= note: expected type `usize`
128+
found type `fn(usize, usize) -> usize {<X as T>::baz}`
129+
130+
error[E0308]: mismatched types
131+
--> $DIR/fn-or-tuple-struct-without-args.rs:38:20
132+
|
133+
LL | fn bat(x: usize) -> usize { 42 }
134+
| ------------------------- fn(usize) -> usize {<X as T>::bat} defined here
135+
...
136+
LL | let _: usize = X::bat;
137+
| ^^^^^^
138+
| |
139+
| expected usize, found fn item
140+
| help: use parentheses to call this function: `X::bat(x)`
141+
|
142+
= note: expected type `usize`
143+
found type `fn(usize) -> usize {<X as T>::bat}`
144+
145+
error[E0308]: mismatched types
146+
--> $DIR/fn-or-tuple-struct-without-args.rs:39:20
147+
|
148+
LL | fn bax(x: usize) -> usize { 42 }
149+
| ------------------------- fn(usize) -> usize {<X as T>::bax} defined here
150+
...
151+
LL | let _: usize = X::bax;
152+
| ^^^^^^
153+
| |
154+
| expected usize, found fn item
155+
| help: use parentheses to call this function: `X::bax(x)`
156+
|
157+
= note: expected type `usize`
158+
found type `fn(usize) -> usize {<X as T>::bax}`
159+
160+
error[E0308]: mismatched types
161+
--> $DIR/fn-or-tuple-struct-without-args.rs:40:20
162+
|
163+
LL | fn bach(x: usize) -> usize;
164+
| --------------------------- fn(usize) -> usize {<X as T>::bach} defined here
165+
...
166+
LL | let _: usize = X::bach;
167+
| ^^^^^^^
168+
| |
169+
| expected usize, found fn item
170+
| help: use parentheses to call this function: `X::bach(x)`
171+
|
172+
= note: expected type `usize`
173+
found type `fn(usize) -> usize {<X as T>::bach}`
174+
175+
error[E0308]: mismatched types
176+
--> $DIR/fn-or-tuple-struct-without-args.rs:41:20
177+
|
178+
LL | fn ban(&self) -> usize { 42 }
179+
| ---------------------- for<'r> fn(&'r X) -> usize {<X as T>::ban} defined here
180+
...
181+
LL | let _: usize = X::ban;
182+
| ^^^^^^
183+
| |
184+
| expected usize, found fn item
185+
| help: use parentheses to call this function: `X::ban(_)`
186+
|
187+
= note: expected type `usize`
188+
found type `for<'r> fn(&'r X) -> usize {<X as T>::ban}`
189+
190+
error[E0308]: mismatched types
191+
--> $DIR/fn-or-tuple-struct-without-args.rs:42:20
192+
|
193+
LL | fn bal(&self) -> usize;
194+
| ----------------------- for<'r> fn(&'r X) -> usize {<X as T>::bal} defined here
195+
...
196+
LL | let _: usize = X::bal;
197+
| ^^^^^^
198+
| |
199+
| expected usize, found fn item
200+
| help: use parentheses to call this function: `X::bal(_)`
201+
|
202+
= note: expected type `usize`
203+
found type `for<'r> fn(&'r X) -> usize {<X as T>::bal}`
204+
205+
error[E0615]: attempted to take value of method `ban` on type `X`
206+
--> $DIR/fn-or-tuple-struct-without-args.rs:43:22
207+
|
208+
LL | let _: usize = X.ban;
209+
| ^^^ help: use parentheses to call the method: `ban()`
210+
211+
error[E0615]: attempted to take value of method `bal` on type `X`
212+
--> $DIR/fn-or-tuple-struct-without-args.rs:44:22
213+
|
214+
LL | let _: usize = X.bal;
215+
| ^^^ help: use parentheses to call the method: `bal()`
216+
217+
error: aborting due to 16 previous errors
116218

117-
Some errors have detailed explanations: E0308, E0423.
219+
Some errors have detailed explanations: E0308, E0423, E0615.
118220
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)