rust-lang / rust-lang/rust

opaque type leakage and RPITIT normalization

Open
#139,788 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-impl-trait F-return_position_impl_trait_in_trait I-cycle WG-trait-system-refactor
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

related to https://github.com/rust-lang/trait-system-refactor-initiative/issues/173, see added tests in https://github.com/rust-lang/rust/pull/139789

trait Trait {
    // desugars to
    // type Assoc: Sized + Send;
    // fn foo(b: bool) -> Self::Assoc;
    fn foo(b: bool) -> impl Sized + Send;
}

impl Trait for u32 {
    // desugars to
    // type Assoc = impl_rpit::<Self>;
    // fn foo(b: bool) -> Self::Assoc { .. }
    fn foo(b: bool) -> impl Sized {
        if b {
            u32::foo(false)
        } else {
            1u32
        }
    }
}

This currently results in a query cycle:

  • type_of(impl::Assoc)
  • collect_return_position_impl_trait_in_trait_tys
  • impl_rpit: Send
  • type_of(impl_rpit) // auto trait leakage
  • typeck(impl::foo)
  • normalize(<u32 as Trait>::Assoc)
  • type_of(impl::Assoc)

I believe that this query cycle should not be there and can be avoided.

collect_return_position_impl_trait_in_trait_tys currently adds the item bounds of the RPITIT when replacing it with fresh infer vars. I believe this is not necessary to guide inference as the method signature is fully concrete.

We could therefore split this in two:

  • collect_return_position_impl_trait_in_trait_tys instantiates RPITIT with infer vars but does not check the item bounds of the RPITIT trait assoc type
  • compare_type_predicate_entailment (or a separate query, idk and idc :3) then uses collect_return_position_impl_trait_in_trait_tys and actually checks the item bounds

This means normalizing impl::Assoc no longer has to prove the item bounds of the RPITIT, allowing the above example to compile and fixing https://github.com/rust-lang/trait-system-refactor-initiative/issues/173

cc @compiler-errors

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 added tests referenced in pull request 139789 and trace collect_return_position_impl_trait_in_trait_tys, compare_type_predicate_entailment, and the query sequence described in this issue. Determine whether RPITIT item bounds can be deferred without recreating the cycle, then verify that the referenced example compiles and the added tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.