Introduce ICE when the topmost projection restriction kicks in, as per issue #32205
This commit is contained in:
parent
d80189d305
commit
e36620dd9c
2 changed files with 35 additions and 6 deletions
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue