rust-lang / rust-lang/rust

Trait fn call does not compile unless fully qualified, but works in the new solver

Open
#153,969 2 comments 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.