Differentiate between tuple structs and tuple variants
This commit is contained in:
parent
efa62d66e3
commit
52da091ee6
5 changed files with 62 additions and 22 deletions
|
@ -287,7 +287,7 @@ impl<'hir> Map<'hir> {
|
|||
self.definitions.def_index_to_hir_id(def_id.to_def_id().index)
|
||||
}
|
||||
|
||||
fn def_kind(&self, hir_id: HirId) -> Option<DefKind> {
|
||||
pub fn def_kind(&self, hir_id: HirId) -> Option<DefKind> {
|
||||
let node = if let Some(node) = self.find(hir_id) {
|
||||
node
|
||||
} else {
|
||||
|
|
|
@ -3839,6 +3839,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ty::FnDef(..) | ty::FnPtr(_) => {}
|
||||
_ => return false,
|
||||
}
|
||||
let hir = self.tcx.hir();
|
||||
|
||||
let sig = found.fn_sig(self.tcx);
|
||||
let sig = self
|
||||
|
@ -3849,25 +3850,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
|
||||
(String::new(), Applicability::MachineApplicable)
|
||||
} else {
|
||||
("...".to_owned(), Applicability::HasPlaceholders)
|
||||
("...".to_string(), Applicability::HasPlaceholders)
|
||||
};
|
||||
let mut msg = "call this function";
|
||||
if let ty::FnDef(def_id, ..) = found.sty {
|
||||
match self.tcx.hir().get_if_local(def_id) {
|
||||
match hir.get_if_local(def_id) {
|
||||
Some(Node::Item(hir::Item {
|
||||
node: ItemKind::Fn(.., body_id),
|
||||
..
|
||||
})) => {
|
||||
let body = self.tcx.hir().body(*body_id);
|
||||
let body = hir.body(*body_id);
|
||||
sugg_call = body.arguments.iter()
|
||||
.map(|arg| hir::print::to_string(
|
||||
hir::print::NO_ANN,
|
||||
|s| s.print_pat(&arg.pat),
|
||||
)).collect::<Vec<_>>().join(", ");
|
||||
.map(|arg| match &arg.pat.node {
|
||||
hir::PatKind::Binding(_, _, ident, None) => ident.to_string(),
|
||||
_ => "_".to_string(),
|
||||
}).collect::<Vec<_>>().join(", ");
|
||||
}
|
||||
Some(Node::Ctor(hir::VariantData::Tuple(field, _))) => {
|
||||
sugg_call = field.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
|
||||
msg = "instatiate this tuple struct";
|
||||
Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
|
||||
sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
|
||||
match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
|
||||
Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
|
||||
msg = "instatiate this tuple variant";
|
||||
}
|
||||
Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
|
||||
msg = "instatiate this tuple struct";
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ LL | let _: Z = Z::Fn;
|
|||
| ^^^^^
|
||||
| |
|
||||
| expected enum `m::n::Z`, found fn item
|
||||
| help: use parentheses to instatiate this tuple struct: `Z::Fn(_)`
|
||||
| help: use parentheses to instatiate this tuple variant: `Z::Fn(_)`
|
||||
|
|
||||
= note: expected type `m::n::Z`
|
||||
found type `fn(u8) -> m::n::Z {m::n::Z::Fn}`
|
||||
|
@ -232,7 +232,7 @@ LL | let _: E = m::E::Fn;
|
|||
| ^^^^^^^^
|
||||
| |
|
||||
| expected enum `m::E`, found fn item
|
||||
| help: use parentheses to instatiate this tuple struct: `m::E::Fn(_)`
|
||||
| help: use parentheses to instatiate this tuple variant: `m::E::Fn(_)`
|
||||
|
|
||||
= note: expected type `m::E`
|
||||
found type `fn(u8) -> m::E {m::E::Fn}`
|
||||
|
@ -262,7 +262,7 @@ LL | let _: E = E::Fn;
|
|||
| ^^^^^
|
||||
| |
|
||||
| expected enum `m::E`, found fn item
|
||||
| help: use parentheses to instatiate this tuple struct: `E::Fn(_)`
|
||||
| help: use parentheses to instatiate this tuple variant: `E::Fn(_)`
|
||||
|
|
||||
= note: expected type `m::E`
|
||||
found type `fn(u8) -> m::E {m::E::Fn}`
|
||||
|
|
|
@ -3,6 +3,10 @@ fn foo(a: usize, b: usize) -> usize { a }
|
|||
fn bar() -> usize { 42 }
|
||||
|
||||
struct S(usize, usize);
|
||||
enum E {
|
||||
A(usize),
|
||||
B { a: usize },
|
||||
}
|
||||
struct V();
|
||||
|
||||
trait T {
|
||||
|
@ -17,4 +21,6 @@ fn main() {
|
|||
let _: V = V; //~ ERROR mismatched types
|
||||
let _: usize = T::baz; //~ ERROR mismatched types
|
||||
let _: usize = T::bat; //~ ERROR mismatched types
|
||||
let _: E = E::A; //~ ERROR mismatched types
|
||||
let _: E = E::B; //~ ERROR expected value, found struct variant `E::B`
|
||||
}
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
error[E0423]: expected value, found struct variant `E::B`
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:25:16
|
||||
|
|
||||
LL | let _: E = E::B;
|
||||
| ^^^-
|
||||
| | |
|
||||
| | help: a tuple variant with a similar name exists: `A`
|
||||
| did you mean `E::B { /* fields */ }`?
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:14:20
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:18:20
|
||||
|
|
||||
LL | fn foo(a: usize, b: usize) -> usize { a }
|
||||
| ----------------------------------- fn(usize, usize) -> usize {foo} defined here
|
||||
|
@ -14,7 +23,7 @@ LL | let _: usize = foo;
|
|||
found type `fn(usize, usize) -> usize {foo}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:15:16
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:19:16
|
||||
|
|
||||
LL | struct S(usize, usize);
|
||||
| ----------------------- fn(usize, usize) -> S {S} defined here
|
||||
|
@ -29,7 +38,7 @@ LL | let _: S = S;
|
|||
found type `fn(usize, usize) -> S {S}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:16:20
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:20:20
|
||||
|
|
||||
LL | fn bar() -> usize { 42 }
|
||||
| ----------------- fn() -> usize {bar} defined here
|
||||
|
@ -44,7 +53,7 @@ LL | let _: usize = bar;
|
|||
found type `fn() -> usize {bar}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:17:16
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:21:16
|
||||
|
|
||||
LL | struct V();
|
||||
| ----------- fn() -> V {V} defined here
|
||||
|
@ -59,7 +68,7 @@ LL | let _: V = V;
|
|||
found type `fn() -> V {V}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:18:20
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:22:20
|
||||
|
|
||||
LL | fn baz(x: usize, y: usize) -> usize { x }
|
||||
| ----------------------------------- fn(usize, usize) -> usize {<_ as T>::baz} defined here
|
||||
|
@ -74,7 +83,7 @@ LL | let _: usize = T::baz;
|
|||
found type `fn(usize, usize) -> usize {<_ as T>::baz}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:19:20
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:23:20
|
||||
|
|
||||
LL | fn bat() -> usize { 42 }
|
||||
| ----------------- fn() -> usize {<_ as T>::bat} defined here
|
||||
|
@ -88,6 +97,22 @@ LL | let _: usize = T::bat;
|
|||
= note: expected type `usize`
|
||||
found type `fn() -> usize {<_ as T>::bat}`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:24:16
|
||||
|
|
||||
LL | A(usize),
|
||||
| -------- fn(usize) -> E {E::A} defined here
|
||||
...
|
||||
LL | let _: E = E::A;
|
||||
| ^^^^
|
||||
| |
|
||||
| expected enum `E`, found fn item
|
||||
| help: use parentheses to instatiate this tuple variant: `E::A(_)`
|
||||
|
|
||||
= note: expected type `E`
|
||||
found type `fn(usize) -> E {E::A}`
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0423.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
|
Loading…
Reference in a new issue