Skip to content

Precise captures in ITIAT are not refining #135144

Open
@QuineDot

Description

@QuineDot

I tried this code:

#![feature(impl_trait_in_assoc_type)]

pub trait Trait {}
impl<T> Trait for T {}
pub struct Context;

pub trait Component {
    type Creation<'a>: Trait;
    fn create(self, ctx: &Context) -> Self::Creation<'_>;
}

impl Component for String {
    // `+ use<>` is allowed without triggering this lint
    // #[allow(refining_impl_trait)]
    type Creation<'a> = impl Trait + use<>;
    fn create(self, _ctx: &Context) -> Self::Creation<'_> {
        self
    }
}

impl Component for &str {
    // `+ use<>` correctly rejects the defining use here
    type Creation<'a> = impl Trait /*+ use<>*/;
    fn create(self, ctx: &Context) -> Self::Creation<'_> {
        ctx
    }
}

// This should accept `T = String` and not `T = &str`, but it
// accepts neither
pub fn component<T, R>(prop: T)
where
    T: for<'a> Component<Creation<'a> = R>,
{
    move |ctx: &Context| prop.create(ctx);
}

fn main() {
    let but_does_it_work = component(String::new());
    // let but_does_it_work = component("");
}

I expected to see this happen: successful compilation

Instead, this happened:

error[E0308]: mismatched types
  --> src/main.rs:39:28
   |
15 |     type Creation<'a> = impl Trait + use<>;
   |                         ------------------
   |                         |
   |                         the expected opaque type
   |                         the found opaque type
...
39 |     let but_does_it_work = component(String::new());
   |                            ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected opaque type `<String as Component>::Creation<'a>`
              found opaque type `<String as Component>::Creation<'_>`
   = note: distinct uses of `impl Trait` result in different opaque types
note: the lifetime requirement is introduced here
  --> src/main.rs:33:26
   |
33 |     T: for<'a> Component<Creation<'a> = R>,
   |                          ^^^^^^^^^^^^^^^^

Why the expectation

The analogous refinement works with RPITIT and RTN.

Meta

Playground 1.86.0-nightly (2025-01-04 1891c28)

@rustbot label +F-impl_trait_in_assoc_type +A-traits +T-types +requires-nightly

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lifetimesArea: Lifetimes / regionsA-trait-systemArea: Trait systemC-bugCategory: This is a bug.F-impl_trait_in_assoc_type`#![feature(impl_trait_in_assoc_type)]`S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issueT-typesRelevant to the types team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions