]> git.lizzy.rs Git - rust.git/commitdiff
Conservatively export all trait methods and impls
authorAlex Crichton <alex@alexcrichton.com>
Tue, 31 Dec 2013 20:40:10 +0000 (12:40 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 31 Dec 2013 20:42:13 +0000 (12:42 -0800)
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
src/libstd/local_data.rs
src/test/auxiliary/issue-11224.rs [new file with mode: 0644]
src/test/auxiliary/issue-11225-1.rs [new file with mode: 0644]
src/test/auxiliary/issue-11225-2.rs [new file with mode: 0644]
src/test/run-pass/issue-11224.rs [new file with mode: 0644]
src/test/run-pass/issue-11225-1.rs [new file with mode: 0644]
src/test/run-pass/issue-11225-2.rs [new file with mode: 0644]

index 707446a78fe217473f9ea3f2294ceecb0cf9507f..a0da1680d00412bef250d81bcf59decfe5d630db 100644 (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 @@ 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.
             _ => {
index d7e11d2f3a70f693a1ff9b8f44386ab0d0e2e4be..95fdce99ea654aceea5cf7e5d4033a6a8121bc2d 100644 (file)
@@ -62,6 +62,7 @@
 #[allow(missing_doc)]
 pub enum KeyValue<T> { Key }
 
+#[allow(missing_doc)]
 trait LocalData {}
 impl<T: 'static> LocalData for T {}
 
diff --git a/src/test/auxiliary/issue-11224.rs b/src/test/auxiliary/issue-11224.rs
new file mode 100644 (file)
index 0000000..448ef8e
--- /dev/null
@@ -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();
+}
diff --git a/src/test/auxiliary/issue-11225-1.rs b/src/test/auxiliary/issue-11225-1.rs
new file mode 100644 (file)
index 0000000..88277af
--- /dev/null
@@ -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();
+}
diff --git a/src/test/auxiliary/issue-11225-2.rs b/src/test/auxiliary/issue-11225-2.rs
new file mode 100644 (file)
index 0000000..848574a
--- /dev/null
@@ -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);
+}
diff --git a/src/test/run-pass/issue-11224.rs b/src/test/run-pass/issue-11224.rs
new file mode 100644 (file)
index 0000000..bf412ce
--- /dev/null
@@ -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() {}
diff --git a/src/test/run-pass/issue-11225-1.rs b/src/test/run-pass/issue-11225-1.rs
new file mode 100644 (file)
index 0000000..ad8cb1e
--- /dev/null
@@ -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);
+}
diff --git a/src/test/run-pass/issue-11225-2.rs b/src/test/run-pass/issue-11225-2.rs
new file mode 100644 (file)
index 0000000..e572e56
--- /dev/null
@@ -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);
+}