Skip to content

Unrelated trait bounds prevents generic types to be inferred in function call. #102939

@RikardLegge

Description

@RikardLegge

I tried this code (Playground):

pub struct Type {}
pub struct Unrelated<T>(T);

impl From<Unrelated<Type>> for Unrelated<()> {
    fn from(_: Unrelated<Type>) -> Self {
        todo!()
    }
}

fn type_ok<T>() {
    let _: Type = type_constraint(Type {});
}

fn type_wrong_type_parameter<T>()
where
    Unrelated<T>: Into<Unrelated<()>>,
{
    let _: Type = type_constraint(Type {});
    //.           --------------- ^^^^^^^ expected type parameter `T`, found struct `Type`
    //            |
    //            arguments to this function are incorrect
}

fn type_constraint<Q>(_: Q) -> Q
where
    Unrelated<Q>: Into<Unrelated<()>>,
{
    unimplemented!()
}

Another example with the same problem caused associated types: Example 2 Playground.

I expected to see this happen: The example should compile and the ignored variables _ on the left hand side has type Type in the examples.

Instead, this happened: Only the unbounded function compiles. The functions with the added trait bounds causes a compile time error. The three simplest ways of resolving the problem are:

  1. Removing the trait bounds from either type_wrong_type_parameter or type_constraint. Might not be possible.
  2. Replacing Unrelated<T> with T in the trait bounds. This is usually not a solution either.
  3. Adding an explicit type to the function call type_constraint::<Type>. This allows the problem to in most cases be side-stepped.

If the problem is that the function want's to resolve T to a known type, the relation between the unused generic variable T and the function call is still not obvious.

Meta

Tested on both the stable and nightly compiler:

rustc 1.64.0 (a55dd71d5 2022-09-19)
binary: rustc
commit-hash: a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52
commit-date: 2022-09-19
host: x86_64-apple-darwin
release: 1.64.0
LLVM version: 14.0.6
rustc 1.66.0-nightly (a6b7274a4 2022-10-10)
binary: rustc
commit-hash: a6b7274a462829f8ef08a1ddcdcec7ac80dbf3e1
commit-date: 2022-10-10
host: x86_64-apple-darwin
release: 1.66.0-nightly
LLVM version: 15.0.2

Error output

Compiling playground v0.0.1 (/playground)
error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): mismatched types
  --> src/lib.rs:18:35
   |
14 | fn type_wrong_type_parameter<T>()
   |                              - this type parameter
...
18 |     let _: Type = type_constraint(Type {});
   |                   --------------- ^^^^^^^ expected type parameter `T`, found struct `Type`
   |                   |
   |                   arguments to this function are incorrect
   |
   = note: expected type parameter `T`
                      found struct `Type`
note: function defined here
  --> src/lib.rs:24:4
   |
24 | fn type_constraint<Q>(_: Q) -> Q
   |    ^^^^^^^^^^^^^^^    ----

error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): mismatched types
  --> src/lib.rs:18:19
   |
14 | fn type_wrong_type_parameter<T>()
   |                              - this type parameter
...
18 |     let _: Type = type_constraint(Type {});
   |            ----   ^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Type`, found type parameter `T`
   |            |
   |            expected due to this
   |
   = note:      expected struct `Type`
           found type parameter `T`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to 2 previous errors

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-inferenceArea: Type inferenceC-bugCategory: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions