]> git.lizzy.rs Git - rust.git/commitdiff
Differentiate between tuple structs and tuple variants
authorEsteban Küber <esteban@kuber.com.ar>
Thu, 8 Aug 2019 21:59:24 +0000 (14:59 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Fri, 9 Aug 2019 14:18:05 +0000 (07:18 -0700)
src/librustc/hir/map/mod.rs
src/librustc_typeck/check/mod.rs
src/test/ui/resolve/privacy-enum-ctor.stderr
src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs
src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr

index 0d477ae79682285628ad01c08e9424152f849af7..b85738dd29a6d835255235d06e60be19bbb6341f 100644 (file)
@@ -287,7 +287,7 @@ pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
         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 {
index 726922c8e5346b573fdef97b01053c7941526657..629b8da355e2354a30a7c37a8f79dd4f673f8deb 100644 (file)
@@ -3839,6 +3839,7 @@ fn suggest_fn_call(
             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 @@ fn suggest_fn_call(
             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";
+                            }
+                            _ => {}
+                        }
                     }
                     _ => {}
                 }
index 49092562feebaf67f0d1e4a9725629e473c6e9bd..3e924f7d161bd05824a5b19b115eeb30ea11969e 100644 (file)
@@ -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}`
index 6758c1d5f238e4fea568a2b5ee628ba0c070765f..838ef78e4fd6a2a9de496a24adfeaf63ea7586ae 100644 (file)
@@ -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`
 }
index 524c779979e3b456fdc418ccb51e6dc6d876afcf..cb128822fcce860fc2a6f3ab1188e76fe62e7edc 100644 (file)
@@ -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}`
+
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0423.
+For more information about an error, try `rustc --explain E0308`.