about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/dead.rs10
-rw-r--r--src/test/run-pass/issue-23808.rs68
2 files changed, 78 insertions, 0 deletions
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index bd8a666ffec..5b7a698eec0 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -73,6 +73,16 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
     }
 
     fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
+        use middle::ty::TypeVariants::{TyEnum, TyStruct};
+
+        // If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar`
+        self.tcx.tables.borrow().item_substs.get(id)
+            .and_then(|substs| substs.substs.self_ty())
+            .map(|ty| match ty.sty {
+                TyEnum(tyid, _) | TyStruct(tyid, _) => self.check_def_id(tyid.did),
+                _ => (),
+            });
+
         self.tcx.def_map.borrow().get(id).map(|def| {
             match def.full_def() {
                 def::DefConst(_) | def::DefAssociatedConst(..) => {
diff --git a/src/test/run-pass/issue-23808.rs b/src/test/run-pass/issue-23808.rs
new file mode 100644
index 00000000000..0302b11fdbb
--- /dev/null
+++ b/src/test/run-pass/issue-23808.rs
@@ -0,0 +1,68 @@
+// Copyright 2015 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.
+
+#![feature(associated_consts)]
+#![deny(dead_code)]
+
+// use different types / traits to test all combinations
+
+trait Const {
+    const C: ();
+}
+
+trait StaticFn {
+    fn sfn();
+}
+
+struct ConstStruct;
+struct StaticFnStruct;
+
+enum ConstEnum {}
+enum StaticFnEnum {}
+
+struct AliasedConstStruct;
+struct AliasedStaticFnStruct;
+
+enum AliasedConstEnum {}
+enum AliasedStaticFnEnum {}
+
+type AliasConstStruct    = AliasedConstStruct;
+type AliasStaticFnStruct = AliasedStaticFnStruct;
+type AliasConstEnum      = AliasedConstEnum;
+type AliasStaticFnEnum   = AliasedStaticFnEnum;
+
+macro_rules! impl_Const {($($T:ident),*) => {$(
+    impl Const for $T {
+        const C: () = ();
+    }
+)*}}
+
+macro_rules! impl_StaticFn {($($T:ident),*) => {$(
+    impl StaticFn for $T {
+        fn sfn() {}
+    }
+)*}}
+
+impl_Const!(ConstStruct, ConstEnum, AliasedConstStruct, AliasedConstEnum);
+impl_StaticFn!(StaticFnStruct, StaticFnEnum, AliasedStaticFnStruct, AliasedStaticFnEnum);
+
+fn main() {
+    let _ = ConstStruct::C;
+    let _ = ConstEnum::C;
+
+    StaticFnStruct::sfn();
+    StaticFnEnum::sfn();
+
+    let _ = AliasConstStruct::C;
+    let _ = AliasConstEnum::C;
+
+    AliasStaticFnStruct::sfn();
+    AliasStaticFnEnum::sfn();
+}