about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonathan Turner <jonathandturner@users.noreply.github.com>2016-08-27 12:43:31 -0700
committerGitHub <noreply@github.com>2016-08-27 12:43:31 -0700
commitd00a89a9ff66447f769288a2e05132e1fd2b331a (patch)
treee1d9dd3c908e1121806b25945f8ab1055a9ffb87
parent3bab26e6f3fabdd9f5c3b855047fdad2179f4334 (diff)
parent9c07ed21282fa0710580d589c6ba468ae12455df (diff)
downloadrust-d00a89a9ff66447f769288a2e05132e1fd2b331a.tar.gz
rust-d00a89a9ff66447f769288a2e05132e1fd2b331a.zip
Rollup merge of #36044 - mikhail-m1:master, r=jonathandturner
update error E0450 to new format

Fixes #35925 as part of #35233.

I've solve the bonus, and I wonder if any simpler way to do this. But may be possible simplify if let expressions?

r? @jonathandturner
-rw-r--r--src/librustc_privacy/lib.rs33
-rw-r--r--src/test/compile-fail/E0450.rs8
2 files changed, 32 insertions, 9 deletions
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 028632ad7c0..6da901a5f86 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -444,13 +444,32 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
                         }), ..}) => ty,
                         _ => expr_ty
                     }.ty_adt_def().unwrap();
-                    let any_priv = def.struct_variant().fields.iter().any(|f| {
-                        !f.vis.is_accessible_from(self.curitem, &self.tcx.map)
-                    });
-                    if any_priv {
-                        span_err!(self.tcx.sess, expr.span, E0450,
-                                  "cannot invoke tuple struct constructor with private \
-                                   fields");
+
+                    let private_indexes : Vec<_> = def.struct_variant().fields.iter().enumerate()
+                        .filter(|&(_,f)| {
+                            !f.vis.is_accessible_from(self.curitem, &self.tcx.map)
+                    }).map(|(n,&_)|n).collect();
+
+                    if !private_indexes.is_empty() {
+
+                        let mut error = struct_span_err!(self.tcx.sess, expr.span, E0450,
+                                                         "cannot invoke tuple struct constructor \
+                                                         with private fields");
+                        error.span_label(expr.span,
+                                         &format!("cannot construct with a private field"));
+
+                        if let Some(def_id) = self.tcx.map.as_local_node_id(def.did) {
+                            if let Some(hir::map::NodeItem(node)) = self.tcx.map.find(def_id) {
+                                if let hir::Item_::ItemStruct(ref tuple_data, _) = node.node {
+
+                                    for i in private_indexes {
+                                        error.span_label(tuple_data.fields()[i].span,
+                                                         &format!("private field declared here"));
+                                    }
+                                }
+                            }
+                        }
+                        error.emit();
                     }
                 }
             }
diff --git a/src/test/compile-fail/E0450.rs b/src/test/compile-fail/E0450.rs
index 3d76cb93773..200b58a3293 100644
--- a/src/test/compile-fail/E0450.rs
+++ b/src/test/compile-fail/E0450.rs
@@ -9,9 +9,13 @@
 // except according to those terms.
 
 mod Bar {
-    pub struct Foo(isize);
+    pub struct Foo( bool, pub i32, f32, bool);
+    //~^ NOTE private field declared here
+    //~| NOTE private field declared here
+    //~| NOTE private field declared here
 }
 
 fn main() {
-    let f = Bar::Foo(0); //~ ERROR E0450
+    let f = Bar::Foo(false,1,0.1, true); //~ ERROR E0450
+                         //~^ NOTE cannot construct with a private field
 }