mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 17:24:06 +00:00
Always report private-in-public in associated types as hard errors
according to RFC 2145. Fix a silly label message.
This commit is contained in:
parent
020961d880
commit
c6209a36bb
@ -1313,6 +1313,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
|
||||
min_visibility: ty::Visibility,
|
||||
has_pub_restricted: bool,
|
||||
has_old_errors: bool,
|
||||
in_assoc_ty: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||
@ -1373,11 +1374,11 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||
self.min_visibility = vis;
|
||||
}
|
||||
if !vis.is_at_least(self.required_visibility, self.tcx) {
|
||||
if self.has_pub_restricted || self.has_old_errors {
|
||||
if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty {
|
||||
struct_span_err!(self.tcx.sess, self.span, E0445,
|
||||
"private trait `{}` in public interface", trait_ref)
|
||||
.span_label(self.span, format!(
|
||||
"private trait can't be public"))
|
||||
"can't leak private trait"))
|
||||
.emit();
|
||||
} else {
|
||||
self.tcx.lint_node(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||
@ -1428,7 +1429,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
|
||||
self.min_visibility = vis;
|
||||
}
|
||||
if !vis.is_at_least(self.required_visibility, self.tcx) {
|
||||
if self.has_pub_restricted || self.has_old_errors {
|
||||
if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty {
|
||||
let mut err = struct_span_err!(self.tcx.sess, self.span, E0446,
|
||||
"private type `{}` in public interface", ty);
|
||||
err.span_label(self.span, "can't leak private type");
|
||||
@ -1489,6 +1490,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
|
||||
required_visibility,
|
||||
has_pub_restricted: self.has_pub_restricted,
|
||||
has_old_errors,
|
||||
in_assoc_ty: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1529,6 +1531,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
|
||||
|
||||
for trait_item_ref in trait_item_refs {
|
||||
let mut check = self.check(trait_item_ref.id.node_id, item_visibility);
|
||||
check.in_assoc_ty = trait_item_ref.kind == hir::AssociatedItemKind::Type;
|
||||
check.generics().predicates();
|
||||
|
||||
if trait_item_ref.kind == hir::AssociatedItemKind::Type &&
|
||||
@ -1579,10 +1582,10 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
|
||||
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
|
||||
let impl_item_vis =
|
||||
ty::Visibility::from_hir(&impl_item.vis, item.id, tcx);
|
||||
self.check(impl_item.id, min(impl_item_vis, ty_vis))
|
||||
.generics().predicates().ty();
|
||||
let impl_item_vis = ty::Visibility::from_hir(&impl_item.vis, item.id, tcx);
|
||||
let mut check = self.check(impl_item.id, min(impl_item_vis, ty_vis));
|
||||
check.in_assoc_ty = impl_item_ref.kind == hir::AssociatedItemKind::Type;
|
||||
check.generics().predicates().ty();
|
||||
|
||||
// Recurse for e.g. `impl Trait` (see `visit_ty`).
|
||||
self.inner_visibility = impl_item_vis;
|
||||
@ -1597,7 +1600,9 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
|
||||
self.check(item.id, vis).generics().predicates();
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
|
||||
self.check(impl_item.id, vis).generics().predicates().ty();
|
||||
let mut check = self.check(impl_item.id, vis);
|
||||
check.in_assoc_ty = impl_item_ref.kind == hir::AssociatedItemKind::Type;
|
||||
check.generics().predicates().ty();
|
||||
|
||||
// Recurse for e.g. `impl Trait` (see `visit_ty`).
|
||||
self.inner_visibility = vis;
|
||||
|
@ -14,9 +14,12 @@ trait Foo {
|
||||
|
||||
pub trait Bar : Foo {}
|
||||
//~^ ERROR private trait `Foo` in public interface [E0445]
|
||||
//~| NOTE can't leak private trait
|
||||
pub struct Bar2<T: Foo>(pub T);
|
||||
//~^ ERROR private trait `Foo` in public interface [E0445]
|
||||
//~| NOTE can't leak private trait
|
||||
pub fn foo<T: Foo> (t: T) {}
|
||||
//~^ ERROR private trait `Foo` in public interface [E0445]
|
||||
//~| NOTE can't leak private trait
|
||||
|
||||
fn main() {}
|
||||
|
@ -8,15 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![deny(private_in_public)]
|
||||
#![allow(unused)]
|
||||
|
||||
struct SemiPriv;
|
||||
|
||||
mod m1 {
|
||||
struct Priv;
|
||||
impl ::SemiPriv {
|
||||
pub fn f(_: Priv) {} //~ ERROR private type `m1::Priv` in public interface
|
||||
pub fn f(_: Priv) {} //~ WARN private type `m1::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
}
|
||||
|
||||
@ -29,7 +26,6 @@ mod m2 {
|
||||
struct Priv;
|
||||
impl ::std::ops::Deref for ::SemiPriv {
|
||||
type Target = Priv; //~ ERROR private type `m2::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
fn deref(&self) -> &Self::Target { unimplemented!() }
|
||||
}
|
||||
|
||||
@ -47,7 +43,6 @@ mod m3 {
|
||||
struct Priv;
|
||||
impl ::SemiPrivTrait for () {
|
||||
type Assoc = Priv; //~ ERROR private type `m3::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
}
|
||||
}
|
||||
|
||||
|
43
src/test/compile-fail/private-in-public-assoc-ty.rs
Normal file
43
src/test/compile-fail/private-in-public-assoc-ty.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// 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.
|
||||
|
||||
// Private types and traits are not allowed in interfaces of associated types.
|
||||
// This test also ensures that the checks are performed even inside private modules.
|
||||
|
||||
#![feature(associated_type_defaults)]
|
||||
|
||||
mod m {
|
||||
struct Priv;
|
||||
trait PrivTr {}
|
||||
impl PrivTr for Priv {}
|
||||
pub trait PubTrAux1<T> {}
|
||||
pub trait PubTrAux2 { type A; }
|
||||
|
||||
// "Private-in-public in associated types is hard error" in RFC 2145
|
||||
// applies only to the aliased types, not bounds.
|
||||
pub trait PubTr {
|
||||
//~^ WARN private trait `m::PrivTr` in public interface
|
||||
//~| WARN this was previously accepted
|
||||
//~| WARN private type `m::Priv` in public interface
|
||||
//~| WARN this was previously accepted
|
||||
type Alias1: PrivTr;
|
||||
type Alias2: PubTrAux1<Priv> = u8;
|
||||
type Alias3: PubTrAux2<A = Priv> = u8;
|
||||
|
||||
type Alias4 = Priv;
|
||||
//~^ ERROR private type `m::Priv` in public interface
|
||||
}
|
||||
impl PubTr for u8 {
|
||||
type Alias1 = Priv;
|
||||
//~^ ERROR private type `m::Priv` in public interface
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
45
src/test/compile-fail/private-in-public-ill-formed.rs
Normal file
45
src/test/compile-fail/private-in-public-ill-formed.rs
Normal file
@ -0,0 +1,45 @@
|
||||
// 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.
|
||||
|
||||
mod aliases_pub {
|
||||
struct Priv;
|
||||
mod m {
|
||||
pub struct Pub3;
|
||||
}
|
||||
|
||||
trait PrivTr {
|
||||
type AssocAlias;
|
||||
}
|
||||
impl PrivTr for Priv {
|
||||
type AssocAlias = m::Pub3;
|
||||
}
|
||||
|
||||
impl (<Priv as PrivTr>::AssocAlias) { //~ ERROR no base type found for inherent implementation
|
||||
pub fn f(arg: Priv) {} // private type `aliases_pub::Priv` in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod aliases_priv {
|
||||
struct Priv;
|
||||
struct Priv3;
|
||||
|
||||
trait PrivTr {
|
||||
type AssocAlias;
|
||||
}
|
||||
impl PrivTr for Priv {
|
||||
type AssocAlias = Priv3;
|
||||
}
|
||||
|
||||
impl (<Priv as PrivTr>::AssocAlias) { //~ ERROR no base type found for inherent implementation
|
||||
pub fn f(arg: Priv) {} // OK
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -13,7 +13,6 @@
|
||||
|
||||
#![feature(associated_type_defaults)]
|
||||
#![deny(private_in_public)]
|
||||
#![allow(unused)]
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
mod types {
|
||||
@ -35,7 +34,6 @@ mod types {
|
||||
const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface
|
||||
@ -51,7 +49,6 @@ mod types {
|
||||
}
|
||||
impl PubTr for Pub {
|
||||
type Alias = Priv; //~ ERROR private type `types::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,7 +143,6 @@ mod impls {
|
||||
}
|
||||
impl PubTr for Pub {
|
||||
type Alias = Priv; //~ ERROR private type `impls::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,21 +216,14 @@ mod aliases_pub {
|
||||
pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
}
|
||||
// This doesn't even parse
|
||||
// impl <Priv as PrivTr>::AssocAlias {
|
||||
// pub fn f(arg: Priv) {} // ERROR private type `aliases_pub::Priv` in public interface
|
||||
// }
|
||||
impl PrivUseAliasTr for PrivUseAlias {
|
||||
type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
}
|
||||
impl PrivUseAliasTr for PrivAlias {
|
||||
type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
}
|
||||
impl PrivUseAliasTr for <Priv as PrivTr>::AssocAlias {
|
||||
type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface
|
||||
//~^ WARNING hard error
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,10 +262,6 @@ mod aliases_priv {
|
||||
impl PrivAlias {
|
||||
pub fn f(arg: Priv) {} // OK
|
||||
}
|
||||
// This doesn't even parse
|
||||
// impl <Priv as PrivTr>::AssocAlias {
|
||||
// pub fn f(arg: Priv) {} // OK
|
||||
// }
|
||||
impl PrivUseAliasTr for PrivUseAlias {
|
||||
type Check = Priv; // OK
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
#![feature(associated_consts)]
|
||||
#![feature(conservative_impl_trait)]
|
||||
#![feature(decl_macro)]
|
||||
#![allow(warnings)]
|
||||
#![allow(private_in_public)]
|
||||
|
||||
mod m {
|
||||
fn priv_fn() {}
|
||||
@ -70,6 +70,7 @@ mod m {
|
||||
impl<T> TraitWithTyParam<T> for u8 {}
|
||||
impl TraitWithTyParam2<Priv> for u8 {}
|
||||
impl TraitWithAssocTy for u8 { type AssocTy = Priv; }
|
||||
//~^ ERROR private type `m::Priv` in public interface
|
||||
|
||||
pub fn leak_anon1() -> impl Trait + 'static { 0 }
|
||||
pub fn leak_anon2() -> impl TraitWithTyParam<Alias> { 0 }
|
||||
@ -90,7 +91,7 @@ mod adjust {
|
||||
pub struct S3;
|
||||
|
||||
impl Deref for S1 {
|
||||
type Target = S2Alias;
|
||||
type Target = S2Alias; //~ ERROR private type `adjust::S2` in public interface
|
||||
fn deref(&self) -> &Self::Target { loop {} }
|
||||
}
|
||||
impl Deref for S2 {
|
||||
|
Loading…
Reference in New Issue
Block a user