1
Fork 0

Introduce ICE when the topmost projection restriction kicks in, as per issue #32205

This commit is contained in:
Aaron Turon 2016-03-11 14:47:29 -08:00
parent d80189d305
commit e36620dd9c
2 changed files with 35 additions and 6 deletions

View file

@ -38,13 +38,13 @@ use std::rc::Rc;
/// more or less conservative. /// more or less conservative.
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ProjectionMode { pub enum ProjectionMode {
/// FIXME (#32205)
/// At coherence-checking time, we're still constructing the /// At coherence-checking time, we're still constructing the
/// specialization graph, and thus we only project project /// specialization graph, and thus we only project project
/// non-`default` associated types that are defined directly in /// non-`default` associated types that are defined directly in
/// the applicable impl. (This behavior should be improved over /// the applicable impl. (This behavior should be improved over
/// time, to allow for successful projections modulo cycles /// time, to allow for successful projections modulo cycles
/// between different impls). /// between different impls).
// TODO: Add tracking issue to do better here.
/// ///
/// Here's an example that will fail due to the restriction: /// 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 /// The projection would succeed if `Output` had been defined
/// directly in the impl for `u8`. /// directly in the impl for `u8`.
// TODO: Add test
Topmost, Topmost,
/// At type-checking time, we refuse to project any associated /// At type-checking time, we refuse to project any associated
@ -91,7 +90,6 @@ pub enum ProjectionMode {
/// fn main() { /// fn main() {
/// let <() as Assoc>::Output = true; /// let <() as Assoc>::Output = true;
/// } /// }
// TODO: Add test
AnyFinal, AnyFinal,
/// At trans time, all projections will succeed. /// 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 // at the topmost impl (we don't even consider the trait
// itself) for the definition -- so we can fail to find a // itself) for the definition -- so we can fail to find a
// definition of the type even if it exists. // 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.");
} }
} }
} }

View file

@ -198,9 +198,11 @@ mod aliases_pub {
use self::m::PubTr as PrivUseAliasTr; use self::m::PubTr as PrivUseAliasTr;
type PrivAlias = m::Pub2; type PrivAlias = m::Pub2;
trait PrivTr { trait PrivTr {
type AssocAlias;
}
impl PrivTr for Priv {
type AssocAlias = m::Pub3; type AssocAlias = m::Pub3;
} }
impl PrivTr for Priv {}
pub fn f1(arg: PrivUseAlias) {} // OK pub fn f1(arg: PrivUseAlias) {} // OK
@ -245,9 +247,11 @@ mod aliases_priv {
use self::PrivTr1 as PrivUseAliasTr; use self::PrivTr1 as PrivUseAliasTr;
type PrivAlias = Priv2; type PrivAlias = Priv2;
trait PrivTr { trait PrivTr {
type AssocAlias;
}
impl PrivTr for Priv {
type AssocAlias = Priv3; type AssocAlias = Priv3;
} }
impl PrivTr for Priv {}
pub trait Tr1: PrivUseAliasTr {} //~ WARN private trait in public interface pub trait Tr1: PrivUseAliasTr {} //~ WARN private trait in public interface
//~^ WARNING hard error //~^ WARNING hard error