mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Prohibit public glob reexports of private variants
This commit is contained in:
parent
187c89a92a
commit
8f359d5912
@ -1012,11 +1012,6 @@ impl NameBinding {
|
||||
self.defined_with(DefModifiers::PUBLIC)
|
||||
}
|
||||
|
||||
fn is_reexportable(&self) -> bool {
|
||||
self.defined_with(DefModifiers::PUBLIC) &&
|
||||
!self.defined_with(DefModifiers::PRIVATE_VARIANT)
|
||||
}
|
||||
|
||||
fn def_and_lp(&self) -> (Def, LastPrivate) {
|
||||
let def = self.def().unwrap();
|
||||
(def, LastMod(if self.is_public() { AllPublic } else { DependsOn(def.def_id()) }))
|
||||
|
@ -25,6 +25,7 @@ use {resolve_error, ResolutionError};
|
||||
|
||||
use build_reduced_graph;
|
||||
|
||||
use rustc::lint;
|
||||
use rustc::middle::def::*;
|
||||
use rustc::middle::def_id::DefId;
|
||||
use rustc::middle::privacy::*;
|
||||
@ -443,7 +444,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
debug!("(resolving single import) found value binding");
|
||||
value_result = BoundResult(target_module.clone(),
|
||||
child_name_bindings.value_ns.clone());
|
||||
if directive.is_public && !child_name_bindings.value_ns.is_reexportable() {
|
||||
if directive.is_public && !child_name_bindings.value_ns.is_public() {
|
||||
let msg = format!("`{}` is private, and cannot be reexported", source);
|
||||
let note_msg = format!("Consider marking `{}` as `pub` in the imported \
|
||||
module",
|
||||
@ -452,19 +453,40 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
self.resolver.session.span_note(directive.span, ¬e_msg);
|
||||
pub_err = true;
|
||||
}
|
||||
if directive.is_public && child_name_bindings.value_ns.
|
||||
defined_with(DefModifiers::PRIVATE_VARIANT) {
|
||||
let msg = format!("variant `{}` is private, and cannot be reexported ( \
|
||||
error E0364), consider declaring its enum as `pub`",
|
||||
source);
|
||||
self.resolver.session.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||
directive.id,
|
||||
directive.span,
|
||||
msg);
|
||||
pub_err = true;
|
||||
}
|
||||
}
|
||||
if child_name_bindings.type_ns.defined() {
|
||||
debug!("(resolving single import) found type binding");
|
||||
type_result = BoundResult(target_module.clone(),
|
||||
child_name_bindings.type_ns.clone());
|
||||
if !pub_err && directive.is_public &&
|
||||
!child_name_bindings.type_ns.is_reexportable() {
|
||||
!child_name_bindings.type_ns.is_public() {
|
||||
let msg = format!("`{}` is private, and cannot be reexported", source);
|
||||
let note_msg = format!("Consider declaring module `{}` as a `pub mod`",
|
||||
source);
|
||||
span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
|
||||
self.resolver.session.span_note(directive.span, ¬e_msg);
|
||||
}
|
||||
if !pub_err && directive.is_public && child_name_bindings.type_ns.
|
||||
defined_with(DefModifiers::PRIVATE_VARIANT) {
|
||||
let msg = format!("variant `{}` is private, and cannot be reexported ( \
|
||||
error E0365), consider declaring its enum as `pub`",
|
||||
source);
|
||||
self.resolver.session.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||
directive.id,
|
||||
directive.span,
|
||||
msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -842,10 +864,22 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
module_to_string(module_));
|
||||
|
||||
// Merge the child item into the import resolution.
|
||||
// pub_err makes sure we don't give the same error twice.
|
||||
let mut pub_err = false;
|
||||
{
|
||||
let mut merge_child_item = |namespace| {
|
||||
let modifier = DefModifiers::IMPORTABLE | DefModifiers::PUBLIC;
|
||||
if !pub_err && is_public &&
|
||||
name_bindings[namespace].defined_with(DefModifiers::PRIVATE_VARIANT) {
|
||||
let msg = format!("variant `{}` is private, and cannot be reexported (error \
|
||||
E0364), consider declaring its enum as `pub`", name);
|
||||
self.resolver.session.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||
import_directive.id,
|
||||
import_directive.span,
|
||||
msg);
|
||||
pub_err = true;
|
||||
}
|
||||
|
||||
let modifier = DefModifiers::IMPORTABLE | DefModifiers::PUBLIC;
|
||||
if name_bindings[namespace].defined_with(modifier) {
|
||||
let namespace_name = match namespace {
|
||||
TypeNS => "type",
|
||||
|
@ -8,8 +8,26 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub use E::V; //~ERROR `V` is private, and cannot be reexported
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod m1 {
|
||||
pub use ::E::V; //~ WARN variant `V` is private, and cannot be reexported
|
||||
}
|
||||
|
||||
mod m2 {
|
||||
pub use ::E::{V}; //~ WARN variant `V` is private, and cannot be reexported
|
||||
}
|
||||
|
||||
mod m3 {
|
||||
pub use ::E::V::{self}; //~ WARN variant `V` is private, and cannot be reexported
|
||||
}
|
||||
|
||||
mod m4 {
|
||||
pub use ::E::*; //~ WARN variant `V` is private, and cannot be reexported
|
||||
}
|
||||
|
||||
enum E { V }
|
||||
|
||||
fn main() {}
|
||||
#[rustc_error]
|
||||
fn main() {} //~ ERROR compilation successful
|
||||
|
Loading…
Reference in New Issue
Block a user