Skip to content
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

Rustc should be able to unify <T as A<'static>>::B> with <T as A<'a>>::B> for all 'a, given A::B: 'static #50166

Open
Boscop opened this issue Apr 22, 2018 · 1 comment
Labels
A-trait-system Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Boscop
Copy link

Boscop commented Apr 22, 2018

I had to use this trick to work around the lack of working GATs:
Ended up with this code: https://play.rust-lang.org/?gist=5f14fd0600bf0b1e1e9eac2c8a3d194a&version=stable
It works but to be able to do

pub struct AppMgr<T: for<'a> DeviceApp<'a>> {
	device: Option<T::Dev>,
	app: T,
	// ...
}

I had to split up my trait

pub trait DeviceApp<'a> {
	type Dev: Device;
	// ...

into two

pub trait DeviceSpecific {
	type Dev: Device;
}

pub trait DeviceApp<'a>: DeviceSpecific {
	// ...

to pull Dev out of the quantification scope of 'a.

I thought it should work if I put Dev back inside DeviceApp but make it : 'static so that rustc can infer that it's the same for all 'a:

/*
pub trait DeviceSpecific {
	type Dev: Device;
}

pub trait DeviceApp<'a>: DeviceSpecific {
*/
pub trait DeviceApp<'a> {
	type Dev: Device + 'static;

// ...

pub struct AppMgr<T: for<'a> DeviceApp<'a>> {
	// device: Option<T::Dev>,
	device: Option<<T as DeviceApp<'static>>::Dev>, // because Dev: 'static, i thought it will be unifyable with any 'a
	app: T,
	// ...
}

But it doesn't work. Now I get this error:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in function call due to conflicting requirements
  --> src/main.rs:79:53
   |
79 |             device.frame(now, |device, input| { app.process(device, input, v) })
   |                                                     ^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 75:5...
  --> src/main.rs:75:5
   |
75 |     pub fn process<'a>(&mut self, now: u64, msgs: Vec<<T as DeviceApp<'a>>::Msg>, v: &'a mut <T as DeviceApp<'a>>::BorrowedState) -> Vec<<T as DeviceApp<'a>>::Event> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: ...so that the expression is assignable:
           expected &mut <T as DeviceApp<'_>>::BorrowedState
              found &mut <T as DeviceApp<'a>>::BorrowedState
   = note: but, the lifetime must be valid for the static lifetime...
   = note: ...so that the expression is assignable:
           expected &mut <T as DeviceApp<'_>>::Dev
              found &mut <T as DeviceApp<'static>>::Dev

https://play.rust-lang.org/?gist=d4084c0a87890d4ed17d0491e453565b&version=stable

Why can't rustc unify <T as DeviceApp<'static>>::Dev> with <T as DeviceApp<'a>>::Dev> for all 'a, when it KNOWS that Dev: 'static (the type doesn't depend on 'a, so it can only be the same for all 'a)?

It should be able to infer it..

@pietroalbini pietroalbini added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-trait-system Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 26, 2018
@steveklabnik
Copy link
Member

Triage: no change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants