about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-01-01 15:29:50 -0800
committerEsteban Küber <esteban@kuber.com.ar>2018-01-15 02:03:02 -0800
commita317da42b16ffe4d06c12ab795aef3cbc0859de9 (patch)
treec097b895aded169357274f452c8e3b21731e2b6d
parent9bab0f09d30c90126993fa824171925a8fa579a7 (diff)
downloadrust-a317da42b16ffe4d06c12ab795aef3cbc0859de9.tar.gz
rust-a317da42b16ffe4d06c12ab795aef3cbc0859de9.zip
Suggest the correct syntax for different struct types
-rw-r--r--src/librustc_resolve/lib.rs34
-rw-r--r--src/test/ui/resolve/issue-18252.stderr2
-rw-r--r--src/test/ui/resolve/issue-19452.stderr4
-rw-r--r--src/test/ui/resolve/privacy-struct-ctor.rs7
-rw-r--r--src/test/ui/resolve/privacy-struct-ctor.stderr46
-rw-r--r--src/test/ui/resolve/tuple-struct-alias.stderr14
6 files changed, 62 insertions, 45 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index d67578e8c06..29ca160fac0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2702,19 +2702,29 @@ impl<'a> Resolver<'a> {
                         }
                         return (err, candidates);
                     },
-                    _ if ns == ValueNS && is_struct_like(def) => {
-                        let mut accessible_ctor = true;
-                        if let Def::Struct(def_id) = def {
-                            if let Some((ctor_def, ctor_vis))
-                                    = this.struct_constructors.get(&def_id).cloned() {
-                                accessible_ctor = this.is_accessible(ctor_vis);
-                                if is_expected(ctor_def) && !accessible_ctor {
-                                    err.span_label(span, format!("constructor is not visible \
-                                                                   here due to private fields"));
-                                }
+                    (Def::Struct(def_id), _) if ns == ValueNS && is_struct_like(def) => {
+                        if let Some((ctor_def, ctor_vis))
+                                = this.struct_constructors.get(&def_id).cloned() {
+                            let accessible_ctor = this.is_accessible(ctor_vis);
+                            if is_expected(ctor_def) && !accessible_ctor {
+                                err.span_label(span, format!("constructor is not visible \
+                                                              here due to private fields"));
+                            } else if accessible_ctor {
+                                let block = match ctor_def {
+                                    Def::StructCtor(_, CtorKind::Fn) |
+                                    Def::VariantCtor(_, CtorKind::Fn) => "(/* fields */)",
+                                    Def::StructCtor(_, CtorKind::Fictive) |
+                                    Def::VariantCtor(_, CtorKind::Fictive) => {
+                                        " { /* fields */ }"
+                                    }
+                                    def => bug!("found def `{:?}` when looking for a ctor",
+                                                def),
+                                };
+                                err.span_label(span, format!("did you mean `{}{}`?",
+                                                             path_str,
+                                                             block));
                             }
-                        }
-                        if accessible_ctor {
+                        } else {
                             err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
                                                          path_str));
                         }
diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr
index edc7196d846..f93007c8b61 100644
--- a/src/test/ui/resolve/issue-18252.stderr
+++ b/src/test/ui/resolve/issue-18252.stderr
@@ -2,7 +2,7 @@ error[E0423]: expected function, found struct variant `Foo::Variant`
   --> $DIR/issue-18252.rs:16:13
    |
 16 |     let f = Foo::Variant(42);
-   |             ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`?
+   |             ^^^^^^^^^^^^ not a function
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr
index 7b14d49af51..44690158b58 100644
--- a/src/test/ui/resolve/issue-19452.stderr
+++ b/src/test/ui/resolve/issue-19452.stderr
@@ -2,13 +2,13 @@ error[E0423]: expected value, found struct variant `Homura::Madoka`
   --> $DIR/issue-19452.rs:19:18
    |
 19 |     let homura = Homura::Madoka;
-   |                  ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`?
+   |                  ^^^^^^^^^^^^^^ not a value
 
 error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka`
   --> $DIR/issue-19452.rs:22:18
    |
 22 |     let homura = issue_19452_aux::Homura::Madoka;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`?
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a value
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/resolve/privacy-struct-ctor.rs b/src/test/ui/resolve/privacy-struct-ctor.rs
index eb6edae7381..821a51e9427 100644
--- a/src/test/ui/resolve/privacy-struct-ctor.rs
+++ b/src/test/ui/resolve/privacy-struct-ctor.rs
@@ -14,6 +14,9 @@ extern crate privacy_struct_ctor as xcrate;
 
 mod m {
     pub struct S(u8);
+    pub struct S2 {
+        s: u8
+    }
 
     pub mod n {
         pub(in m) struct Z(pub(in m::n) u8);
@@ -29,6 +32,7 @@ mod m {
 }
 
 use m::S; // OK, only the type is imported
+use m::S2; // OK, only the type is imported
 
 fn main() {
     m::S; //~ ERROR tuple struct `S` is private
@@ -36,6 +40,9 @@ fn main() {
     //~^ ERROR expected value, found struct `S`
     m::n::Z; //~ ERROR tuple struct `Z` is private
 
+    S2;
+    //~^ ERROR expected value, found struct `S2`
+
     xcrate::m::S; //~ ERROR tuple struct `S` is private
     xcrate::S;
     //~^ ERROR expected value, found struct `xcrate::S`
diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr
index b688d2fc95b..e274ac02c57 100644
--- a/src/test/ui/resolve/privacy-struct-ctor.stderr
+++ b/src/test/ui/resolve/privacy-struct-ctor.stderr
@@ -1,65 +1,71 @@
 error[E0423]: expected value, found struct `Z`
-  --> $DIR/privacy-struct-ctor.rs:26:9
+  --> $DIR/privacy-struct-ctor.rs:29:9
    |
-26 |         Z;
+29 |         Z;
    |         ^
    |         |
    |         did you mean `S`?
    |         constructor is not visible here due to private fields
 help: possible better candidate is found in another module, you can import it into scope
    |
-22 |     use m::n::Z;
+25 |     use m::n::Z;
    |
 
 error[E0423]: expected value, found struct `S`
-  --> $DIR/privacy-struct-ctor.rs:35:5
+  --> $DIR/privacy-struct-ctor.rs:39:5
    |
-35 |     S;
+39 |     S;
    |     ^ constructor is not visible here due to private fields
 help: possible better candidate is found in another module, you can import it into scope
    |
-31 | use m::S;
+34 | use m::S;
+   |
+
+error[E0423]: expected value, found struct `S2`
+  --> $DIR/privacy-struct-ctor.rs:43:5
    |
+43 |     S2;
+   |     ^^ did you mean `S2 { /* fields */ }`?
 
 error[E0423]: expected value, found struct `xcrate::S`
-  --> $DIR/privacy-struct-ctor.rs:40:5
+  --> $DIR/privacy-struct-ctor.rs:47:5
    |
-40 |     xcrate::S;
+47 |     xcrate::S;
    |     ^^^^^^^^^ constructor is not visible here due to private fields
 help: possible better candidate is found in another module, you can import it into scope
    |
-31 | use m::S;
+34 | use m::S;
    |
 
 error[E0603]: tuple struct `Z` is private
-  --> $DIR/privacy-struct-ctor.rs:25:9
+  --> $DIR/privacy-struct-ctor.rs:28:9
    |
-25 |         n::Z; //~ ERROR tuple struct `Z` is private
+28 |         n::Z; //~ ERROR tuple struct `Z` is private
    |         ^^^^
 
 error[E0603]: tuple struct `S` is private
-  --> $DIR/privacy-struct-ctor.rs:34:5
+  --> $DIR/privacy-struct-ctor.rs:38:5
    |
-34 |     m::S; //~ ERROR tuple struct `S` is private
+38 |     m::S; //~ ERROR tuple struct `S` is private
    |     ^^^^
 
 error[E0603]: tuple struct `Z` is private
-  --> $DIR/privacy-struct-ctor.rs:37:5
+  --> $DIR/privacy-struct-ctor.rs:41:5
    |
-37 |     m::n::Z; //~ ERROR tuple struct `Z` is private
+41 |     m::n::Z; //~ ERROR tuple struct `Z` is private
    |     ^^^^^^^
 
 error[E0603]: tuple struct `S` is private
-  --> $DIR/privacy-struct-ctor.rs:39:5
+  --> $DIR/privacy-struct-ctor.rs:46:5
    |
-39 |     xcrate::m::S; //~ ERROR tuple struct `S` is private
+46 |     xcrate::m::S; //~ ERROR tuple struct `S` is private
    |     ^^^^^^^^^^^^
 
 error[E0603]: tuple struct `Z` is private
-  --> $DIR/privacy-struct-ctor.rs:42:5
+  --> $DIR/privacy-struct-ctor.rs:49:5
    |
-42 |     xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
+49 |     xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
    |     ^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr
index aea9fc356bf..3b89c87b36f 100644
--- a/src/test/ui/resolve/tuple-struct-alias.stderr
+++ b/src/test/ui/resolve/tuple-struct-alias.stderr
@@ -2,31 +2,25 @@ error[E0423]: expected function, found self type `Self`
   --> $DIR/tuple-struct-alias.rs:16:17
    |
 16 |         let s = Self(0, 1); //~ ERROR expected function
-   |                 ^^^^ did you mean `Self { /* fields */ }`?
+   |                 ^^^^ not a function
 
 error[E0532]: expected tuple struct/variant, found self type `Self`
   --> $DIR/tuple-struct-alias.rs:18:13
    |
 18 |             Self(..) => {} //~ ERROR expected tuple struct/variant
-   |             ^^^^ did you mean `Self { /* fields */ }`?
+   |             ^^^^ not a tuple struct/variant
 
 error[E0423]: expected function, found type alias `A`
   --> $DIR/tuple-struct-alias.rs:24:13
    |
 24 |     let s = A(0, 1); //~ ERROR expected function
-   |             ^
-   |             |
-   |             did you mean `S`?
-   |             did you mean `A { /* fields */ }`?
+   |             ^ did you mean `S`?
 
 error[E0532]: expected tuple struct/variant, found type alias `A`
   --> $DIR/tuple-struct-alias.rs:26:9
    |
 26 |         A(..) => {} //~ ERROR expected tuple struct/variant
-   |         ^
-   |         |
-   |         did you mean `S`?
-   |         did you mean `A { /* fields */ }`?
+   |         ^ did you mean `S`?
 
 error: aborting due to 4 previous errors