Suggest to replace tuple constructor through projection
This commit is contained in:
parent
243d2ca4db
commit
304ccf45d1
4 changed files with 83 additions and 1 deletions
|
@ -14,7 +14,7 @@ use rustc_data_structures::sorted_map::SortedMap;
|
|||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Applicability, Diag, MultiSpan, StashKey, pluralize, struct_span_code_err};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
|
@ -690,6 +690,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
// Check if we wrote `Self::Assoc(1)` as if it were a tuple ctor.
|
||||
if let SelfSource::QPath(ty) = source
|
||||
&& let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
|
||||
&& let Res::SelfTyAlias { alias_to: impl_def_id, .. } = path.res
|
||||
&& let DefKind::Impl { .. } = self.tcx.def_kind(impl_def_id)
|
||||
&& let Some(candidate) = tcx.associated_items(impl_def_id).find_by_name_and_kind(
|
||||
self.tcx,
|
||||
item_name,
|
||||
ty::AssocKind::Type,
|
||||
impl_def_id,
|
||||
)
|
||||
&& let Some(adt_def) = tcx.type_of(candidate.def_id).skip_binder().ty_adt_def()
|
||||
&& adt_def.is_struct()
|
||||
&& adt_def.non_enum_variant().ctor_kind() == Some(CtorKind::Fn)
|
||||
{
|
||||
let def_path = tcx.def_path_str(adt_def.did());
|
||||
err.span_suggestion(
|
||||
ty.span.to(item_name.span),
|
||||
format!("to construct a value of type `{}`, use the explicit path", def_path),
|
||||
def_path,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
||||
err
|
||||
};
|
||||
if tcx.sess.source_map().is_multiline(sugg_span) {
|
||||
|
|
22
tests/ui/associated-types/invalid-ctor.fixed
Normal file
22
tests/ui/associated-types/invalid-ctor.fixed
Normal file
|
@ -0,0 +1,22 @@
|
|||
//@ run-rustfix
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
struct Constructor(i32);
|
||||
|
||||
trait Trait {
|
||||
type Out;
|
||||
|
||||
fn mk() -> Self::Out;
|
||||
}
|
||||
|
||||
impl Trait for () {
|
||||
type Out = Constructor;
|
||||
|
||||
fn mk() -> Self::Out {
|
||||
Constructor(1)
|
||||
//~^ ERROR no associated item named `Out` found for unit type `()`
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
22
tests/ui/associated-types/invalid-ctor.rs
Normal file
22
tests/ui/associated-types/invalid-ctor.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
//@ run-rustfix
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
struct Constructor(i32);
|
||||
|
||||
trait Trait {
|
||||
type Out;
|
||||
|
||||
fn mk() -> Self::Out;
|
||||
}
|
||||
|
||||
impl Trait for () {
|
||||
type Out = Constructor;
|
||||
|
||||
fn mk() -> Self::Out {
|
||||
Self::Out(1)
|
||||
//~^ ERROR no associated item named `Out` found for unit type `()`
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
14
tests/ui/associated-types/invalid-ctor.stderr
Normal file
14
tests/ui/associated-types/invalid-ctor.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
error[E0599]: no associated item named `Out` found for unit type `()` in the current scope
|
||||
--> $DIR/invalid-ctor.rs:17:15
|
||||
|
|
||||
LL | Self::Out(1)
|
||||
| ^^^ associated item not found in `()`
|
||||
|
|
||||
help: to construct a value of type `Constructor`, use the explicit path
|
||||
|
|
||||
LL | Constructor(1)
|
||||
| ~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Add table
Add a link
Reference in a new issue