Trait fn call does not compile unless fully qualified, but works in the new solver
Open
Nobody has claimed this yet.
A-trait-system
C-bug
fixed-by-next-solver
T-types
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I tried this code:
use std::marker::PhantomData;
pub trait ForLt<'a> { type Ty: 'a; }
impl<'a, T: ForLt<'a> + ?Sized> ForLt<'a> for PhantomData<T> {
type Ty = T::Ty;
}
macro_rules! hkt {
(for<$lt:lifetime> $T:ty) => {
::core::marker::PhantomData<dyn for<$lt> ForLt<$lt, Ty = $T>>
};
($T:ty) => {
::core::marker::PhantomData<dyn for<'a> ForLt<'a, Ty = $T>>
};
}
pub trait ValueLike {}
pub trait Value<'a>: ValueLike {}
pub trait ComposableValue<'a>: ValueLike {}
pub struct Dummy;
impl ValueLike for Dummy {}
impl<'a> Value<'a> for Dummy {}
impl<'a> ComposableValue<'a> for Dummy {}
impl<A: ValueLike, B: ValueLike> ValueLike for (A, B) {}
impl<'a, A: ComposableValue<'a>, B: Value<'a>> Value<'a> for (A, B) {}
pub trait OpenTable {
type Table;
fn open();
}
pub trait TableDesc {
type Table;
}
pub struct RocksDbTable<M, K, V> {
pub(crate) _pd: PhantomData<(M, K, V)>,
}
impl<
M,
K: for<'a> ForLt<'a, Ty: Value<'a>>,
V: for<'a> ForLt<'a, Ty: Value<'a>>,
T: TableDesc<Table = RocksDbTable<M, K, V>>,
> OpenTable for T
{
type Table = <T as TableDesc>::Table;
fn open() {}
}
pub struct TableA;
impl TableDesc for TableA {
type Table = RocksDbTable<Self, hkt!(Dummy), hkt!((Dummy, Dummy))>;
}
fn open_table() {
// Fails in old solver, works in new solver:
TableA::open();
// Works in both solvers:
// <TableA as OpenTable>::open();
}
I expected to see this happen: Code compiles successfully with the old trait solver.
Instead, this happened: Code does not compile unless you fully qualify the trait fn call. Outputs an incorrect error about trait implementations that do not exist.
error[E0599]: the function or associated item `open` exists for struct `TableA`, but its trait bounds were not satisfied
--> src/lib.rs:61:13
|
53 | pub struct TableA;
| ----------------- function or associated item `open` not found for this struct
...
61 | TableA::open();
| ^^^^ function or associated item cannot be called on `TableA` due to unsatisfied trait bounds
|
note: the following trait bounds were not satisfied:
`&TableA: TableDesc`
`&mut TableA: TableDesc`
`<&TableA as TableDesc>::Table = RocksDbTable<_, _, _>`
`<&mut TableA as TableDesc>::Table = RocksDbTable<_, _, _>`
--> src/lib.rs:46:6
|
46 | T: TableDesc<Table = RocksDbTable<M, K, V>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | unsatisfied trait bound introduced here
| unsatisfied trait bound introduced here
47 | > OpenTable for T
| --------- -
= help: items from traits can only be used if the trait is implemented and in scope
note: `OpenTable` defines an item `open`, perhaps you need to implement it
--> src/lib.rs:29:1
|
29 | pub trait OpenTable {
| ^^^^^^^^^^^^^^^^^^^
Meta
rustc --version --verbose:
1.94.0 (playground)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the standalone reproducer in src/lib.rs and compile it using the old and new trait solvers. Trace resolution of the unqualified TableA::open() call and compare it with the fully qualified call. Done means the unqualified call compiles and no longer reports the incorrect trait-bound errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100