Suggest to replace tuple constructor through projection · rust-lang/rust@304ccf4 (original) (raw)
File tree
4 files changed
lines changed
- compiler/rustc_hir_typeck/src/method
- tests/ui/associated-types
4 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -14,7 +14,7 @@ use rustc_data_structures::sorted_map::SortedMap; | ||
14 | 14 | use rustc_data_structures::unord::UnordSet; |
15 | 15 | use rustc_errors::codes::*; |
16 | 16 | use rustc_errors::{Applicability, Diag, MultiSpan, StashKey, pluralize, struct_span_code_err}; |
17 | -use rustc_hir::def::DefKind; | |
17 | +use rustc_hir::def::{CtorKind, DefKind, Res}; | |
18 | 18 | use rustc_hir::def_id::DefId; |
19 | 19 | use rustc_hir::intravisit::{self, Visitor}; |
20 | 20 | use rustc_hir::lang_items::LangItem; |
@@ -690,6 +690,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ||
690 | 690 | ); |
691 | 691 | } |
692 | 692 | |
693 | +// Check if we wrote `Self::Assoc(1)` as if it were a tuple ctor. | |
694 | +if let SelfSource::QPath(ty) = source | |
695 | + && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind | |
696 | + && let Res::SelfTyAlias { alias_to: impl_def_id, .. } = path.res | |
697 | + && let DefKind::Impl { .. } = self.tcx.def_kind(impl_def_id) | |
698 | + && let Some(candidate) = tcx.associated_items(impl_def_id).find_by_name_and_kind( | |
699 | +self.tcx, | |
700 | + item_name, | |
701 | + ty::AssocKind::Type, | |
702 | + impl_def_id, | |
703 | +) | |
704 | + && let Some(adt_def) = tcx.type_of(candidate.def_id).skip_binder().ty_adt_def() | |
705 | + && adt_def.is_struct() | |
706 | + && adt_def.non_enum_variant().ctor_kind() == Some(CtorKind::Fn) | |
707 | +{ | |
708 | +let def_path = tcx.def_path_str(adt_def.did()); | |
709 | + err.span_suggestion( | |
710 | + ty.span.to(item_name.span), | |
711 | +format!("to construct a value of type `{}`, use the explicit path", def_path), | |
712 | + def_path, | |
713 | +Applicability::MachineApplicable, | |
714 | +); | |
715 | +} | |
716 | + | |
693 | 717 | err |
694 | 718 | }; |
695 | 719 | if tcx.sess.source_map().is_multiline(sugg_span) { |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
1 | +//@ run-rustfix | |
2 | + | |
3 | +#![allow(unused)] | |
4 | + | |
5 | +struct Constructor(i32); | |
6 | + | |
7 | +trait Trait { | |
8 | + type Out; | |
9 | + | |
10 | + fn mk() -> Self::Out; | |
11 | +} | |
12 | + | |
13 | +impl Trait for () { | |
14 | + type Out = Constructor; | |
15 | + | |
16 | + fn mk() -> Self::Out { | |
17 | + Constructor(1) | |
18 | + //~^ ERROR no associated item named `Out` found for unit type `()` | |
19 | + } | |
20 | +} | |
21 | + | |
22 | +fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
1 | +//@ run-rustfix | |
2 | + | |
3 | +#![allow(unused)] | |
4 | + | |
5 | +struct Constructor(i32); | |
6 | + | |
7 | +trait Trait { | |
8 | +type Out; | |
9 | + | |
10 | +fn mk() -> Self::Out; | |
11 | +} | |
12 | + | |
13 | +impl Trait for () { | |
14 | +type Out = Constructor; | |
15 | + | |
16 | +fn mk() -> Self::Out { | |
17 | +Self::Out(1) | |
18 | +//~^ ERROR no associated item named `Out` found for unit type `()` | |
19 | +} | |
20 | +} | |
21 | + | |
22 | +fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
1 | +error[E0599]: no associated item named `Out` found for unit type `()` in the current scope | |
2 | + --> $DIR/invalid-ctor.rs:17:15 | |
3 | + | | |
4 | +LL | Self::Out(1) | |
5 | + | ^^^ associated item not found in `()` | |
6 | + | | |
7 | +help: to construct a value of type `Constructor`, use the explicit path | |
8 | + | | |
9 | +LL | Constructor(1) | |
10 | + | ~~~~~~~~~~~ | |
11 | + | |
12 | +error: aborting due to 1 previous error | |
13 | + | |
14 | +For more information about this error, try `rustc --explain E0599`. |