"detects names that resolve to ambiguous glob imports with RFC 1560"
}
+declare_lint! {
+ pub LEGACY_CONSTRUCTOR_VISIBILITY,
+ Deny,
+ "detects use of struct constructors that would be invisible with new visibility rules"
+}
+
declare_lint! {
pub DEPRECATED,
Warn,
EXTRA_REQUIREMENT_IN_IMPL,
LEGACY_DIRECTORY_OWNERSHIP,
LEGACY_IMPORTS,
+ LEGACY_CONSTRUCTOR_VISIBILITY,
DEPRECATED
)
}
id: LintId::of(LEGACY_IMPORTS),
reference: "issue #38260 <https://github.com/rust-lang/rust/issues/38260>",
},
+ FutureIncompatibleInfo {
+ id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY),
+ reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
+ },
]);
// Register renamed and removed lints
let struct_id = tcx.hir.as_local_node_id(adt_def_id).unwrap();
let struct_vis = &tcx.hir.expect_item(struct_id).vis;
+ let mut ctor_vis = ty::Visibility::from_hir(struct_vis, struct_id, tcx);
+ for field in &variant.fields {
+ if ctor_vis.is_at_least(field.vis, tcx) {
+ ctor_vis = field.vis;
+ }
+ }
Entry {
kind: EntryKind::Struct(self.lazy(&data)),
- visibility: self.lazy(&ty::Visibility::from_hir(struct_vis, struct_id, tcx)),
+ visibility: self.lazy(&ctor_vis),
span: self.lazy(&tcx.def_span(def_id)),
attributes: LazySeq::empty(),
children: LazySeq::empty(),
```
"##,
-E0450: r##"
-A tuple constructor was invoked while some of its fields are private. Erroneous
-code example:
-
-```compile_fail,E0450
-mod Bar {
- pub struct Foo(isize);
-}
-
-let f = Bar::Foo(0); // error: cannot invoke tuple struct constructor with
- // private fields
-```
-
-To solve this issue, please ensure that all of the fields of the tuple struct
-are public. Alternatively, provide a `new()` method to the tuple struct to
-construct it from a given inner value. Example:
-
-```
-mod Bar {
- pub struct Foo(pub isize); // we set its field to public
-}
-
-let f = Bar::Foo(0); // ok!
-
-// or:
-mod bar {
- pub struct Foo(isize);
-
- impl Foo {
- pub fn new(x: isize) -> Foo {
- Foo(x)
- }
- }
-}
-
-let f = bar::Foo::new(1);
-```
-"##,
-
E0451: r##"
A struct constructor with private fields was invoked. Erroneous code example:
"##,
}
+
+register_diagnostics! {
+// E0450, moved into resolve
+}
use rustc::dep_graph::DepNode;
use rustc::hir::{self, PatKind};
-use rustc::hir::def::{self, Def, CtorKind};
+use rustc::hir::def::{self, Def};
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::DeepVisitor;
}
}
}
- hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
- if let Def::StructCtor(_, CtorKind::Fn) = path.def {
- let adt_def = self.tcx.expect_variant_def(path.def);
- let private_indexes = adt_def.fields.iter().enumerate().filter(|&(_, field)| {
- !field.vis.is_accessible_from(self.curitem, self.tcx)
- }).map(|(i, _)| i).collect::<Vec<_>>();
-
- 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(node_id) = self.tcx.hir.as_local_node_id(adt_def.did) {
- let node = self.tcx.hir.find(node_id);
- if let Some(hir::map::NodeStructCtor(vdata)) = node {
- for i in private_indexes {
- error.span_label(vdata.fields()[i].span,
- &format!("private field declared here"));
- }
- }
- }
- error.emit();
- }
- }
- }
_ => {}
}
let def = Def::Struct(self.definitions.local_def_id(item.id));
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
- // If this is a tuple or unit struct, define a name
- // in the value namespace as well.
- if !struct_def.is_struct() {
- let ctor_def = Def::StructCtor(self.definitions.local_def_id(struct_def.id()),
- CtorKind::from_ast(struct_def));
- self.define(parent, ident, ValueNS, (ctor_def, vis, sp, expansion));
- }
-
// Record field names for error reporting.
+ let mut ctor_vis = vis;
let field_names = struct_def.fields().iter().filter_map(|field| {
- self.resolve_visibility(&field.vis);
+ let field_vis = self.resolve_visibility(&field.vis);
+ if ctor_vis.is_at_least(field_vis, &*self) {
+ ctor_vis = field_vis;
+ }
field.ident.map(|ident| ident.name)
}).collect();
let item_def_id = self.definitions.local_def_id(item.id);
self.insert_field_names(item_def_id, field_names);
+
+ // If this is a tuple or unit struct, define a name
+ // in the value namespace as well.
+ if !struct_def.is_struct() {
+ let ctor_def = Def::StructCtor(self.definitions.local_def_id(struct_def.id()),
+ CtorKind::from_ast(struct_def));
+ self.define(parent, ident, ValueNS, (ctor_def, ctor_vis, sp, expansion));
+ self.struct_constructors.insert(def.def_id(), (ctor_def, ctor_vis));
+ }
}
ItemKind::Union(ref vdata, _) => {
Def::Variant(..) | Def::TyAlias(..) => {
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
}
- Def::Fn(..) | Def::Static(..) | Def::Const(..) |
- Def::VariantCtor(..) | Def::StructCtor(..) => {
+ Def::Fn(..) | Def::Static(..) | Def::Const(..) | Def::VariantCtor(..) => {
+ self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
+ }
+ Def::StructCtor(..) => {
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
+
+ if let Some(struct_def_id) =
+ self.session.cstore.def_key(def_id).parent
+ .map(|index| DefId { krate: def_id.krate, index: index }) {
+ self.struct_constructors.insert(struct_def_id, (def, vis));
+ }
}
Def::Trait(..) => {
let module_kind = ModuleKind::Def(def, ident.name);
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
use rustc::ty;
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
-use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet};
+use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
use syntax::ext::hygiene::{Mark, SyntaxContext};
use syntax::ast::{self, Name, NodeId, Ident, SpannedIdent, FloatTy, IntTy, UintTy};
warned_proc_macros: FxHashSet<Name>,
potentially_unused_imports: Vec<&'a ImportDirective<'a>>,
+
+ // This table maps struct IDs into struct constructor IDs,
+ // it's not used during normal resolution, only for better error reporting.
+ struct_constructors: DefIdMap<(Def, ty::Visibility)>,
}
pub struct ResolverArenas<'a> {
proc_macro_enabled: features.proc_macro,
warned_proc_macros: FxHashSet(),
potentially_unused_imports: Vec::new(),
+ struct_constructors: DefIdMap(),
}
}
_ => {}
},
_ if ns == ValueNS && is_struct_like(def) => {
+ if let Def::Struct(def_id) = def {
+ if let Some((ctor_def, ctor_vis))
+ = this.struct_constructors.get(&def_id).cloned() {
+ if is_expected(ctor_def) && !this.is_accessible(ctor_vis) {
+ err.span_label(span, &format!("constructor is not visible \
+ here due to private fields"));
+ }
+ }
+ }
err.span_label(span, &format!("did you mean `{} {{ /* fields */ }}`?",
path_str));
return err;
if is_expected(resolution.base_def) || resolution.base_def == Def::Err {
resolution
} else {
- report_errors(self, Some(resolution.base_def))
+ // Add a temporary hack to smooth the transition to new struct ctor
+ // visibility rules. See #38932 for more details.
+ let mut res = None;
+ if let Def::Struct(def_id) = resolution.base_def {
+ if let Some((ctor_def, ctor_vis))
+ = self.struct_constructors.get(&def_id).cloned() {
+ if is_expected(ctor_def) && self.is_accessible(ctor_vis) {
+ let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
+ self.session.add_lint(lint, id, span,
+ "private struct constructors are not usable through \
+ reexports in outer modules".to_string());
+ res = Some(PathResolution::new(ctor_def));
+ }
+ }
+ }
+
+ res.unwrap_or_else(|| report_errors(self, Some(resolution.base_def)))
}
}
Some(resolution) if source.defer_to_typeck() => {
t("no_run", false, true, false, true, false, false, Vec::new());
t("test_harness", false, false, false, true, true, false, Vec::new());
t("compile_fail", false, true, false, true, false, true, Vec::new());
- t("E0450", false, false, false, true, false, false,
- vec!["E0450".to_owned()]);
t("{.no_run .example}", false, true, false, true, false, false, Vec::new());
t("{.sh .should_panic}", true, false, false, true, false, false, Vec::new());
t("{.example .rust}", false, false, false, true, false, false, Vec::new());
$(
#[allow(non_upper_case_globals)]
pub const $konst: Keyword = Keyword {
- ident: ast::Ident::with_empty_ctxt(ast::Name($index))
+ ident: ast::Ident::with_empty_ctxt(super::Symbol($index))
};
)*
}
#[cfg(test)]
mod tests {
use super::*;
- use ast::Name;
#[test]
fn interner_tests() {
let mut i: Interner = Interner::new();
// first one is zero:
- assert_eq!(i.intern("dog"), Name(0));
+ assert_eq!(i.intern("dog"), Symbol(0));
// re-use gets the same entry:
- assert_eq!(i.intern ("dog"), Name(0));
+ assert_eq!(i.intern ("dog"), Symbol(0));
// different string gets a different #:
- assert_eq!(i.intern("cat"), Name(1));
- assert_eq!(i.intern("cat"), Name(1));
+ assert_eq!(i.intern("cat"), Symbol(1));
+ assert_eq!(i.intern("cat"), Symbol(1));
// dog is still at zero
- assert_eq!(i.intern("dog"), Name(0));
+ assert_eq!(i.intern("dog"), Symbol(0));
// gensym gets 3
- assert_eq!(i.gensym("zebra"), Name(2));
+ assert_eq!(i.gensym("zebra"), Symbol(2));
// gensym of same string gets new number :
- assert_eq!(i.gensym("zebra"), Name(3));
+ assert_eq!(i.gensym("zebra"), Symbol(3));
// gensym of *existing* string gets new number:
- assert_eq!(i.gensym("dog"), Name(4));
+ assert_eq!(i.gensym("dog"), Symbol(4));
}
}
fn main() {
// Okay
let Record { .. } = Record::new();
- // Okay (for now; see RFC Issue #902)
- let Tuple(..) = Tuple::new();
// Okay
let Record { a_stable_pub: _, a_unstable_declared_pub: _, .. } = Record::new();
- // Okay (for now; see RFC Issue #902)
- let Tuple(_, _, ..) = Tuple::new(); // analogous to above
let Record { a_stable_pub: _, a_unstable_declared_pub: _, a_unstable_undeclared_pub: _, .. } =
Record::new();
//~^^ ERROR use of unstable library feature 'unstable_undeclared'
- let Tuple(_, _, _, ..) = Tuple::new(); // analogous to previous
- //~^ ERROR use of unstable library feature 'unstable_undeclared'
-
let r = Record::new();
let t = Tuple::new();
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod Bar {
- 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(false,1,0.1, true); //~ ERROR E0450
- //~^ NOTE cannot construct with a private field
-}
//~^ NOTE field `b` is private
}
-fn pat_match_tuple(foo: Bar::FooTuple) {
- let Bar::FooTuple(a,b) = foo; //~ ERROR E0451
- //~^ NOTE field `1` is private
-}
-
fn main() {
let f = Bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451
//~^ NOTE field `b` is private
fn main() {
let Box(a) = loop { };
- //~^ ERROR field `0` of struct `std::boxed::Box` is private
+ //~^ ERROR expected tuple struct/variant, found struct `Box`
+ //~| ERROR expected tuple struct/variant, found struct `Box`
// (The below is a trick to allow compiler to infer a type for
// variable `a` without attempting to ascribe a type to the
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused)]
+
+use m::S;
+
+mod m {
+ pub struct S(u8);
+
+ mod n {
+ use S;
+ fn f() {
+ S(10);
+ //~^ ERROR private struct constructors are not usable through reexports in outer modules
+ //~| WARN this was previously accepted
+ }
+ }
+}
+
+fn main() {}
}
fn this_crate() {
- let a = a::A(()); //~ ERROR: cannot invoke tuple struct constructor
- let b = a::B(2); //~ ERROR: cannot invoke tuple struct constructor
- let c = a::C(2, 3); //~ ERROR: cannot invoke tuple struct constructor
+ let a = a::A(()); //~ ERROR tuple struct `A` is private
+ let b = a::B(2); //~ ERROR tuple struct `B` is private
+ let c = a::C(2, 3); //~ ERROR tuple struct `C` is private
let d = a::D(4);
- let a::A(()) = a; //~ ERROR: field `0` of struct `a::A` is private
- let a::A(_) = a;
- match a { a::A(()) => {} } //~ ERROR: field `0` of struct `a::A` is private
- match a { a::A(_) => {} }
-
- let a::B(_) = b;
- let a::B(_b) = b; //~ ERROR: field `0` of struct `a::B` is private
- match b { a::B(_) => {} }
- match b { a::B(_b) => {} } //~ ERROR: field `0` of struct `a::B` is private
- match b { a::B(1) => {} a::B(_) => {} } //~ ERROR: field `0` of struct `a::B` is private
-
- let a::C(_, _) = c;
- let a::C(_a, _) = c;
- let a::C(_, _b) = c; //~ ERROR: field `1` of struct `a::C` is private
- let a::C(_a, _b) = c; //~ ERROR: field `1` of struct `a::C` is private
- match c { a::C(_, _) => {} }
- match c { a::C(_a, _) => {} }
- match c { a::C(_, _b) => {} } //~ ERROR: field `1` of struct `a::C` is private
- match c { a::C(_a, _b) => {} } //~ ERROR: field `1` of struct `a::C` is private
+ let a::A(()) = a; //~ ERROR tuple struct `A` is private
+ let a::A(_) = a; //~ ERROR tuple struct `A` is private
+ match a { a::A(()) => {} } //~ ERROR tuple struct `A` is private
+ match a { a::A(_) => {} } //~ ERROR tuple struct `A` is private
+
+ let a::B(_) = b; //~ ERROR tuple struct `B` is private
+ let a::B(_b) = b; //~ ERROR tuple struct `B` is private
+ match b { a::B(_) => {} } //~ ERROR tuple struct `B` is private
+ match b { a::B(_b) => {} } //~ ERROR tuple struct `B` is private
+ match b { a::B(1) => {} a::B(_) => {} } //~ ERROR tuple struct `B` is private
+ //~^ ERROR tuple struct `B` is private
+
+ let a::C(_, _) = c; //~ ERROR tuple struct `C` is private
+ let a::C(_a, _) = c; //~ ERROR tuple struct `C` is private
+ let a::C(_, _b) = c; //~ ERROR tuple struct `C` is private
+ let a::C(_a, _b) = c; //~ ERROR tuple struct `C` is private
+ match c { a::C(_, _) => {} } //~ ERROR tuple struct `C` is private
+ match c { a::C(_a, _) => {} } //~ ERROR tuple struct `C` is private
+ match c { a::C(_, _b) => {} } //~ ERROR tuple struct `C` is private
+ match c { a::C(_a, _b) => {} } //~ ERROR tuple struct `C` is private
let a::D(_) = d;
let a::D(_d) = d;
match d { a::D(_d) => {} }
match d { a::D(1) => {} a::D(_) => {} }
- let a2 = a::A; //~ ERROR: cannot invoke tuple struct constructor
- let b2 = a::B; //~ ERROR: cannot invoke tuple struct constructor
- let c2 = a::C; //~ ERROR: cannot invoke tuple struct constructor
+ let a2 = a::A; //~ ERROR tuple struct `A` is private
+ let b2 = a::B; //~ ERROR tuple struct `B` is private
+ let c2 = a::C; //~ ERROR tuple struct `C` is private
let d2 = a::D;
}
fn xcrate() {
- let a = other::A(()); //~ ERROR: cannot invoke tuple struct constructor
- let b = other::B(2); //~ ERROR: cannot invoke tuple struct constructor
- let c = other::C(2, 3); //~ ERROR: cannot invoke tuple struct constructor
+ let a = other::A(()); //~ ERROR tuple struct `A` is private
+ let b = other::B(2); //~ ERROR tuple struct `B` is private
+ let c = other::C(2, 3); //~ ERROR tuple struct `C` is private
let d = other::D(4);
- let other::A(()) = a; //~ ERROR: field `0` of struct `other::A` is private
- let other::A(_) = a;
- match a { other::A(()) => {} }
- //~^ ERROR: field `0` of struct `other::A` is private
- match a { other::A(_) => {} }
-
- let other::B(_) = b;
- let other::B(_b) = b; //~ ERROR: field `0` of struct `other::B` is private
- match b { other::B(_) => {} }
- match b { other::B(_b) => {} }
- //~^ ERROR: field `0` of struct `other::B` is private
- match b { other::B(1) => {} other::B(_) => {} }
- //~^ ERROR: field `0` of struct `other::B` is private
-
- let other::C(_, _) = c;
- let other::C(_a, _) = c;
- let other::C(_, _b) = c; //~ ERROR: field `1` of struct `other::C` is private
- let other::C(_a, _b) = c; //~ ERROR: field `1` of struct `other::C` is private
- match c { other::C(_, _) => {} }
- match c { other::C(_a, _) => {} }
- match c { other::C(_, _b) => {} }
- //~^ ERROR: field `1` of struct `other::C` is private
- match c { other::C(_a, _b) => {} }
- //~^ ERROR: field `1` of struct `other::C` is private
+ let other::A(()) = a; //~ ERROR tuple struct `A` is private
+ let other::A(_) = a; //~ ERROR tuple struct `A` is private
+ match a { other::A(()) => {} } //~ ERROR tuple struct `A` is private
+ match a { other::A(_) => {} } //~ ERROR tuple struct `A` is private
+
+ let other::B(_) = b; //~ ERROR tuple struct `B` is private
+ let other::B(_b) = b; //~ ERROR tuple struct `B` is private
+ match b { other::B(_) => {} } //~ ERROR tuple struct `B` is private
+ match b { other::B(_b) => {} } //~ ERROR tuple struct `B` is private
+ match b { other::B(1) => {} other::B(_) => {} } //~ ERROR tuple struct `B` is private
+ //~^ ERROR tuple struct `B` is private
+
+ let other::C(_, _) = c; //~ ERROR tuple struct `C` is private
+ let other::C(_a, _) = c; //~ ERROR tuple struct `C` is private
+ let other::C(_, _b) = c; //~ ERROR tuple struct `C` is private
+ let other::C(_a, _b) = c; //~ ERROR tuple struct `C` is private
+ match c { other::C(_, _) => {} } //~ ERROR tuple struct `C` is private
+ match c { other::C(_a, _) => {} } //~ ERROR tuple struct `C` is private
+ match c { other::C(_, _b) => {} } //~ ERROR tuple struct `C` is private
+ match c { other::C(_a, _b) => {} } //~ ERROR tuple struct `C` is private
let other::D(_) = d;
let other::D(_d) = d;
match d { other::D(_d) => {} }
match d { other::D(1) => {} other::D(_) => {} }
- let a2 = other::A; //~ ERROR: cannot invoke tuple struct constructor
- let b2 = other::B; //~ ERROR: cannot invoke tuple struct constructor
- let c2 = other::C; //~ ERROR: cannot invoke tuple struct constructor
+ let a2 = other::A; //~ ERROR tuple struct `A` is private
+ let b2 = other::B; //~ ERROR tuple struct `B` is private
+ let c2 = other::C; //~ ERROR tuple struct `C` is private
let d2 = other::D;
}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(pub_restricted)]
+
+pub mod m {
+ pub struct S(u8);
+
+ pub mod n {
+ pub(m) struct Z(pub(m::n) u8);
+ }
+}
+
+pub use m::S;
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:privacy-struct-ctor.rs
+
+#![feature(pub_restricted)]
+
+extern crate privacy_struct_ctor as xcrate;
+
+mod m {
+ pub struct S(u8);
+
+ pub mod n {
+ pub(m) struct Z(pub(m::n) u8);
+ }
+
+ use m::n::Z; // OK, only the type is imported
+
+ fn f() {
+ n::Z; //~ ERROR tuple struct `Z` is private
+ Z;
+ //~^ ERROR expected value, found struct `Z`
+ //~| NOTE tuple struct constructors with private fields are invisible outside of their mod
+ }
+}
+
+use m::S; // OK, only the type is imported
+
+fn main() {
+ m::S; //~ ERROR tuple struct `S` is private
+ S;
+ //~^ ERROR expected value, found struct `S`
+ //~| NOTE constructor is not visible here due to private fields
+ m::n::Z; //~ ERROR tuple struct `Z` is private
+
+ xcrate::m::S; //~ ERROR tuple struct `S` is private
+ xcrate::S;
+ //~^ ERROR expected value, found struct `xcrate::S`
+ //~| NOTE constructor is not visible here due to private fields
+ xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
+}
--- /dev/null
+error[E0423]: expected value, found struct `Z`
+ --> $DIR/privacy-struct-ctor.rs:28:9
+ |
+28 | Z;
+ | ^
+ | |
+ | did you mean `Z { /* fields */ }`?
+ | constructor is not visible here due to private fields
+ |
+ = help: possible better candidate is found in another module, you can import it into scope:
+ `use m::n::Z;`
+
+error[E0423]: expected value, found struct `S`
+ --> $DIR/privacy-struct-ctor.rs:38:5
+ |
+38 | S;
+ | ^
+ | |
+ | did you mean `S { /* fields */ }`?
+ | constructor is not visible here due to private fields
+ |
+ = help: possible better candidate is found in another module, you can import it into scope:
+ `use m::S;`
+
+error[E0423]: expected value, found struct `xcrate::S`
+ --> $DIR/privacy-struct-ctor.rs:44:5
+ |
+44 | xcrate::S;
+ | ^^^^^^^^^
+ | |
+ | did you mean `xcrate::S { /* fields */ }`?
+ | constructor is not visible here due to private fields
+ |
+ = help: possible better candidate is found in another module, you can import it into scope:
+ `use m::S;`
+
+error: tuple struct `Z` is private
+ --> $DIR/privacy-struct-ctor.rs:27:9
+ |
+27 | n::Z; //~ ERROR tuple struct `Z` is private
+ | ^^^^
+
+error: tuple struct `S` is private
+ --> $DIR/privacy-struct-ctor.rs:37:5
+ |
+37 | m::S; //~ ERROR tuple struct `S` is private
+ | ^^^^
+
+error: tuple struct `Z` is private
+ --> $DIR/privacy-struct-ctor.rs:41:5
+ |
+41 | m::n::Z; //~ ERROR tuple struct `Z` is private
+ | ^^^^^^^
+
+error: tuple struct `S` is private
+ --> $DIR/privacy-struct-ctor.rs:43:5
+ |
+43 | xcrate::m::S; //~ ERROR tuple struct `S` is private
+ | ^^^^^^^^^^^^
+
+error: tuple struct `Z` is private
+ --> $DIR/privacy-struct-ctor.rs:47:5
+ |
+47 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+