Rollup merge of #67747 - estebank:bare-assoc-const, r=Centril
Explain that associated types and consts can't be accessed directly on the trait's path Partially address #44539.
This commit is contained in:
commit
1a0b2a5aaa
4 changed files with 50 additions and 5 deletions
|
@ -2075,7 +2075,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
|
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
|
||||||
err.note(&format!("cannot resolve `{}`", predicate));
|
err.note(&format!("cannot resolve `{}`", predicate));
|
||||||
if let (Ok(ref snippet), ObligationCauseCode::BindingObligation(ref def_id, _)) =
|
if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
|
||||||
|
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
|
||||||
|
} else if let (
|
||||||
|
Ok(ref snippet),
|
||||||
|
ObligationCauseCode::BindingObligation(ref def_id, _),
|
||||||
|
) =
|
||||||
(self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code)
|
(self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code)
|
||||||
{
|
{
|
||||||
let generics = self.tcx.generics_of(*def_id);
|
let generics = self.tcx.generics_of(*def_id);
|
||||||
|
@ -2173,6 +2178,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn suggest_fully_qualified_path(
|
||||||
|
&self,
|
||||||
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
|
def_id: DefId,
|
||||||
|
span: Span,
|
||||||
|
trait_ref: DefId,
|
||||||
|
) {
|
||||||
|
if let Some(assoc_item) = self.tcx.opt_associated_item(def_id) {
|
||||||
|
if let ty::AssocKind::Const | ty::AssocKind::Type = assoc_item.kind {
|
||||||
|
err.note(&format!(
|
||||||
|
"{}s cannot be accessed directly on a `trait`, they can only be \
|
||||||
|
accessed through a specific `impl`",
|
||||||
|
assoc_item.kind.suggestion_descr(),
|
||||||
|
));
|
||||||
|
err.span_suggestion(
|
||||||
|
span,
|
||||||
|
"use the fully qualified path to an implementation",
|
||||||
|
format!("<Type as {}>::{}", self.tcx.def_path_str(trait_ref), assoc_item.ident),
|
||||||
|
Applicability::HasPlaceholders,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the trait predicate may apply for *some* assignment
|
/// Returns `true` if the trait predicate may apply for *some* assignment
|
||||||
/// to the type parameters.
|
/// to the type parameters.
|
||||||
fn predicate_can_apply(
|
fn predicate_can_apply(
|
||||||
|
|
|
@ -5,9 +5,13 @@ LL | const C: usize;
|
||||||
| --------------- required by `A::C`
|
| --------------- required by `A::C`
|
||||||
LL |
|
LL |
|
||||||
LL | fn f() -> ([u8; A::C], [u8; A::C]);
|
LL | fn f() -> ([u8; A::C], [u8; A::C]);
|
||||||
| ^^^^ cannot infer type
|
| ^^^^
|
||||||
|
| |
|
||||||
|
| cannot infer type
|
||||||
|
| help: use the fully qualified path to an implementation: `<Type as A>::C`
|
||||||
|
|
|
|
||||||
= note: cannot resolve `_: A`
|
= note: cannot resolve `_: 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[E0283]: type annotations needed
|
||||||
--> $DIR/issue-63496.rs:4:33
|
--> $DIR/issue-63496.rs:4:33
|
||||||
|
@ -16,9 +20,13 @@ LL | const C: usize;
|
||||||
| --------------- required by `A::C`
|
| --------------- required by `A::C`
|
||||||
LL |
|
LL |
|
||||||
LL | fn f() -> ([u8; A::C], [u8; A::C]);
|
LL | fn f() -> ([u8; A::C], [u8; A::C]);
|
||||||
| ^^^^ cannot infer type
|
| ^^^^
|
||||||
|
| |
|
||||||
|
| cannot infer type
|
||||||
|
| help: use the fully qualified path to an implementation: `<Type as A>::C`
|
||||||
|
|
|
|
||||||
= note: cannot resolve `_: A`
|
= note: cannot resolve `_: 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
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,13 @@ error[E0283]: type annotations needed
|
||||||
LL | const X: usize;
|
LL | const X: usize;
|
||||||
| --------------- required by `Bar::X`
|
| --------------- required by `Bar::X`
|
||||||
LL | fn return_n(&self) -> [u8; Bar::X];
|
LL | fn return_n(&self) -> [u8; Bar::X];
|
||||||
| ^^^^^^ cannot infer type
|
| ^^^^^^
|
||||||
|
| |
|
||||||
|
| cannot infer type
|
||||||
|
| help: use the fully qualified path to an implementation: `<Type as Bar>::X`
|
||||||
|
|
|
|
||||||
= note: cannot resolve `_: Bar`
|
= note: cannot resolve `_: 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
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,13 @@ LL | const SIZE: usize;
|
||||||
| ------------------ required by `Foo::SIZE`
|
| ------------------ required by `Foo::SIZE`
|
||||||
LL |
|
LL |
|
||||||
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
||||||
| ^^^^^^^^^ cannot infer type
|
| ^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| cannot infer type
|
||||||
|
| help: use the fully qualified path to an implementation: `<Type as Foo>::SIZE`
|
||||||
|
|
|
|
||||||
= note: cannot resolve `_: Foo`
|
= note: cannot resolve `_: 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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue