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
This commit is contained in:
Jonathan Turner 2016-08-27 12:43:31 -07:00 committed by GitHub
commit d00a89a9ff
2 changed files with 32 additions and 9 deletions

View File

@ -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();
}
}
}

View File

@ -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
}