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)
|
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) {
|
fn def_and_lp(&self) -> (Def, LastPrivate) {
|
||||||
let def = self.def().unwrap();
|
let def = self.def().unwrap();
|
||||||
(def, LastMod(if self.is_public() { AllPublic } else { DependsOn(def.def_id()) }))
|
(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 build_reduced_graph;
|
||||||
|
|
||||||
|
use rustc::lint;
|
||||||
use rustc::middle::def::*;
|
use rustc::middle::def::*;
|
||||||
use rustc::middle::def_id::DefId;
|
use rustc::middle::def_id::DefId;
|
||||||
use rustc::middle::privacy::*;
|
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");
|
debug!("(resolving single import) found value binding");
|
||||||
value_result = BoundResult(target_module.clone(),
|
value_result = BoundResult(target_module.clone(),
|
||||||
child_name_bindings.value_ns.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 msg = format!("`{}` is private, and cannot be reexported", source);
|
||||||
let note_msg = format!("Consider marking `{}` as `pub` in the imported \
|
let note_msg = format!("Consider marking `{}` as `pub` in the imported \
|
||||||
module",
|
module",
|
||||||
@ -452,19 +453,40 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
|||||||
self.resolver.session.span_note(directive.span, ¬e_msg);
|
self.resolver.session.span_note(directive.span, ¬e_msg);
|
||||||
pub_err = true;
|
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() {
|
if child_name_bindings.type_ns.defined() {
|
||||||
debug!("(resolving single import) found type binding");
|
debug!("(resolving single import) found type binding");
|
||||||
type_result = BoundResult(target_module.clone(),
|
type_result = BoundResult(target_module.clone(),
|
||||||
child_name_bindings.type_ns.clone());
|
child_name_bindings.type_ns.clone());
|
||||||
if !pub_err && directive.is_public &&
|
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 msg = format!("`{}` is private, and cannot be reexported", source);
|
||||||
let note_msg = format!("Consider declaring module `{}` as a `pub mod`",
|
let note_msg = format!("Consider declaring module `{}` as a `pub mod`",
|
||||||
source);
|
source);
|
||||||
span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
|
span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
|
||||||
self.resolver.session.span_note(directive.span, ¬e_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_));
|
module_to_string(module_));
|
||||||
|
|
||||||
// Merge the child item into the import resolution.
|
// 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 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) {
|
if name_bindings[namespace].defined_with(modifier) {
|
||||||
let namespace_name = match namespace {
|
let namespace_name = match namespace {
|
||||||
TypeNS => "type",
|
TypeNS => "type",
|
||||||
|
@ -8,8 +8,26 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// 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 }
|
enum E { V }
|
||||||
|
|
||||||
fn main() {}
|
#[rustc_error]
|
||||||
|
fn main() {} //~ ERROR compilation successful
|
||||||
|
Loading…
Reference in New Issue
Block a user