mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
For E0038, suggest associated type if available
This commit is contained in:
parent
502ce8287b
commit
220e8a7484
@ -524,6 +524,7 @@ pub enum StashKey {
|
||||
MaybeFruTypo,
|
||||
CallAssocMethod,
|
||||
TraitMissingMethod,
|
||||
AssociatedTypeSuggestion,
|
||||
OpaqueHiddenTypeMismatch,
|
||||
MaybeForgetReturn,
|
||||
/// Query cycle detected, stashing in favor of a better error.
|
||||
|
@ -18,6 +18,7 @@ use rustc_ast::*;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_errors::{
|
||||
codes::*, struct_span_code_err, Applicability, DiagnosticArgValue, ErrCode, IntoDiagnosticArg,
|
||||
StashKey,
|
||||
};
|
||||
use rustc_hir::def::Namespace::{self, *};
|
||||
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
|
||||
@ -3890,6 +3891,23 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
finalize,
|
||||
) {
|
||||
Ok(Some(partial_res)) if let Some(res) = partial_res.full_res() => {
|
||||
// if we also have an associated type that matches the ident, stash a suggestion
|
||||
if let Some(items) = self.diagnostic_metadata.current_trait_assoc_items
|
||||
&& let [Segment { ident, .. }] = path
|
||||
&& items.iter().any(|item| {
|
||||
item.ident == *ident && matches!(item.kind, AssocItemKind::Type(_))
|
||||
})
|
||||
{
|
||||
let mut diag = self.r.tcx.dcx().struct_allow("");
|
||||
diag.span_suggestion_verbose(
|
||||
path_span.shrink_to_lo(),
|
||||
"there is an associated type with the same name",
|
||||
"Self::",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
diag.stash(path_span, StashKey::AssociatedTypeSuggestion);
|
||||
}
|
||||
|
||||
if source.is_expected(res) || res == Res::Err {
|
||||
partial_res
|
||||
} else {
|
||||
|
@ -2922,6 +2922,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
&mut Default::default(),
|
||||
);
|
||||
self.suggest_unsized_bound_if_applicable(err, obligation);
|
||||
if let Some(span) = err.span.primary_span()
|
||||
&& let Some(mut diag) =
|
||||
self.tcx.dcx().steal_diagnostic(span, StashKey::AssociatedTypeSuggestion)
|
||||
&& let Ok(ref mut s1) = err.suggestions
|
||||
&& let Ok(ref mut s2) = diag.suggestions
|
||||
{
|
||||
s1.append(s2);
|
||||
diag.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,12 @@ trait Foo {
|
||||
fn foo() -> Clone;
|
||||
//~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
|
||||
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
//~| HELP if this is an object-safe trait, use `dyn`
|
||||
//~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
|
||||
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
//~| HELP if this is an object-safe trait, use `dyn`
|
||||
//~| ERROR the trait `Clone` cannot be made into an object [E0038]
|
||||
//~| HELP there is an associated type with the same name
|
||||
}
|
||||
|
||||
trait DbHandle: Sized {}
|
||||
@ -15,9 +18,12 @@ trait DbInterface {
|
||||
fn handle() -> DbHandle;
|
||||
//~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
|
||||
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
//~| HELP if this is an object-safe trait, use `dyn`
|
||||
//~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
|
||||
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
//~| HELP if this is an object-safe trait, use `dyn`
|
||||
//~| ERROR the trait `DbHandle` cannot be made into an object [E0038]
|
||||
//~| HELP there is an associated type with the same name
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -13,7 +13,7 @@ LL | fn foo() -> dyn Clone;
|
||||
| +++
|
||||
|
||||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/issue-116434-2015.rs:15:20
|
||||
--> $DIR/issue-116434-2015.rs:18:20
|
||||
|
|
||||
LL | fn handle() -> DbHandle;
|
||||
| ^^^^^^^^
|
||||
@ -47,9 +47,13 @@ LL | fn foo() -> Clone;
|
||||
|
|
||||
= note: the trait cannot be made into an object because it requires `Self: Sized`
|
||||
= note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
help: there is an associated type with the same name
|
||||
|
|
||||
LL | fn foo() -> Self::Clone;
|
||||
| ++++++
|
||||
|
||||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/issue-116434-2015.rs:15:20
|
||||
--> $DIR/issue-116434-2015.rs:18:20
|
||||
|
|
||||
LL | fn handle() -> DbHandle;
|
||||
| ^^^^^^^^
|
||||
@ -63,18 +67,22 @@ LL | fn handle() -> dyn DbHandle;
|
||||
| +++
|
||||
|
||||
error[E0038]: the trait `DbHandle` cannot be made into an object
|
||||
--> $DIR/issue-116434-2015.rs:15:20
|
||||
--> $DIR/issue-116434-2015.rs:18:20
|
||||
|
|
||||
LL | fn handle() -> DbHandle;
|
||||
| ^^^^^^^^ `DbHandle` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/issue-116434-2015.rs:11:17
|
||||
--> $DIR/issue-116434-2015.rs:14:17
|
||||
|
|
||||
LL | trait DbHandle: Sized {}
|
||||
| -------- ^^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait cannot be made into an object...
|
||||
help: there is an associated type with the same name
|
||||
|
|
||||
LL | fn handle() -> Self::DbHandle;
|
||||
| ++++++
|
||||
|
||||
error: aborting due to 2 previous errors; 4 warnings emitted
|
||||
|
||||
|
@ -4,6 +4,7 @@ trait Foo {
|
||||
type Clone;
|
||||
fn foo() -> Clone;
|
||||
//~^ ERROR the trait `Clone` cannot be made into an object [E0038]
|
||||
//~| HELP there is an associated type with the same name
|
||||
}
|
||||
|
||||
trait DbHandle: Sized {}
|
||||
@ -12,6 +13,7 @@ trait DbInterface {
|
||||
type DbHandle;
|
||||
fn handle() -> DbHandle;
|
||||
//~^ ERROR the trait `DbHandle` cannot be made into an object [E0038]
|
||||
//~| HELP there is an associated type with the same name
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -6,20 +6,28 @@ LL | fn foo() -> Clone;
|
||||
|
|
||||
= note: the trait cannot be made into an object because it requires `Self: Sized`
|
||||
= note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
help: there is an associated type with the same name
|
||||
|
|
||||
LL | fn foo() -> Self::Clone;
|
||||
| ++++++
|
||||
|
||||
error[E0038]: the trait `DbHandle` cannot be made into an object
|
||||
--> $DIR/issue-116434-2021.rs:13:20
|
||||
--> $DIR/issue-116434-2021.rs:14:20
|
||||
|
|
||||
LL | fn handle() -> DbHandle;
|
||||
| ^^^^^^^^ `DbHandle` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/issue-116434-2021.rs:9:17
|
||||
--> $DIR/issue-116434-2021.rs:10:17
|
||||
|
|
||||
LL | trait DbHandle: Sized {}
|
||||
| -------- ^^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait cannot be made into an object...
|
||||
help: there is an associated type with the same name
|
||||
|
|
||||
LL | fn handle() -> Self::DbHandle;
|
||||
| ++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user