Skip to content

impl_trait_in_bindings is a breaking change #83021

Closed
@oli-obk

Description

@oli-obk

The following program compiles without the impl_trait_in_bindings feature, but not with that feature. I believe this is because the way impl_trait_in_bindings is set up. If you look at

let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
self.fcx.instantiate_opaque_types_from_value(self.parent_id, o_ty, ty.span)
} else {
o_ty
};

you can see that enabling the feature gate runs a completely different algorithm instead of emitting a feature error when the feature gate is not active. Before stabilizing type_alias_impl_trait we need to make sure that we change all such occurrences of feature-gate based type processing.

#![allow(incomplete_features)]
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_bindings)]
use std::marker::PhantomData;

trait MyIndex<T> {
    type O;
    fn my_index(self) -> Self::O;
}
trait MyFrom<T>: Sized {
    type Error;
    fn my_from(value: T) -> Result<Self, Self::Error>;
}

trait F {}
impl F for () {}
type DummyT<T> = impl F;
fn _dummy_t<T>() -> DummyT<T> {}

struct Phantom1<T>(PhantomData<T>);
struct Phantom2<T>(PhantomData<T>);
struct Scope<T>(Phantom2<DummyT<T>>);

impl<T> Scope<T> {
    fn new() -> Self {
        unimplemented!()
    }
}

impl<T> MyFrom<Phantom2<T>> for Phantom1<T> {
    type Error = ();
    fn my_from(_: Phantom2<T>) -> Result<Self, Self::Error> {
        unimplemented!()
    }
}

impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<Phantom1<T>> for Scope<U> {
    type O = T;
    fn my_index(self) -> Self::O {
        MyFrom::my_from(self.0).ok().unwrap()
    }
}

fn main() {
    let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed
  --> src/main.rs:45:38
   |
7  |     type O;
   |     ------- `<Self as MyIndex<T>>::O` defined here
...
45 |     let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
   |                                      ^^^^^^^^^^-------------
   |                                      |
   |                                      this method call resolves to `<Self as MyIndex<T>>::O`
   |                                      cannot infer type for type parameter `T`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.F-impl_trait_in_bindings`#![feature(impl_trait_in_bindings)]`

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions