]> git.lizzy.rs Git - rust.git/commitdiff
Introduce ICE when the topmost projection restriction kicks in, as per issue #32205
authorAaron Turon <aturon@mozilla.com>
Fri, 11 Mar 2016 22:47:29 +0000 (14:47 -0800)
committerAaron Turon <aturon@mozilla.com>
Mon, 14 Mar 2016 22:05:15 +0000 (15:05 -0700)
src/librustc/middle/traits/project.rs
src/test/compile-fail/private-in-public-warn.rs

index 0c857692ad11c904d5eaa7341be8d97bddc16722..469ce0a4d2799be9945527d2c515db5bad9dbdc8 100644 (file)
 /// more or less conservative.
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum ProjectionMode {
+    /// FIXME (#32205)
     /// At coherence-checking time, we're still constructing the
     /// specialization graph, and thus we only project project
     /// non-`default` associated types that are defined directly in
     /// the applicable impl. (This behavior should be improved over
     /// time, to allow for successful projections modulo cycles
     /// between different impls).
-    // TODO: Add tracking issue to do better here.
     ///
     /// Here's an example that will fail due to the restriction:
     ///
@@ -66,7 +66,6 @@ pub enum ProjectionMode {
     ///
     /// The projection would succeed if `Output` had been defined
     /// directly in the impl for `u8`.
-    // TODO: Add test
     Topmost,
 
     /// At type-checking time, we refuse to project any associated
@@ -91,7 +90,6 @@ pub enum ProjectionMode {
     /// fn main() {
     ///     let <() as Assoc>::Output = true;
     /// }
-    // TODO: Add test
     AnyFinal,
 
     /// At trans time, all projections will succeed.
@@ -695,7 +693,34 @@ fn project_type<'cx,'tcx>(
                     // at the topmost impl (we don't even consider the trait
                     // itself) for the definition -- so we can fail to find a
                     // definition of the type even if it exists.
-                    return None;
+
+                    // For now, we just unconditionally ICE, because otherwise,
+                    // examples like the following will succeed:
+                    //
+                    // ```
+                    // trait Assoc {
+                    //     type Output;
+                    // }
+                    //
+                    // impl<T> Assoc for T {
+                    //     default type Output = bool;
+                    // }
+                    //
+                    // impl Assoc for u8 {}
+                    // impl Assoc for u16 {}
+                    //
+                    // trait Foo {}
+                    // impl Foo for <u8 as Assoc>::Output {}
+                    // impl Foo for <u16 as Assoc>::Output {}
+                    //     return None;
+                    // }
+                    // ```
+                    //
+                    // The essential problem here is that the projection fails,
+                    // leaving two unnormalized types, which appear not to unify
+                    // -- so the overlap check succeeds, when it should fail.
+                    selcx.tcx().sess.bug("Tried to project an inherited associated type during \
+                                          coherence checking, which is currently not supported.");
                 }
             }
         }
index 9aab06ce14ee16b324075fcaed44fbedc7c63766..b9d632a8cf07e6ce33dcbcd4271e05758769b5d0 100644 (file)
@@ -198,9 +198,11 @@ pub trait PubTr<T = u8> {
     use self::m::PubTr as PrivUseAliasTr;
     type PrivAlias = m::Pub2;
     trait PrivTr {
+        type AssocAlias;
+    }
+    impl PrivTr for Priv {
         type AssocAlias = m::Pub3;
     }
-    impl PrivTr for Priv {}
 
     pub fn f1(arg: PrivUseAlias) {} // OK
 
@@ -245,9 +247,11 @@ trait PrivTr1<T = u8> {
     use self::PrivTr1 as PrivUseAliasTr;
     type PrivAlias = Priv2;
     trait PrivTr {
+        type AssocAlias;
+    }
+    impl PrivTr for Priv {
         type AssocAlias = Priv3;
     }
-    impl PrivTr for Priv {}
 
     pub trait Tr1: PrivUseAliasTr {} //~ WARN private trait in public interface
         //~^ WARNING hard error