-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trait argument from associated type has conflicting impl #99940
Comments
I want this to focus away from Also note, this requires a crate boundary. impl<T> ops::FromResidual for Option<T> {}
impl<T> ops::FromResidual<ops::Yeet<()>> for Option<T> {} which is exactly what I'm trying to accomplish - just that it's conflicting in my crate |
This involves many hacky things including implementing some of the traits to the JOption enum instead!! That's because there are some issues in the compiler like this one! rust-lang/rust#99940 Signed-off-by: Nefo Fortressia <[email protected]>
It was suggested that this might be due to the generic #![feature(try_trait_v2)]
struct Flip;
impl<T> std::ops::FromResidual<Flip> for Option<T>
{
fn from_residual(residual: Flip) -> Self {
None
}
} |
minimization // crate `dep`
pub trait Assoc {
type Ty;
}
impl Assoc for () {
type Ty = ();
}
pub trait Trait {}
impl Trait for <() as Assoc>::Ty {} // err
// impl Trait for () {} // ok
// local crate
struct LocalTy;
impl dep::Trait for LocalTy {} results in
this is a language/compiler bug. Footnotes
|
normalizing the trait refs during coherence we end up with the obligation For this we try to get the impl candidate for
This should succeed, but instead gets converted to ambiguity as the
We currently always convert trait obligations to ambiguity if either an upstream or downstream crate may implement that trait ref in the future. Most of the time, that is fine as coherence only checks whether some obligation definitely does not hold. So if some obligations get downgraded from success to ambiguity, this doesn't matter. The only time where that matters is if this obligation succeeding may cause another obligation to fail. This is the case when checking projection predicates. I think the correct fix here is to move the intercrate field into the |
going to look into this at some point after rustconf @rustbot claim |
another case where normalization being ambiguous prevents a later error is // dep
pub trait Assoc {
type Ty;
}
impl Assoc for () {
type Ty = ();
}
// local crate
trait Trait {}
impl Trait for <() as dep::Assoc>::Ty {} // err
trait Bar {}
impl<T: Bar> Trait for T {} // this errors, but we know that `(): Bar` does not hold. unlike the first case, this one is order dependent as
|
Not sure how similar this is to your approach, but I previously tried to fix this by changing the |
…=scottmcm Explicitly specify type parameter on FromResidual for Option and ControlFlow. ~~Remove type parameter default `R = <Self as Try>::Residual` from `FromResidual`~~ _Specify default type parameter on `FromResidual` impls in the stdlib_ to work around rust-lang#99940 / rust-lang#87350 ~~as mentioned in rust-lang#84277 (comment). This does not completely fix the issue, but works around it for `Option` and `ControlFlow` specifically (`Result` does not have the issue since it already did not use the default parameter of `FromResidual`). ~~(Does this need an ACP or similar?)~~ ~~This probably needs at least an FCP since it changes the API described in [the RFC](rust-lang/rfcs#3058). Not sure if T-lang, T-libs-api, T-libs, or some combination (The tracking issue is tagged T-lang, T-libs-api).~~ This probably doesn't need T-lang input, since it is not changing the API of `FromResidual` from the RFC? Maybe needs T-libs-api FCP?
…=scottmcm Explicitly specify type parameter on FromResidual for Option and ControlFlow. ~~Remove type parameter default `R = <Self as Try>::Residual` from `FromResidual`~~ _Specify default type parameter on `FromResidual` impls in the stdlib_ to work around rust-lang#99940 / rust-lang#87350 ~~as mentioned in rust-lang#84277 (comment). This does not completely fix the issue, but works around it for `Option` and `ControlFlow` specifically (`Result` does not have the issue since it already did not use the default parameter of `FromResidual`). ~~(Does this need an ACP or similar?)~~ ~~This probably needs at least an FCP since it changes the API described in [the RFC](rust-lang/rfcs#3058). Not sure if T-lang, T-libs-api, T-libs, or some combination (The tracking issue is tagged T-lang, T-libs-api).~~ This probably doesn't need T-lang input, since it is not changing the API of `FromResidual` from the RFC? Maybe needs T-libs-api FCP?
Rollup merge of rust-lang#128954 - zachs18:fromresidual-no-default, r=scottmcm Explicitly specify type parameter on FromResidual for Option and ControlFlow. ~~Remove type parameter default `R = <Self as Try>::Residual` from `FromResidual`~~ _Specify default type parameter on `FromResidual` impls in the stdlib_ to work around rust-lang#99940 / rust-lang#87350 ~~as mentioned in rust-lang#84277 (comment). This does not completely fix the issue, but works around it for `Option` and `ControlFlow` specifically (`Result` does not have the issue since it already did not use the default parameter of `FromResidual`). ~~(Does this need an ACP or similar?)~~ ~~This probably needs at least an FCP since it changes the API described in [the RFC](rust-lang/rfcs#3058). Not sure if T-lang, T-libs-api, T-libs, or some combination (The tracking issue is tagged T-lang, T-libs-api).~~ This probably doesn't need T-lang input, since it is not changing the API of `FromResidual` from the RFC? Maybe needs T-libs-api FCP?
I just inadvertently fell into this issue: forum post My use case is generic methods so that the caller can (parametrically) decide the level of error reporting it wants from the callee. Without more general |
I tried this code:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=5a6bc60775d41ce5ef3ff9656d489c51
I expected to see this happen: Code compiles successfully
Instead, this happened:
As you you see, the stdlib has
Which makes use of a default type arg on
FromResidual
-<Self as Try>::Residual
. ForOption<T>
, that isOption<Infallible>
.So apparently,
FromResidual<Option<Infallible>>
conflicts withFromResidual<Flip<T>>
.Playing devil's advocate, we could assume that
FromResidual
is being conservative with its conflicts becauseTry::Residual
could change, but it could never change to a type I own.Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: