From 400b6d6ffead7ae7aeb0e9f766715f84e30b8850 Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Sat, 16 Jul 2022 04:35:30 +0300 Subject: [PATCH 1/6] Add new label for E0283 new label: `cannot call trait method as a free function` --- .../rustc_trait_selection/src/traits/error_reporting/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index aa1c91362891b..86a0aef8487c7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1998,6 +1998,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts()); let mut err = if let Some(subst) = subst { + let mut err = + struct_span_err!(self.tcx.sess, span, E0283, "type annotations needed",); + err.span_label(span, "cannot call trait method as a free function"); + err.emit(); + self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283, true) } else { struct_span_err!( From 29c32a8299a028ddc2606ce36a25a8b414f31e8d Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Sat, 16 Jul 2022 04:49:56 +0300 Subject: [PATCH 2/6] Check if `PredicateObligation` is `ObligationCauseCode::ItemObligation` to emit E0283 --- .../src/traits/error_reporting/mod.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 86a0aef8487c7..a161b22720373 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1998,10 +1998,17 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts()); let mut err = if let Some(subst) = subst { - let mut err = - struct_span_err!(self.tcx.sess, span, E0283, "type annotations needed",); - err.span_label(span, "cannot call trait method as a free function"); - err.emit(); + if matches!(obligation.cause.code(), ObligationCauseCode::ItemObligation(..)) { + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0283, + "type annotations needed", + ); + err.span_label(span, "cannot call trait method as a free function"); + err.emit(); + return; + } self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283, true) } else { From 6c63d817d139ccc8cc0818ed35394f2d0cd709cc Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Sat, 16 Jul 2022 05:10:42 +0300 Subject: [PATCH 3/6] `PredicateObligation` should not be a constant to emit E0283 --- .../rustc_trait_selection/src/traits/error_reporting/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index a161b22720373..6189025c5efb8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1998,7 +1998,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts()); let mut err = if let Some(subst) = subst { - if matches!(obligation.cause.code(), ObligationCauseCode::ItemObligation(..)) { + if matches!(obligation.cause.code(), ObligationCauseCode::ItemObligation(..)) + && !obligation.param_env.is_const() + { let mut err = struct_span_err!( self.tcx.sess, span, From 8f2c21d590a78a19ffe623587a5326416600c304 Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Mon, 18 Jul 2022 21:43:06 +0300 Subject: [PATCH 4/6] Avoid saying `cannot call trait method as a free function` on an expression like `<_ as Trait>::method()` --- compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 6189025c5efb8..d497e2b71c933 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2000,6 +2000,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { let mut err = if let Some(subst) = subst { if matches!(obligation.cause.code(), ObligationCauseCode::ItemObligation(..)) && !obligation.param_env.is_const() + && !self.is_tainted_by_errors() { let mut err = struct_span_err!( self.tcx.sess, From afaa32973a13376d9576c2afb27c9697f3258a96 Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Tue, 19 Jul 2022 02:23:21 +0300 Subject: [PATCH 5/6] Update ui test for the new E0283 label label: `cannot call trait method as a free function` --- .../associated-types-unconstrained.stderr | 4 +- src/test/ui/error-codes/E0283.stderr | 19 +----- src/test/ui/inference/issue-72690.stderr | 58 ++++--------------- src/test/ui/issues/issue-29147.stderr | 10 +--- src/test/ui/traits/issue-77982.stderr | 53 +++-------------- .../static-method-generic-inference.stderr | 4 +- 6 files changed, 23 insertions(+), 125 deletions(-) diff --git a/src/test/ui/associated-types/associated-types-unconstrained.stderr b/src/test/ui/associated-types/associated-types-unconstrained.stderr index 60ec23cf655ab..a414bf04868cf 100644 --- a/src/test/ui/associated-types/associated-types-unconstrained.stderr +++ b/src/test/ui/associated-types/associated-types-unconstrained.stderr @@ -2,9 +2,7 @@ error[E0283]: type annotations needed --> $DIR/associated-types-unconstrained.rs:14:20 | LL | let x: isize = Foo::bar(); - | ^^^^^^^^ cannot infer type - | - = note: cannot satisfy `_: Foo` + | ^^^^^^^^ cannot call trait method as a free function error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index a107160d11a35..1021fed41508d 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -2,28 +2,13 @@ error[E0283]: type annotations needed --> $DIR/E0283.rs:30:21 | LL | let cont: u32 = Generator::create(); - | ^^^^^^^^^^^^^^^^^ cannot infer type - | - = note: cannot satisfy `_: Generator` + | ^^^^^^^^^^^^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/E0283.rs:35:24 | LL | let bar = foo_impl.into() * 1u32; - | ^^^^ - | -note: multiple `impl`s satisfying `Impl: Into<_>` found - --> $DIR/E0283.rs:17:1 - | -LL | impl Into for Impl { - | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: and another `impl` found in the `core` crate: - - impl Into for T - where U: From; -help: try using a fully qualified path to specify the expected types - | -LL | let bar = >::into(foo_impl) * 1u32; - | ++++++++++++++++++++++++ ~ + | ^^^^ cannot call trait method as a free function error: aborting due to 2 previous errors diff --git a/src/test/ui/inference/issue-72690.stderr b/src/test/ui/inference/issue-72690.stderr index d4eeda07366a8..ee56a245a34ef 100644 --- a/src/test/ui/inference/issue-72690.stderr +++ b/src/test/ui/inference/issue-72690.stderr @@ -2,11 +2,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:7:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` - | - = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - - impl<> From<&String> for String; - - impl<> From<&str> for String; + | ^^^^^^^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/issue-72690.rs:7:22 @@ -51,31 +47,17 @@ help: try using a fully qualified path to specify the expected types LL | |x| String::from(>::as_ref("x")); | ++++++++++++++++++++++++++ ~ -error[E0283]: type annotations needed for `&T` - --> $DIR/issue-72690.rs:17:9 +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:17:17 | LL | let _ = "x".as_ref(); - | ^ ------ type must be known at this point - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: consider giving this pattern a type, where the type for type parameter `T` is specified - | -LL | let _: &T = "x".as_ref(); - | ++++ + | ^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/issue-72690.rs:21:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` - | - = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - - impl<> From<&String> for String; - - impl<> From<&str> for String; + | ^^^^^^^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/issue-72690.rs:21:22 @@ -97,11 +79,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:28:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` - | - = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - - impl<> From<&String> for String; - - impl<> From<&str> for String; + | ^^^^^^^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/issue-72690.rs:28:22 @@ -123,11 +101,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:37:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` - | - = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - - impl<> From<&String> for String; - - impl<> From<&str> for String; + | ^^^^^^^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/issue-72690.rs:37:22 @@ -149,11 +123,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:46:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` - | - = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - - impl<> From<&String> for String; - - impl<> From<&str> for String; + | ^^^^^^^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/issue-72690.rs:46:22 @@ -175,11 +145,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:53:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` - | - = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - - impl<> From<&String> for String; - - impl<> From<&str> for String; + | ^^^^^^^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/issue-72690.rs:53:22 @@ -201,11 +167,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:62:5 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` - | - = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - - impl<> From<&String> for String; - - impl<> From<&str> for String; + | ^^^^^^^^^^^^ cannot call trait method as a free function error[E0283]: type annotations needed --> $DIR/issue-72690.rs:62:22 diff --git a/src/test/ui/issues/issue-29147.stderr b/src/test/ui/issues/issue-29147.stderr index 5570e887edce5..e96cf9293efce 100644 --- a/src/test/ui/issues/issue-29147.stderr +++ b/src/test/ui/issues/issue-29147.stderr @@ -2,15 +2,7 @@ error[E0283]: type annotations needed --> $DIR/issue-29147.rs:21:13 | LL | let _ = >::xxx; - | ^^^^^^^^^^^^ cannot infer type for struct `S5<_>` - | -note: multiple `impl`s satisfying `S5<_>: Foo` found - --> $DIR/issue-29147.rs:17:1 - | -LL | impl Foo for S5 { fn xxx(&self) {} } - | ^^^^^^^^^^^^^^^^^^^^ -LL | impl Foo for S5 { fn xxx(&self) {} } - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ cannot call trait method as a free function error: aborting due to previous error diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index a2d23c4e9dfad..6c063b36ef2fd 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -41,59 +41,22 @@ LL | opts.get::(opt.as_ref()); | +++++ error[E0283]: type annotations needed - --> $DIR/issue-77982.rs:13:59 + --> $DIR/issue-77982.rs:13:44 | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); - | --------- ^^^^ - | | - | type must be known at this point - | - = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`: - - impl From for u32; - - impl From for u32; - - impl From for u32; - - impl From for u32; - and 3 more -help: try using a fully qualified path to specify the expected types - | -LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into(0u32))).collect(); - | +++++++++++++++++++++++ ~ + | ^^^^^^^^^ cannot call trait method as a free function -error[E0283]: type annotations needed for `Box` - --> $DIR/issue-77982.rs:36:9 +error[E0283]: type annotations needed + --> $DIR/issue-77982.rs:36:16 | LL | let _ = ().foo(); - | ^ --- type must be known at this point - | -note: multiple `impl`s satisfying `(): Foo<'_, _>` found - --> $DIR/issue-77982.rs:29:1 - | -LL | impl Foo<'static, u32> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | impl<'a> Foo<'a, i16> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: consider giving this pattern a type, where the type for type parameter `T` is specified - | -LL | let _: Box = ().foo(); - | ++++++++ + | ^^^ cannot call trait method as a free function -error[E0283]: type annotations needed for `Box` - --> $DIR/issue-77982.rs:40:9 +error[E0283]: type annotations needed + --> $DIR/issue-77982.rs:40:19 | LL | let _ = (&()).bar(); - | ^ --- type must be known at this point - | -note: multiple `impl`s satisfying `&(): Bar<'_, _>` found - --> $DIR/issue-77982.rs:32:1 - | -LL | impl<'a> Bar<'static, u32> for &'a () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | impl<'a> Bar<'a, i16> for &'a () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: consider giving this pattern a type, where the type for type parameter `T` is specified - | -LL | let _: Box = (&()).bar(); - | ++++++++ + | ^^^ cannot call trait method as a free function error: aborting due to 5 previous errors diff --git a/src/test/ui/traits/static-method-generic-inference.stderr b/src/test/ui/traits/static-method-generic-inference.stderr index 1a0bcf00a673a..6bf79dabce225 100644 --- a/src/test/ui/traits/static-method-generic-inference.stderr +++ b/src/test/ui/traits/static-method-generic-inference.stderr @@ -2,9 +2,7 @@ error[E0283]: type annotations needed --> $DIR/static-method-generic-inference.rs:24:25 | LL | let _f: base::Foo = base::HasNew::new(); - | ^^^^^^^^^^^^^^^^^ cannot infer type - | - = note: cannot satisfy `_: HasNew` + | ^^^^^^^^^^^^^^^^^ cannot call trait method as a free function error: aborting due to previous error From c30badaf024888e48c51dc54cdd7765f59f9549d Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Tue, 19 Jul 2022 03:08:17 +0300 Subject: [PATCH 6/6] Add ui test for #98938 --- src/test/ui/traits/issue-98938.rs | 10 ++++++++++ src/test/ui/traits/issue-98938.stderr | 9 +++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/test/ui/traits/issue-98938.rs create mode 100644 src/test/ui/traits/issue-98938.stderr diff --git a/src/test/ui/traits/issue-98938.rs b/src/test/ui/traits/issue-98938.rs new file mode 100644 index 0000000000000..2d05bee14b9e6 --- /dev/null +++ b/src/test/ui/traits/issue-98938.rs @@ -0,0 +1,10 @@ +trait Foo { + fn bar() {} +} + +fn main() { + Foo::bar(); + //~^ ERROR type annotations needed + + <_ as Foo>::bar(); +} diff --git a/src/test/ui/traits/issue-98938.stderr b/src/test/ui/traits/issue-98938.stderr new file mode 100644 index 0000000000000..37650f53fdbd8 --- /dev/null +++ b/src/test/ui/traits/issue-98938.stderr @@ -0,0 +1,9 @@ +error[E0283]: type annotations needed + --> $DIR/issue-98938.rs:6:5 + | +LL | Foo::bar(); + | ^^^^^^^^ cannot call trait method as a free function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`.