Conservatively export all trait methods and impls

The comments have more information as to why this is done, but the basic idea is
that finding an exported trait is actually a fairly difficult problem. The true
answer lies in whether a trait is ever referenced from another exported method,
and right now this kind of analysis doesn't exist, so the conservative answer of
"yes" is always returned to answer whether a trait is exported.

Closes #11224
Closes #11225
This commit is contained in:
Alex Crichton 2013-12-31 12:40:10 -08:00
parent 1502b1197b
commit 0daaeab244
8 changed files with 157 additions and 0 deletions

View File

@ -167,6 +167,23 @@ struct EmbargoVisitor<'a> {
reexports: HashSet<ast::NodeId>,
}
impl<'a> EmbargoVisitor<'a> {
// There are checks inside of privacy which depend on knowing whether a
// trait should be exported or not. The two current consumers of this are:
//
// 1. Should default methods of a trait be exported?
// 2. Should the methods of an implementation of a trait be exported?
//
// The answer to both of these questions partly rely on whether the trait
// itself is exported or not. If the trait is somehow exported, then the
// answers to both questions must be yes. Right now this question involves
// more analysis than is currently done in rustc, so we conservatively
// answer "yes" so that all traits need to be exported.
fn exported_trait(&self, _id: ast::NodeId) -> bool {
true
}
}
impl<'a> Visitor<()> for EmbargoVisitor<'a> {
fn visit_item(&mut self, item: @ast::item, _: ()) {
let orig_all_pub = self.prev_exported;
@ -175,6 +192,12 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
// cannot have visibility qualifiers on them anyway
ast::item_impl(..) | ast::item_foreign_mod(..) => {}
// Traits are a little special in that even if they themselves are
// not public they may still be exported.
ast::item_trait(..) => {
self.prev_exported = self.exported_trait(item.id);
}
// Private by default, hence we only retain the "public chain" if
// `pub` is explicitly listed.
_ => {

View File

@ -62,6 +62,7 @@ pub type Key<T> = &'static KeyValue<T>;
#[allow(missing_doc)]
pub enum KeyValue<T> { Key }
#[allow(missing_doc)]
trait LocalData {}
impl<T: 'static> LocalData for T {}

View File

@ -0,0 +1,26 @@
// Copyright 2013 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.
#[deny(dead_code)];
mod inner {
pub trait Trait {
fn f(&self) { f(); }
}
impl Trait for int {}
fn f() {}
}
pub fn foo() {
let a = &1 as &inner::Trait;
a.f();
}

View File

@ -0,0 +1,23 @@
// Copyright 2013 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 inner {
pub trait Trait {
fn f(&self) { f(); }
}
impl Trait for int {}
fn f() {}
}
pub fn foo<T: inner::Trait>(t: T) {
t.f();
}

View File

@ -0,0 +1,32 @@
// Copyright 2013 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.
use inner::Trait;
mod inner {
pub struct Foo;
pub trait Trait {
fn f(&self);
}
impl Trait for Foo {
fn f(&self) { }
}
}
pub trait Outer {
fn foo<T: Trait>(&self, t: T) { t.f(); }
}
impl Outer for int {}
pub fn foo<T: Outer>(t: T) {
t.foo(inner::Foo);
}

View File

@ -0,0 +1,16 @@
// Copyright 2013 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:issue-11224.rs
// xfail-fast
extern mod unused = "issue-11224";
fn main() {}

View File

@ -0,0 +1,18 @@
// Copyright 2013 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:issue-11225-1.rs
// xfail-fast
extern mod foo = "issue-11225-1";
fn main() {
foo::foo(1);
}

View File

@ -0,0 +1,18 @@
// Copyright 2013 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:issue-11225-2.rs
// xfail-fast
extern mod foo = "issue-11225-2";
fn main() {
foo::foo(1);
}