From: Aaron Turon Date: Fri, 11 Mar 2016 22:47:29 +0000 (-0800) Subject: Introduce ICE when the topmost projection restriction kicks in, as per issue #32205 X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=e36620dd9c29e39da688d87e1a6566710aa2ccc5;hp=d80189d305ce24b6a1fd83a4f724d17506b64a13;p=rust.git Introduce ICE when the topmost projection restriction kicks in, as per issue #32205 --- diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 0c857692ad1..469ce0a4d27 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -38,13 +38,13 @@ /// 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 Assoc for T { + // default type Output = bool; + // } + // + // impl Assoc for u8 {} + // impl Assoc for u16 {} + // + // trait Foo {} + // impl Foo for ::Output {} + // impl Foo for ::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."); } } } diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index 9aab06ce14e..b9d632a8cf0 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -198,9 +198,11 @@ pub trait PubTr { 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 { 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