From 5a54945b6f637eadd4848874db39b49d2764839f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Aug 2019 15:53:32 -0700 Subject: [PATCH] Extend suggestion support for traits and foreign items --- src/librustc_typeck/check/mod.rs | 25 +++- .../fn-or-tuple-struct-without-args.rs | 21 ++- .../fn-or-tuple-struct-without-args.stderr | 132 ++++++++++++++++-- 3 files changed, 161 insertions(+), 17 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 629b8da355e2..d389563aea63 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3858,11 +3858,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(Node::Item(hir::Item { node: ItemKind::Fn(.., body_id), .. + })) | + Some(Node::ImplItem(hir::ImplItem { + node: hir::ImplItemKind::Method(_, body_id), + .. + })) | + Some(Node::TraitItem(hir::TraitItem { + node: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)), + .. })) => { let body = hir.body(*body_id); sugg_call = body.arguments.iter() .map(|arg| match &arg.pat.node { - hir::PatKind::Binding(_, _, ident, None) => ident.to_string(), + hir::PatKind::Binding(_, _, ident, None) + if ident.name != kw::SelfLower => ident.to_string(), _ => "_".to_string(), }).collect::>().join(", "); } @@ -3878,6 +3887,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => {} } } + Some(Node::ForeignItem(hir::ForeignItem { + node: hir::ForeignItemKind::Fn(_, idents, _), + .. + })) | + Some(Node::TraitItem(hir::TraitItem { + node: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)), + .. + })) => sugg_call = idents.iter() + .map(|ident| if ident.name != kw::SelfLower { + ident.to_string() + } else { + "_".to_string() + }).collect::>() + .join(", "), _ => {} } }; diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs index 838ef78e4fd6..9b6b10748172 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs @@ -11,7 +11,18 @@ struct V(); trait T { fn baz(x: usize, y: usize) -> usize { x } - fn bat() -> usize { 42 } + fn bat(x: usize) -> usize { 42 } + fn bax(x: usize) -> usize { 42 } + fn bach(x: usize) -> usize; + fn ban(&self) -> usize { 42 } + fn bal(&self) -> usize; +} + +struct X; + +impl T for X { + fn bach(x: usize) -> usize { 42 } + fn bal(&self) -> usize { 42 } } fn main() { @@ -23,4 +34,12 @@ fn main() { let _: usize = T::bat; //~ ERROR mismatched types let _: E = E::A; //~ ERROR mismatched types let _: E = E::B; //~ ERROR expected value, found struct variant `E::B` + let _: usize = X::baz; //~ ERROR mismatched types + let _: usize = X::bat; //~ ERROR mismatched types + let _: usize = X::bax; //~ ERROR mismatched types + let _: usize = X::bach; //~ ERROR mismatched types + let _: usize = X::ban; //~ ERROR mismatched types + let _: usize = X::bal; //~ ERROR mismatched types + let _: usize = X.ban; //~ ERROR attempted to take value of method + let _: usize = X.bal; //~ ERROR attempted to take value of method } diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr index cb128822fcce..e3012144513f 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -1,5 +1,5 @@ error[E0423]: expected value, found struct variant `E::B` - --> $DIR/fn-or-tuple-struct-without-args.rs:25:16 + --> $DIR/fn-or-tuple-struct-without-args.rs:36:16 | LL | let _: E = E::B; | ^^^- @@ -8,7 +8,7 @@ LL | let _: E = E::B; | did you mean `E::B { /* fields */ }`? error[E0308]: mismatched types - --> $DIR/fn-or-tuple-struct-without-args.rs:18:20 + --> $DIR/fn-or-tuple-struct-without-args.rs:29:20 | LL | fn foo(a: usize, b: usize) -> usize { a } | ----------------------------------- fn(usize, usize) -> usize {foo} defined here @@ -23,7 +23,7 @@ LL | let _: usize = foo; found type `fn(usize, usize) -> usize {foo}` error[E0308]: mismatched types - --> $DIR/fn-or-tuple-struct-without-args.rs:19:16 + --> $DIR/fn-or-tuple-struct-without-args.rs:30:16 | LL | struct S(usize, usize); | ----------------------- fn(usize, usize) -> S {S} defined here @@ -38,7 +38,7 @@ LL | let _: S = S; found type `fn(usize, usize) -> S {S}` error[E0308]: mismatched types - --> $DIR/fn-or-tuple-struct-without-args.rs:20:20 + --> $DIR/fn-or-tuple-struct-without-args.rs:31:20 | LL | fn bar() -> usize { 42 } | ----------------- fn() -> usize {bar} defined here @@ -53,7 +53,7 @@ LL | let _: usize = bar; found type `fn() -> usize {bar}` error[E0308]: mismatched types - --> $DIR/fn-or-tuple-struct-without-args.rs:21:16 + --> $DIR/fn-or-tuple-struct-without-args.rs:32:16 | LL | struct V(); | ----------- fn() -> V {V} defined here @@ -68,7 +68,7 @@ LL | let _: V = V; found type `fn() -> V {V}` error[E0308]: mismatched types - --> $DIR/fn-or-tuple-struct-without-args.rs:22:20 + --> $DIR/fn-or-tuple-struct-without-args.rs:33:20 | LL | fn baz(x: usize, y: usize) -> usize { x } | ----------------------------------- fn(usize, usize) -> usize {<_ as T>::baz} defined here @@ -77,28 +77,28 @@ LL | let _: usize = T::baz; | ^^^^^^ | | | expected usize, found fn item - | help: use parentheses to call this function: `T::baz(...)` + | help: use parentheses to call this function: `T::baz(x, y)` | = note: expected type `usize` found type `fn(usize, usize) -> usize {<_ as T>::baz}` error[E0308]: mismatched types - --> $DIR/fn-or-tuple-struct-without-args.rs:23:20 + --> $DIR/fn-or-tuple-struct-without-args.rs:34:20 | -LL | fn bat() -> usize { 42 } - | ----------------- fn() -> usize {<_ as T>::bat} defined here +LL | fn bat(x: usize) -> usize { 42 } + | ------------------------- fn(usize) -> usize {<_ as T>::bat} defined here ... LL | let _: usize = T::bat; | ^^^^^^ | | | expected usize, found fn item - | help: use parentheses to call this function: `T::bat()` + | help: use parentheses to call this function: `T::bat(x)` | = note: expected type `usize` - found type `fn() -> usize {<_ as T>::bat}` + found type `fn(usize) -> usize {<_ as T>::bat}` error[E0308]: mismatched types - --> $DIR/fn-or-tuple-struct-without-args.rs:24:16 + --> $DIR/fn-or-tuple-struct-without-args.rs:35:16 | LL | A(usize), | -------- fn(usize) -> E {E::A} defined here @@ -112,7 +112,109 @@ LL | let _: E = E::A; = note: expected type `E` found type `fn(usize) -> E {E::A}` -error: aborting due to 8 previous errors +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:37:20 + | +LL | fn baz(x: usize, y: usize) -> usize { x } + | ----------------------------------- fn(usize, usize) -> usize {::baz} defined here +... +LL | let _: usize = X::baz; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::baz(x, y)` + | + = note: expected type `usize` + found type `fn(usize, usize) -> usize {::baz}` -Some errors have detailed explanations: E0308, E0423. +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:38:20 + | +LL | fn bat(x: usize) -> usize { 42 } + | ------------------------- fn(usize) -> usize {::bat} defined here +... +LL | let _: usize = X::bat; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::bat(x)` + | + = note: expected type `usize` + found type `fn(usize) -> usize {::bat}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:39:20 + | +LL | fn bax(x: usize) -> usize { 42 } + | ------------------------- fn(usize) -> usize {::bax} defined here +... +LL | let _: usize = X::bax; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::bax(x)` + | + = note: expected type `usize` + found type `fn(usize) -> usize {::bax}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:40:20 + | +LL | fn bach(x: usize) -> usize; + | --------------------------- fn(usize) -> usize {::bach} defined here +... +LL | let _: usize = X::bach; + | ^^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::bach(x)` + | + = note: expected type `usize` + found type `fn(usize) -> usize {::bach}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:41:20 + | +LL | fn ban(&self) -> usize { 42 } + | ---------------------- for<'r> fn(&'r X) -> usize {::ban} defined here +... +LL | let _: usize = X::ban; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::ban(_)` + | + = note: expected type `usize` + found type `for<'r> fn(&'r X) -> usize {::ban}` + +error[E0308]: mismatched types + --> $DIR/fn-or-tuple-struct-without-args.rs:42:20 + | +LL | fn bal(&self) -> usize; + | ----------------------- for<'r> fn(&'r X) -> usize {::bal} defined here +... +LL | let _: usize = X::bal; + | ^^^^^^ + | | + | expected usize, found fn item + | help: use parentheses to call this function: `X::bal(_)` + | + = note: expected type `usize` + found type `for<'r> fn(&'r X) -> usize {::bal}` + +error[E0615]: attempted to take value of method `ban` on type `X` + --> $DIR/fn-or-tuple-struct-without-args.rs:43:22 + | +LL | let _: usize = X.ban; + | ^^^ help: use parentheses to call the method: `ban()` + +error[E0615]: attempted to take value of method `bal` on type `X` + --> $DIR/fn-or-tuple-struct-without-args.rs:44:22 + | +LL | let _: usize = X.bal; + | ^^^ help: use parentheses to call the method: `bal()` + +error: aborting due to 16 previous errors + +Some errors have detailed explanations: E0308, E0423, E0615. For more information about an error, try `rustc --explain E0308`.