Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with type inference and impl Trait #73239

Closed
joe-hauns opened this issue Jun 11, 2020 · 2 comments
Closed

Problem with type inference and impl Trait #73239

joe-hauns opened this issue Jun 11, 2020 · 2 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) A-trait-system Area: Trait system C-bug Category: This is a bug. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@joe-hauns
Copy link

Hi!
I recently experienced a bug in that probably comes from problems of the interference of type inference, impl Trait in return type position, and associated types.

This is a very strongly simplified version of what was going on in my codebase. In fact my codebase included Arc instead of SmartPointer and AsRef instead of MyAsRef, but I wanted to simplify to reproduce the problem without std.

struct SmartPointer<A>(A);

trait MyAsRef<A> {
    fn my_ref(&self) -> &A;
}

impl<A> MyAsRef<A> for SmartPointer<A> {
    fn my_ref(&self) -> &A {
        &self.0
    }
}

struct Type0Container<P>(SmartPointer<P::Type0>)
where
    P: TypeSet;

impl<P> Type0Container<P>
where
    P: TypeSet,
{
    // fn item(&self) -> &SmartPointer<P::Type0> { // << compiles
    fn item(&self) -> &impl MyAsRef<P::Type0> {    // << does not compile
        &self.0
    }
}

trait TypeSet {
    type Type0;
}

struct TypeSetImpl;
struct Type0Impl;

impl TypeSet for TypeSetImpl {
    type Type0 = Type0Impl;
}

fn main() {
    let proc: Type0Container<TypeSetImpl> = Type0Container(SmartPointer(Type0Impl)); 
    let _: &Type0Impl = proc.item().my_ref();
}

I expected to see this happen:
The compiler should be able to infer that <TypeSetImpl as TypeSet>::Type0 = Type0Impl and compile the program.

Instead, this happened:
The compiler failed with this error message:

   Compiling lala v0.1.0 (/path/to/lala)
error[E0308]: mismatched types
  --> src/main.rs:41:25
   |
41 |     let _: &Type0Impl = proc.item().my_ref();
   |            ----------   ^^^^^^^^^^^^^^^^^^^^ expected struct `Type0Impl`, found associated type
   |            |
   |            expected due to this
   |
   = note: expected reference `&Type0Impl`
              found reference `&<TypeSetImpl as TypeSet>::Type0`
   = help: consider constraining the associated type `<TypeSetImpl as TypeSet>::Type0` to `Type0Impl`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

As noted in the comments in the code snipped changing the one line using impl Trait in return type position enables the compiler to build the program.
I'm not entirely sure if this is a bug or if I expecting type inference to be stronger as it is or if the code I wrote is indeed not correct, so sorry if that is the case.

Meta

rustc --version --verbose:

rustc 1.46.0-nightly (449e8eaa2 2020-06-10)
binary: rustc
commit-hash: 449e8eaa286e407c9cd8cac655b77998fd53db6b
commit-date: 2020-06-10
host: x86_64-apple-darwin
release: 1.46.0-nightly
LLVM version: 10.0
None

<backtrace>

@joe-hauns joe-hauns added the C-bug Category: This is a bug. label Jun 11, 2020
@jonas-schievink jonas-schievink added A-associated-items Area: Associated items (types, constants & functions) A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) labels Jun 11, 2020
@fmease fmease added A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-trait-system Area: Trait system T-types Relevant to the types team, which will review and decide on the PR/issue. labels Dec 21, 2024
@fmease
Copy link
Member

fmease commented Dec 22, 2024

The provided snippet compiles just fine in the current version of Rust. I'm pretty sure that we have a test for this somewhere already, so we don't need to add a regression test and can close this issue directly. However, I actually still need to look for it ^^

@fmease
Copy link
Member

fmease commented Dec 28, 2024

Smaller:

trait Id { type Out; }
impl<T> Id for T { type Out = T; }

fn main() {
    fn make<P: Id>(x: P::Out) -> impl Into<P::Out> { x }
    let _: () = make::<()>(()).into(); // error: mismatched types
                                       //  note:    expected unit type `()`
                                       //        found associated type `<() as Id>::Out`
}

searched toolchains nightly-2020-06-11 through nightly-2024-12-28

********************************************************************************
Regression in nightly-2020-10-07
********************************************************************************

looking for regression commit between 2020-10-06 and 2020-10-07
fetching (via remote github) commits from max(a1dfd2490a6cb456b92e469fa550dc217e20ad6d, 2020-10-04) to 98edd1fbf8a68977a2a7c1312eb1ebff80515a92
ending github query because we found starting sha: a1dfd2490a6cb456b92e469fa550dc217e20ad6d
get_commits_between returning commits, len: 6
  commit[0] 2020-10-05: Auto merge of #77080 - richkadel:llvm-coverage-counters-2, r=tmandry
  commit[1] 2020-10-06: Auto merge of #77606 - JohnTitor:rollup-7rgahdt, r=JohnTitor
  commit[2] 2020-10-06: Auto merge of #77594 - timvermeulen:chain_advance_by, r=scottmcm
  commit[3] 2020-10-06: Auto merge of #73905 - matthewjasper:projection-bounds-2, r=nikomatsakis
  commit[4] 2020-10-06: Auto merge of #76356 - caass:hooks, r=jyn514
  commit[5] 2020-10-06: Auto merge of #77386 - joshtriplett:static-glibc, r=petrochenkov
ERROR: no CI builds available between a1dfd2490a6cb456b92e469fa550dc217e20ad6d and 98edd1fbf8a68977a2a7c1312eb1ebff80515a92 within last 167 days

Fixed by PR: #73905. A lot of tests were modified and added, none look quite like this test but I'm more than certain that this is covered by a bunch of tests. Closing as fixed.

@fmease fmease closed this as completed Dec 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) A-trait-system Area: Trait system C-bug Category: This is a bug. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants