Skip to content

relating higher-ranked projections can unexpectedly constrain inference #107268

Description

@aliemjay

The following compiles (although it shouldn't, arguably, see below for reasoning): https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=05d31c1cc2a9e8752d7a3fc05e9446ea

pub trait Trait {
    type Ty<'a>;
}

fn my_fn<T: Trait>(_: T::Ty<'_>) {}

fn test<A: Trait, B: Trait>() -> impl Fn(A::Ty<'static>) {
    my_fn
}

It stops compiling with a trivial change that gets rid of higher-ranked regions:

- fn my_fn<T: Trait>(_: T::Ty<'_>) {}
+ fn my_fn<T: Trait>(_: T::Ty<'static>) {}

fn test<A: Trait, B: Trait>() -> impl Fn(A::Ty<'static>) {
    my_fn
+   //~^ ERROR type annotation needed
}

This was discovered by @BoxyUwU in #96912.

@rustbot label T-types C-bug I-unsound A-inference

Activity

  1. added
    C-bugCategory: This is a bug.
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Jan 24, 2023
  2. aliemjay commented on Jan 24, 2023

    @aliemjay
    ContributorAuthor

    Here is a variant that shows why it's unsound; Inference ambiguity is accepted here:

    pub trait Trait {
        type Ty<'a>;
    }
    
    fn my_fn<T: Trait>(_: T::Ty<'_>) {}
    
    fn test<A, B>() -> impl Fn(A::Ty<'static>)
    where
        A: Trait,
        B: for<'a> Trait<Ty<'a> = A::Ty<'a>>,
    {
        my_fn::<_> // A and B are both valid options; We pick A!
    }
  3. compiler-errors commented on Jan 24, 2023

    @compiler-errors
    Contributor

    I think this needs a better example for the unsoundness. The inference variable being constrained by one where-clause predicate over the other is not unsound, regardless of whether we think that the behavior is surprising.

    At least, this is totally fine to do inside of a function body, I thought?

  4. aliemjay commented on Jan 27, 2023

    @aliemjay
    ContributorAuthor

    After the discussion in a zulip thread, I agree that this is not necessarily a soundness bug. 😅

    @rustbot label -I-unsound

  5. removed
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    on Jan 27, 2023
  6. changed the title [-]relating higher-ranked projections can unsoundly constrain inference[/-] [+]relating higher-ranked projections can unexpectedly constrain inference[/+] on Jan 27, 2023
  7. apiraino commented on Jan 31, 2023

    @apiraino
    Contributor

    WG-prioritization assigning priority (Zulip discussion).

    @rustbot label -I-prioritize +P-medium

  8. added and removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Jan 31, 2023
  9. added
    A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)
    on Sep 24, 2024
  10. added
    fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.
    on May 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-inferenceArea: Type inferenceC-bugCategory: This is a bug.P-mediumMedium priorityT-typesRelevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions