diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 977318b8589..97766b8368a 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -492,6 +492,7 @@ E0785: include_str!("./error_codes/E0785.md"), E0786: include_str!("./error_codes/E0786.md"), E0787: include_str!("./error_codes/E0787.md"), E0788: include_str!("./error_codes/E0788.md"), +E0790: include_str!("./error_codes/E0790.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/compiler/rustc_error_codes/src/error_codes/E0283.md b/compiler/rustc_error_codes/src/error_codes/E0283.md index 6885f9a486d..e5a3179aabf 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0283.md +++ b/compiler/rustc_error_codes/src/error_codes/E0283.md @@ -3,48 +3,31 @@ An implementation cannot be chosen unambiguously because of lack of information. Erroneous code example: ```compile_fail,E0283 -trait Generator { - fn create() -> u32; -} +struct Foo; -struct Impl; - -impl Generator for Impl { - fn create() -> u32 { 1 } -} - -struct AnotherImpl; - -impl Generator for AnotherImpl { - fn create() -> u32 { 2 } +impl Into for Foo { + fn into(self) -> u32 { 1 } } fn main() { - let cont: u32 = Generator::create(); - // error, impossible to choose one of Generator trait implementation - // Should it be Impl or AnotherImpl, maybe something else? + let foo = Foo; + let bar: u32 = foo.into() * 1u32; } ``` This error can be solved by adding type annotations that provide the missing -information to the compiler. In this case, the solution is to use a concrete -type: +information to the compiler. In this case, the solution is to specify the +fully-qualified method: ``` -trait Generator { - fn create() -> u32; -} +struct Foo; -struct AnotherImpl; - -impl Generator for AnotherImpl { - fn create() -> u32 { 2 } +impl Into for Foo { + fn into(self) -> u32 { 1 } } fn main() { - let gen1 = AnotherImpl::create(); - - // if there are multiple methods with same name (different traits) - let gen2 = ::create(); + let foo = Foo; + let bar: u32 = >::into(foo) * 1u32; } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0790.md b/compiler/rustc_error_codes/src/error_codes/E0790.md new file mode 100644 index 00000000000..93d9636626d --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0790.md @@ -0,0 +1,51 @@ +You need to specify a specific implementation of the trait in order to call the +method. + +Erroneous code example: + +```compile_fail,E0790 +trait Generator { + fn create() -> u32; +} + +struct Impl; + +impl Generator for Impl { + fn create() -> u32 { 1 } +} + +struct AnotherImpl; + +impl Generator for AnotherImpl { + fn create() -> u32 { 2 } +} + +fn main() { + let cont: u32 = Generator::create(); + // error, impossible to choose one of Generator trait implementation + // Should it be Impl or AnotherImpl, maybe something else? +} +``` + +This error can be solved by adding type annotations that provide the missing +information to the compiler. In this case, the solution is to use a concrete +type: + +``` +trait Generator { + fn create() -> u32; +} + +struct AnotherImpl; + +impl Generator for AnotherImpl { + fn create() -> u32 { 2 } +} + +fn main() { + let gen1 = AnotherImpl::create(); + + // if there are multiple methods with same name (different traits) + let gen2 = ::create(); +} +``` diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 826c16dda4a..541dace5cc2 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -74,6 +74,10 @@ impl TraitImpls { pub fn blanket_impls(&self) -> &[DefId] { self.blanket_impls.as_slice() } + + pub fn non_blanket_impls(&self) -> &FxIndexMap> { + &self.non_blanket_impls + } } impl<'tcx> TraitDef { 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 8a679ca005f..585159e309f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2104,6 +2104,98 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ); } } + + if let (Some(body_id), Some(ty::subst::GenericArgKind::Type(_))) = + (body_id, subst.map(|subst| subst.unpack())) + { + struct FindExprBySpan<'hir> { + span: Span, + result: Option<&'hir hir::Expr<'hir>>, + } + + impl<'v> hir::intravisit::Visitor<'v> for FindExprBySpan<'v> { + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + if self.span == ex.span { + self.result = Some(ex); + } else { + hir::intravisit::walk_expr(self, ex); + } + } + } + + let mut expr_finder = FindExprBySpan { span, result: None }; + + expr_finder.visit_expr(&self.tcx.hir().body(body_id).value); + + if let Some(hir::Expr { + kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)), .. } + ) = expr_finder.result + && let [ + .., + trait_path_segment @ hir::PathSegment { + res: Some(rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Trait, trait_id)), + .. + }, + hir::PathSegment { + ident: assoc_item_name, + res: Some(rustc_hir::def::Res::Def(_, item_id)), + .. + } + ] = path.segments + && data.trait_ref.def_id == *trait_id + && self.tcx.trait_of_item(item_id) == Some(*trait_id) + && !self.is_tainted_by_errors() + { + let (verb, noun) = match self.tcx.associated_item(item_id).kind { + ty::AssocKind::Const => ("refer to the", "constant"), + ty::AssocKind::Fn => ("call", "function"), + ty::AssocKind::Type => ("refer to the", "type"), // this is already covered by E0223, but this single match arm doesn't hurt here + }; + + // Replace the more general E0283 with a more specific error + err.cancel(); + err = self.tcx.sess.struct_span_err_with_code( + span, + &format!( + "cannot {verb} associated {noun} on trait without specifying the corresponding `impl` type", + ), + rustc_errors::error_code!(E0790), + ); + + if let Some(local_def_id) = data.trait_ref.def_id.as_local() + && let Some(hir::Node::Item(hir::Item { ident: trait_name, kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs), .. })) = self.tcx.hir().find_by_def_id(local_def_id) + && let Some(method_ref) = trait_item_refs.iter().find(|item_ref| item_ref.ident == *assoc_item_name) { + err.span_label(method_ref.span, format!("`{}::{}` defined here", trait_name, assoc_item_name)); + } + + err.span_label(span, format!("cannot {verb} associated {noun} of trait")); + + let trait_impls = self.tcx.trait_impls_of(data.trait_ref.def_id); + + if trait_impls.blanket_impls().is_empty() + && let Some((impl_ty, _)) = trait_impls.non_blanket_impls().iter().next() + && let Some(impl_def_id) = impl_ty.def() { + let message = if trait_impls.non_blanket_impls().len() == 1 { + "use the fully-qualified path to the only available implementation".to_string() + } else { + format!( + "use a fully-qualified path to a specific available implementation ({} found)", + trait_impls.non_blanket_impls().len() + ) + }; + + err.multipart_suggestion( + message, + vec![ + (trait_path_segment.ident.span.shrink_to_lo(), format!("<{} as ", self.tcx.def_path(impl_def_id).to_string_no_crate_verbose())), + (trait_path_segment.ident.span.shrink_to_hi(), format!(">")) + ], + Applicability::MaybeIncorrect + ); + } + } + }; + err } diff --git a/src/test/ui/associated-consts/issue-63496.rs b/src/test/ui/associated-consts/issue-63496.rs index f9f663af5e2..67ef4e74cf2 100644 --- a/src/test/ui/associated-consts/issue-63496.rs +++ b/src/test/ui/associated-consts/issue-63496.rs @@ -2,8 +2,8 @@ trait A { const C: usize; fn f() -> ([u8; A::C], [u8; A::C]); - //~^ ERROR: type annotations needed - //~| ERROR: type annotations needed + //~^ ERROR: E0790 + //~| ERROR: E0790 } fn main() {} diff --git a/src/test/ui/associated-consts/issue-63496.stderr b/src/test/ui/associated-consts/issue-63496.stderr index db39fd762c3..f2a4e01adea 100644 --- a/src/test/ui/associated-consts/issue-63496.stderr +++ b/src/test/ui/associated-consts/issue-63496.stderr @@ -1,27 +1,21 @@ -error[E0283]: type annotations needed +error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type --> $DIR/issue-63496.rs:4:21 | +LL | const C: usize; + | --------------- `A::C` defined here +LL | LL | fn f() -> ([u8; A::C], [u8; A::C]); - | ^^^^ - | | - | cannot infer type - | help: use the fully qualified path to an implementation: `::C` - | - = note: cannot satisfy `_: A` - = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + | ^^^^ cannot refer to the associated constant of trait -error[E0283]: type annotations needed +error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type --> $DIR/issue-63496.rs:4:33 | +LL | const C: usize; + | --------------- `A::C` defined here +LL | LL | fn f() -> ([u8; A::C], [u8; A::C]); - | ^^^^ - | | - | cannot infer type - | help: use the fully qualified path to an implementation: `::C` - | - = note: cannot satisfy `_: A` - = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + | ^^^^ cannot refer to the associated constant of trait error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0790`. diff --git a/src/test/ui/associated-item/issue-48027.rs b/src/test/ui/associated-item/issue-48027.rs index c9b4ccd3e8a..d2b51184c99 100644 --- a/src/test/ui/associated-item/issue-48027.rs +++ b/src/test/ui/associated-item/issue-48027.rs @@ -1,6 +1,6 @@ trait Bar { const X: usize; - fn return_n(&self) -> [u8; Bar::X]; //~ ERROR: type annotations needed + fn return_n(&self) -> [u8; Bar::X]; //~ ERROR: E0790 } impl dyn Bar {} //~ ERROR: the trait `Bar` cannot be made into an object diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr index 5487af1a835..45ea419336b 100644 --- a/src/test/ui/associated-item/issue-48027.stderr +++ b/src/test/ui/associated-item/issue-48027.stderr @@ -13,19 +13,15 @@ LL | const X: usize; | ^ ...because it contains this associated `const` = help: consider moving `X` to another trait -error[E0283]: type annotations needed +error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type --> $DIR/issue-48027.rs:3:32 | +LL | const X: usize; + | --------------- `Bar::X` defined here LL | fn return_n(&self) -> [u8; Bar::X]; - | ^^^^^^ - | | - | cannot infer type - | help: use the fully qualified path to an implementation: `::X` - | - = note: cannot satisfy `_: Bar` - = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + | ^^^^^^ cannot refer to the associated constant of trait error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0283. +Some errors have detailed explanations: E0038, E0790. For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/associated-types/associated-types-unconstrained.rs b/src/test/ui/associated-types/associated-types-unconstrained.rs index b97d4af184f..2fb27bf3cd1 100644 --- a/src/test/ui/associated-types/associated-types-unconstrained.rs +++ b/src/test/ui/associated-types/associated-types-unconstrained.rs @@ -12,5 +12,5 @@ impl Foo for isize { pub fn main() { let x: isize = Foo::bar(); - //~^ ERROR type annotations needed + //~^ ERROR E0790 } diff --git a/src/test/ui/associated-types/associated-types-unconstrained.stderr b/src/test/ui/associated-types/associated-types-unconstrained.stderr index 60ec23cf655..e51a8f3bd1a 100644 --- a/src/test/ui/associated-types/associated-types-unconstrained.stderr +++ b/src/test/ui/associated-types/associated-types-unconstrained.stderr @@ -1,11 +1,12 @@ -error[E0283]: type annotations needed +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> $DIR/associated-types-unconstrained.rs:14:20 | +LL | fn bar() -> isize; + | ------------------ `Foo::bar` defined here +... LL | let x: isize = Foo::bar(); - | ^^^^^^^^ cannot infer type - | - = note: cannot satisfy `_: Foo` + | ^^^^^^^^ cannot call associated function of trait error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0790`. diff --git a/src/test/ui/error-codes/E0283.rs b/src/test/ui/error-codes/E0283.rs index 4d7c2f2396d..0643af4b7e8 100644 --- a/src/test/ui/error-codes/E0283.rs +++ b/src/test/ui/error-codes/E0283.rs @@ -27,7 +27,7 @@ impl Generator for AnotherImpl { } fn main() { - let cont: u32 = Generator::create(); //~ ERROR E0283 + let cont: u32 = Generator::create(); //~ ERROR E0790 } fn buzz() { diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index a107160d11a..90a28874ead 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -1,10 +1,16 @@ -error[E0283]: type annotations needed +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> $DIR/E0283.rs:30:21 | +LL | fn create() -> u32; + | ------------------- `Generator::create` defined here +... LL | let cont: u32 = Generator::create(); - | ^^^^^^^^^^^^^^^^^ cannot infer type + | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | - = note: cannot satisfy `_: Generator` +help: use a fully-qualified path to a specific available implementation (2 found) + | +LL | let cont: u32 = <::Impl as Generator>::create(); + | ++++++++++ + error[E0283]: type annotations needed --> $DIR/E0283.rs:35:24 @@ -27,4 +33,5 @@ LL | let bar = >::into(foo_impl) * 1u32; error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0283, E0790. +For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/error-codes/E0790.rs b/src/test/ui/error-codes/E0790.rs new file mode 100644 index 00000000000..d99006d2df7 --- /dev/null +++ b/src/test/ui/error-codes/E0790.rs @@ -0,0 +1,53 @@ +mod inner { + pub trait MyTrait { + const MY_ASSOC_CONST: (); + + fn my_fn(); + } + + pub struct MyStruct; + + impl MyTrait for MyStruct { + const MY_ASSOC_CONST: () = (); + + fn my_fn() {} + } + + fn call() { + MyTrait::my_fn(); //~ ERROR E0790 + } + + fn use_const() { + let _ = MyTrait::MY_ASSOC_CONST; //~ ERROR E0790 + } +} + +fn call_inner() { + inner::MyTrait::my_fn(); //~ ERROR E0790 +} + +fn use_const_inner() { + let _ = inner::MyTrait::MY_ASSOC_CONST; //~ ERROR E0790 +} + +trait MyTrait2 { + fn my_fn(); +} + +struct Impl1; + +impl MyTrait2 for Impl1 { + fn my_fn() {} +} + +struct Impl2; + +impl MyTrait2 for Impl2 { + fn my_fn() {} +} + +fn call_multiple_impls() { + MyTrait2::my_fn(); //~ ERROR E0790 +} + +fn main() {} diff --git a/src/test/ui/error-codes/E0790.stderr b/src/test/ui/error-codes/E0790.stderr new file mode 100644 index 00000000000..6e173a9682a --- /dev/null +++ b/src/test/ui/error-codes/E0790.stderr @@ -0,0 +1,73 @@ +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/E0790.rs:17:9 + | +LL | fn my_fn(); + | ----------- `MyTrait::my_fn` defined here +... +LL | MyTrait::my_fn(); + | ^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use the fully-qualified path to the only available implementation + | +LL | <::inner::MyStruct as MyTrait>::my_fn(); + | +++++++++++++++++++++ + + +error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type + --> $DIR/E0790.rs:21:17 + | +LL | const MY_ASSOC_CONST: (); + | ------------------------- `MyTrait::MY_ASSOC_CONST` defined here +... +LL | let _ = MyTrait::MY_ASSOC_CONST; + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot refer to the associated constant of trait + | +help: use the fully-qualified path to the only available implementation + | +LL | let _ = <::inner::MyStruct as MyTrait>::MY_ASSOC_CONST; + | +++++++++++++++++++++ + + +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/E0790.rs:26:5 + | +LL | fn my_fn(); + | ----------- `MyTrait::my_fn` defined here +... +LL | inner::MyTrait::my_fn(); + | ^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use the fully-qualified path to the only available implementation + | +LL | inner::<::inner::MyStruct as MyTrait>::my_fn(); + | +++++++++++++++++++++ + + +error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type + --> $DIR/E0790.rs:30:13 + | +LL | const MY_ASSOC_CONST: (); + | ------------------------- `MyTrait::MY_ASSOC_CONST` defined here +... +LL | let _ = inner::MyTrait::MY_ASSOC_CONST; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot refer to the associated constant of trait + | +help: use the fully-qualified path to the only available implementation + | +LL | let _ = inner::<::inner::MyStruct as MyTrait>::MY_ASSOC_CONST; + | +++++++++++++++++++++ + + +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/E0790.rs:50:5 + | +LL | fn my_fn(); + | ----------- `MyTrait2::my_fn` defined here +... +LL | MyTrait2::my_fn(); + | ^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use a fully-qualified path to a specific available implementation (2 found) + | +LL | <::Impl1 as MyTrait2>::my_fn(); + | +++++++++++ + + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0790`. diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/issues/issue-54954.rs index ddd39141541..d4e1df22770 100644 --- a/src/test/ui/issues/issue-54954.rs +++ b/src/test/ui/issues/issue-54954.rs @@ -1,5 +1,5 @@ const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); -//~^ ERROR type annotations needed +//~^ ERROR E0790 trait Tt { const fn const_val() -> usize { diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/issues/issue-54954.stderr index 6e8d3cac9a7..668985c2b59 100644 --- a/src/test/ui/issues/issue-54954.stderr +++ b/src/test/ui/issues/issue-54954.stderr @@ -4,13 +4,17 @@ error[E0379]: functions in traits cannot be declared const LL | const fn const_val() -> usize { | ^^^^^ functions in traits cannot be const -error[E0283]: type annotations needed +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> $DIR/issue-54954.rs:1:24 | -LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - | - = note: cannot satisfy `_: Tt` +LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait +... +LL | / const fn const_val() -> usize { +LL | | +LL | | core::mem::size_of::() +LL | | } + | |_____- `Tt::const_val` defined here error[E0080]: evaluation of constant value failed --> $DIR/issue-54954.rs:11:15 @@ -26,5 +30,5 @@ LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { error: aborting due to 4 previous errors -Some errors have detailed explanations: E0080, E0283, E0379. +Some errors have detailed explanations: E0080, E0379, E0790. For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/issues/issue-58022.rs b/src/test/ui/issues/issue-58022.rs index e4b9b3b53a6..2a8a1eaa6d3 100644 --- a/src/test/ui/issues/issue-58022.rs +++ b/src/test/ui/issues/issue-58022.rs @@ -2,7 +2,7 @@ pub trait Foo: Sized { const SIZE: usize; fn new(slice: &[u8; Foo::SIZE]) -> Self; - //~^ ERROR: type annotations needed + //~^ ERROR: E0790 } pub struct Bar(T); diff --git a/src/test/ui/issues/issue-58022.stderr b/src/test/ui/issues/issue-58022.stderr index 0128b70e216..6d24209ad3c 100644 --- a/src/test/ui/issues/issue-58022.stderr +++ b/src/test/ui/issues/issue-58022.stderr @@ -4,19 +4,16 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo LL | Foo(Box::new(*slice)) | ^^^ not a function, tuple struct or tuple variant -error[E0283]: type annotations needed +error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type --> $DIR/issue-58022.rs:4:25 | +LL | const SIZE: usize; + | ------------------ `Foo::SIZE` defined here +LL | LL | fn new(slice: &[u8; Foo::SIZE]) -> Self; - | ^^^^^^^^^ - | | - | cannot infer type - | help: use the fully qualified path to an implementation: `::SIZE` - | - = note: cannot satisfy `_: Foo` - = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + | ^^^^^^^^^ cannot refer to the associated constant of trait error: aborting due to 2 previous errors -Some errors have detailed explanations: E0283, E0423. -For more information about an error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0423, E0790. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/traits/static-method-generic-inference.rs b/src/test/ui/traits/static-method-generic-inference.rs index 759416d1901..f4e94c4f786 100644 --- a/src/test/ui/traits/static-method-generic-inference.rs +++ b/src/test/ui/traits/static-method-generic-inference.rs @@ -22,7 +22,7 @@ mod base { pub fn foo() { let _f: base::Foo = base::HasNew::new(); - //~^ ERROR type annotations needed + //~^ ERROR E0790 } fn main() { } diff --git a/src/test/ui/traits/static-method-generic-inference.stderr b/src/test/ui/traits/static-method-generic-inference.stderr index 1a0bcf00a67..f1b8f23ecc7 100644 --- a/src/test/ui/traits/static-method-generic-inference.stderr +++ b/src/test/ui/traits/static-method-generic-inference.stderr @@ -1,11 +1,17 @@ -error[E0283]: type annotations needed +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> $DIR/static-method-generic-inference.rs:24:25 | +LL | fn new() -> T; + | -------------- `HasNew::new` defined here +... LL | let _f: base::Foo = base::HasNew::new(); - | ^^^^^^^^^^^^^^^^^ cannot infer type + | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | - = note: cannot satisfy `_: HasNew` +help: use the fully-qualified path to the only available implementation + | +LL | let _f: base::Foo = base::<::base::Foo as HasNew>::new(); + | +++++++++++++++ + error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0790`.