Add E0790 as more specific variant of E0283
This commit is contained in:
parent
96c2df810b
commit
1cbacc0c8a
21 changed files with 354 additions and 92 deletions
|
@ -492,6 +492,7 @@ E0785: include_str!("./error_codes/E0785.md"),
|
||||||
E0786: include_str!("./error_codes/E0786.md"),
|
E0786: include_str!("./error_codes/E0786.md"),
|
||||||
E0787: include_str!("./error_codes/E0787.md"),
|
E0787: include_str!("./error_codes/E0787.md"),
|
||||||
E0788: include_str!("./error_codes/E0788.md"),
|
E0788: include_str!("./error_codes/E0788.md"),
|
||||||
|
E0790: include_str!("./error_codes/E0790.md"),
|
||||||
;
|
;
|
||||||
// E0006, // merged with E0005
|
// E0006, // merged with E0005
|
||||||
// E0008, // cannot bind by-move into a pattern guard
|
// E0008, // cannot bind by-move into a pattern guard
|
||||||
|
|
|
@ -3,48 +3,31 @@ An implementation cannot be chosen unambiguously because of lack of information.
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0283
|
```compile_fail,E0283
|
||||||
trait Generator {
|
struct Foo;
|
||||||
fn create() -> u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Impl;
|
impl Into<u32> for Foo {
|
||||||
|
fn into(self) -> u32 { 1 }
|
||||||
impl Generator for Impl {
|
|
||||||
fn create() -> u32 { 1 }
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AnotherImpl;
|
|
||||||
|
|
||||||
impl Generator for AnotherImpl {
|
|
||||||
fn create() -> u32 { 2 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cont: u32 = Generator::create();
|
let foo = Foo;
|
||||||
// error, impossible to choose one of Generator trait implementation
|
let bar: u32 = foo.into() * 1u32;
|
||||||
// Should it be Impl or AnotherImpl, maybe something else?
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This error can be solved by adding type annotations that provide the missing
|
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
|
information to the compiler. In this case, the solution is to specify the
|
||||||
type:
|
fully-qualified method:
|
||||||
|
|
||||||
```
|
```
|
||||||
trait Generator {
|
struct Foo;
|
||||||
fn create() -> u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AnotherImpl;
|
impl Into<u32> for Foo {
|
||||||
|
fn into(self) -> u32 { 1 }
|
||||||
impl Generator for AnotherImpl {
|
|
||||||
fn create() -> u32 { 2 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let gen1 = AnotherImpl::create();
|
let foo = Foo;
|
||||||
|
let bar: u32 = <Foo as Into<u32>>::into(foo) * 1u32;
|
||||||
// if there are multiple methods with same name (different traits)
|
|
||||||
let gen2 = <AnotherImpl as Generator>::create();
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
51
compiler/rustc_error_codes/src/error_codes/E0790.md
Normal file
51
compiler/rustc_error_codes/src/error_codes/E0790.md
Normal file
|
@ -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 = <AnotherImpl as Generator>::create();
|
||||||
|
}
|
||||||
|
```
|
|
@ -74,6 +74,10 @@ impl TraitImpls {
|
||||||
pub fn blanket_impls(&self) -> &[DefId] {
|
pub fn blanket_impls(&self) -> &[DefId] {
|
||||||
self.blanket_impls.as_slice()
|
self.blanket_impls.as_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn non_blanket_impls(&self) -> &FxIndexMap<SimplifiedType, Vec<DefId>> {
|
||||||
|
&self.non_blanket_impls
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TraitDef {
|
impl<'tcx> TraitDef {
|
||||||
|
|
|
@ -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
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ trait A {
|
||||||
const C: usize;
|
const C: usize;
|
||||||
|
|
||||||
fn f() -> ([u8; A::C], [u8; A::C]);
|
fn f() -> ([u8; A::C], [u8; A::C]);
|
||||||
//~^ ERROR: type annotations needed
|
//~^ ERROR: E0790
|
||||||
//~| ERROR: type annotations needed
|
//~| ERROR: E0790
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -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
|
--> $DIR/issue-63496.rs:4:21
|
||||||
|
|
|
|
||||||
|
LL | const C: usize;
|
||||||
|
| --------------- `A::C` defined here
|
||||||
|
LL |
|
||||||
LL | fn f() -> ([u8; A::C], [u8; A::C]);
|
LL | fn f() -> ([u8; A::C], [u8; A::C]);
|
||||||
| ^^^^
|
| ^^^^ cannot refer to the associated constant of trait
|
||||||
| |
|
|
||||||
| cannot infer type
|
|
||||||
| help: use the fully qualified path to an implementation: `<Type as A>::C`
|
|
||||||
|
|
|
||||||
= note: cannot satisfy `_: A`
|
|
||||||
= note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
|
|
||||||
|
|
||||||
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
|
--> $DIR/issue-63496.rs:4:33
|
||||||
|
|
|
|
||||||
|
LL | const C: usize;
|
||||||
|
| --------------- `A::C` defined here
|
||||||
|
LL |
|
||||||
LL | fn f() -> ([u8; A::C], [u8; A::C]);
|
LL | fn f() -> ([u8; A::C], [u8; A::C]);
|
||||||
| ^^^^
|
| ^^^^ cannot refer to the associated constant of trait
|
||||||
| |
|
|
||||||
| cannot infer type
|
|
||||||
| help: use the fully qualified path to an implementation: `<Type as A>::C`
|
|
||||||
|
|
|
||||||
= note: cannot satisfy `_: A`
|
|
||||||
= note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
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`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
trait Bar {
|
trait Bar {
|
||||||
const X: usize;
|
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
|
impl dyn Bar {} //~ ERROR: the trait `Bar` cannot be made into an object
|
||||||
|
|
|
@ -13,19 +13,15 @@ LL | const X: usize;
|
||||||
| ^ ...because it contains this associated `const`
|
| ^ ...because it contains this associated `const`
|
||||||
= help: consider moving `X` to another trait
|
= 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
|
--> $DIR/issue-48027.rs:3:32
|
||||||
|
|
|
|
||||||
|
LL | const X: usize;
|
||||||
|
| --------------- `Bar::X` defined here
|
||||||
LL | fn return_n(&self) -> [u8; Bar::X];
|
LL | fn return_n(&self) -> [u8; Bar::X];
|
||||||
| ^^^^^^
|
| ^^^^^^ cannot refer to the associated constant of trait
|
||||||
| |
|
|
||||||
| cannot infer type
|
|
||||||
| help: use the fully qualified path to an implementation: `<Type as Bar>::X`
|
|
||||||
|
|
|
||||||
= note: cannot satisfy `_: Bar`
|
|
||||||
= note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
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`.
|
For more information about an error, try `rustc --explain E0038`.
|
||||||
|
|
|
@ -12,5 +12,5 @@ impl Foo for isize {
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let x: isize = Foo::bar();
|
let x: isize = Foo::bar();
|
||||||
//~^ ERROR type annotations needed
|
//~^ ERROR E0790
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
--> $DIR/associated-types-unconstrained.rs:14:20
|
||||||
|
|
|
|
||||||
|
LL | fn bar() -> isize;
|
||||||
|
| ------------------ `Foo::bar` defined here
|
||||||
|
...
|
||||||
LL | let x: isize = Foo::bar();
|
LL | let x: isize = Foo::bar();
|
||||||
| ^^^^^^^^ cannot infer type
|
| ^^^^^^^^ cannot call associated function of trait
|
||||||
|
|
|
||||||
= note: cannot satisfy `_: Foo`
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
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`.
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Generator for AnotherImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cont: u32 = Generator::create(); //~ ERROR E0283
|
let cont: u32 = Generator::create(); //~ ERROR E0790
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buzz() {
|
fn buzz() {
|
||||||
|
|
|
@ -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
|
--> $DIR/E0283.rs:30:21
|
||||||
|
|
|
|
||||||
|
LL | fn create() -> u32;
|
||||||
|
| ------------------- `Generator::create` defined here
|
||||||
|
...
|
||||||
LL | let cont: u32 = Generator::create();
|
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
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/E0283.rs:35:24
|
--> $DIR/E0283.rs:35:24
|
||||||
|
@ -27,4 +33,5 @@ LL | let bar = <Impl as Into<T>>::into(foo_impl) * 1u32;
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
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`.
|
||||||
|
|
53
src/test/ui/error-codes/E0790.rs
Normal file
53
src/test/ui/error-codes/E0790.rs
Normal file
|
@ -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() {}
|
73
src/test/ui/error-codes/E0790.stderr
Normal file
73
src/test/ui/error-codes/E0790.stderr
Normal file
|
@ -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`.
|
|
@ -1,5 +1,5 @@
|
||||||
const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
|
const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
|
||||||
//~^ ERROR type annotations needed
|
//~^ ERROR E0790
|
||||||
|
|
||||||
trait Tt {
|
trait Tt {
|
||||||
const fn const_val<T: Sized>() -> usize {
|
const fn const_val<T: Sized>() -> usize {
|
||||||
|
|
|
@ -4,13 +4,17 @@ error[E0379]: functions in traits cannot be declared const
|
||||||
LL | const fn const_val<T: Sized>() -> usize {
|
LL | const fn const_val<T: Sized>() -> usize {
|
||||||
| ^^^^^ functions in traits cannot be const
|
| ^^^^^ 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
|
--> $DIR/issue-54954.rs:1:24
|
||||||
|
|
|
|
||||||
LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
|
LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
|
||||||
|
|
...
|
||||||
= note: cannot satisfy `_: Tt`
|
LL | / const fn const_val<T: Sized>() -> usize {
|
||||||
|
LL | |
|
||||||
|
LL | | core::mem::size_of::<T>()
|
||||||
|
LL | | }
|
||||||
|
| |_____- `Tt::const_val` defined here
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/issue-54954.rs:11:15
|
--> $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
|
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`.
|
For more information about an error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -2,7 +2,7 @@ pub trait Foo: Sized {
|
||||||
const SIZE: usize;
|
const SIZE: usize;
|
||||||
|
|
||||||
fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
||||||
//~^ ERROR: type annotations needed
|
//~^ ERROR: E0790
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Bar<T: ?Sized>(T);
|
pub struct Bar<T: ?Sized>(T);
|
||||||
|
|
|
@ -4,19 +4,16 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo
|
||||||
LL | Foo(Box::new(*slice))
|
LL | Foo(Box::new(*slice))
|
||||||
| ^^^ not a function, tuple struct or tuple variant
|
| ^^^ 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
|
--> $DIR/issue-58022.rs:4:25
|
||||||
|
|
|
|
||||||
|
LL | const SIZE: usize;
|
||||||
|
| ------------------ `Foo::SIZE` defined here
|
||||||
|
LL |
|
||||||
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^ cannot refer to the associated constant of trait
|
||||||
| |
|
|
||||||
| cannot infer type
|
|
||||||
| help: use the fully qualified path to an implementation: `<Type as Foo>::SIZE`
|
|
||||||
|
|
|
||||||
= note: cannot satisfy `_: Foo`
|
|
||||||
= note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0283, E0423.
|
Some errors have detailed explanations: E0423, E0790.
|
||||||
For more information about an error, try `rustc --explain E0283`.
|
For more information about an error, try `rustc --explain E0423`.
|
||||||
|
|
|
@ -22,7 +22,7 @@ mod base {
|
||||||
|
|
||||||
pub fn foo() {
|
pub fn foo() {
|
||||||
let _f: base::Foo = base::HasNew::new();
|
let _f: base::Foo = base::HasNew::new();
|
||||||
//~^ ERROR type annotations needed
|
//~^ ERROR E0790
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -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
|
--> $DIR/static-method-generic-inference.rs:24:25
|
||||||
|
|
|
|
||||||
|
LL | fn new() -> T;
|
||||||
|
| -------------- `HasNew::new` defined here
|
||||||
|
...
|
||||||
LL | let _f: base::Foo = base::HasNew::new();
|
LL | let _f: base::Foo = base::HasNew::new();
|
||||||
| ^^^^^^^^^^^^^^^^^ cannot infer type
|
| ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
|
||||||
|
|
|
|
||||||
= note: cannot satisfy `_: HasNew<Foo>`
|
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
|
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`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue