From 0daaeab244a583b6bb5b88c41ad0fdd51388619d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 31 Dec 2013 12:40:10 -0800 Subject: [PATCH] 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 --- src/librustc/middle/privacy.rs | 23 +++++++++++++++++++++ src/libstd/local_data.rs | 1 + src/test/auxiliary/issue-11224.rs | 26 +++++++++++++++++++++++ src/test/auxiliary/issue-11225-1.rs | 23 +++++++++++++++++++++ src/test/auxiliary/issue-11225-2.rs | 32 +++++++++++++++++++++++++++++ src/test/run-pass/issue-11224.rs | 16 +++++++++++++++ src/test/run-pass/issue-11225-1.rs | 18 ++++++++++++++++ src/test/run-pass/issue-11225-2.rs | 18 ++++++++++++++++ 8 files changed, 157 insertions(+) create mode 100644 src/test/auxiliary/issue-11224.rs create mode 100644 src/test/auxiliary/issue-11225-1.rs create mode 100644 src/test/auxiliary/issue-11225-2.rs create mode 100644 src/test/run-pass/issue-11224.rs create mode 100644 src/test/run-pass/issue-11225-1.rs create mode 100644 src/test/run-pass/issue-11225-2.rs diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 707446a78fe..a0da1680d00 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -167,6 +167,23 @@ struct EmbargoVisitor<'a> { reexports: HashSet, } +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 @@ fn visit_item(&mut self, item: @ast::item, _: ()) { // 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. _ => { diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs index d7e11d2f3a7..95fdce99ea6 100644 --- a/src/libstd/local_data.rs +++ b/src/libstd/local_data.rs @@ -62,6 +62,7 @@ #[allow(missing_doc)] pub enum KeyValue { Key } +#[allow(missing_doc)] trait LocalData {} impl LocalData for T {} diff --git a/src/test/auxiliary/issue-11224.rs b/src/test/auxiliary/issue-11224.rs new file mode 100644 index 00000000000..448ef8ef818 --- /dev/null +++ b/src/test/auxiliary/issue-11224.rs @@ -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 or the MIT license +// , 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(); +} diff --git a/src/test/auxiliary/issue-11225-1.rs b/src/test/auxiliary/issue-11225-1.rs new file mode 100644 index 00000000000..88277af4a51 --- /dev/null +++ b/src/test/auxiliary/issue-11225-1.rs @@ -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 or the MIT license +// , 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: T) { + t.f(); +} diff --git a/src/test/auxiliary/issue-11225-2.rs b/src/test/auxiliary/issue-11225-2.rs new file mode 100644 index 00000000000..848574a61fe --- /dev/null +++ b/src/test/auxiliary/issue-11225-2.rs @@ -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 or the MIT license +// , 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(&self, t: T) { t.f(); } +} + +impl Outer for int {} + +pub fn foo(t: T) { + t.foo(inner::Foo); +} diff --git a/src/test/run-pass/issue-11224.rs b/src/test/run-pass/issue-11224.rs new file mode 100644 index 00000000000..bf412ceab28 --- /dev/null +++ b/src/test/run-pass/issue-11224.rs @@ -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 or the MIT license +// , 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() {} diff --git a/src/test/run-pass/issue-11225-1.rs b/src/test/run-pass/issue-11225-1.rs new file mode 100644 index 00000000000..ad8cb1e79ab --- /dev/null +++ b/src/test/run-pass/issue-11225-1.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/test/run-pass/issue-11225-2.rs b/src/test/run-pass/issue-11225-2.rs new file mode 100644 index 00000000000..e572e56362b --- /dev/null +++ b/src/test/run-pass/issue-11225-2.rs @@ -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 or the MIT license +// , 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); +} -- GitLab